PDA

View Full Version : Help with Math functions




Nibbles
Apr 12, 2006, 01:26 PM
I am trying to create a plane from 3 points in the form of Ax + By + Cz + D = 0. I think I am doing this right by computing 2 vectors through a common point as:

V1 = P3 - P1
V2 = P2 - P1

and then computing a cross product

V1 X V2

then I should be able to take point 1 and use it with the formula to determine the distance from the plane to the point. I think I should get 0, but I am not.

Has anyone done this before? Are these numbers correct? Someone told me that a matrix calculation would be better something about a determinant. How do I compute a determinant of a 3 X 3 matrix to make the formula Ax + By + Cz + D = 0

Here's my sample program I need to incorporate this function into the rest of my program after I know it is working right.


#include <iostream>
#include <math.h>

using namespace std;

void calc_plane(double[], double[], double[], double[]);
void calc_plane2(double[], double[], double[]);

int main ()
{

double pt1[3];
pt1[0] = 1200;
pt1[1] = 2400;
pt1[2] = -35.89;

double pt2[3];
pt2[0] = 1200;
pt2[1] = 1800;
pt2[2] = -35.89;

double pt3[3];
pt3[0] = 1845;
pt3[1] = 2400;
pt3[2] = -35.89;

double plane[5];

calc_plane(pt1, pt2, pt3, plane);
calc_plane2(pt1, pt2, pt3);

return 0;
}

void calc_plane2(double pt1[3], double pt2[3], double pt3[3])
{
double a, b, c, d;

a = ((pt2[1] - pt1[1]) * (pt3[2] - pt1[2])) - ((pt3[1] - pt1[1]) * (pt2[2] - pt1[2]));
b = ((pt3[0] - pt1[0]) * (pt2[2] - pt1[2])) - ((pt2[0] - pt1[0]) * (pt3[2] - pt1[2]));
c = ((pt2[0] - pt1[0]) * (pt2[1] - pt1[1])) - ((pt3[0] - pt1[0]) * (pt2[1] - pt1[1]));
d = 0 - (pt1[0] * a) + (pt1[1] * b) + (pt1[2] * c);

cout << a << "x + " << b << "y + " << c << "z + " << d << endl;


double distPoint2;
double denom;

denom = sqrt( (a * a) + (b * b) + (c * c));

distPoint2 = (pt2[0] * a) + (pt2[1] * b) + (pt2[2] * c) + d;
distPoint2 = distPoint2 / denom;
cout << "Distance to Point 2: " << distPoint2 << endl;

distPoint2 = (1400 * a) + (2000 * b) + (60.58 * c) + d;
distPoint2 = distPoint2 / denom;
cout << "Distance to Point 2: " << distPoint2 << endl;


}


void calc_plane(double pt1[3], double pt2[3], double pt3[3], double plane[5])
{

cout << "Point 1: " << pt1[0] << ", " << pt1[1] << ", " << pt1[2] << endl;
cout << "Point 2: " << pt2[0] << ", " << pt2[1] << ", " << pt2[2] << endl;
cout << "Point 3: " << pt3[0] << ", " << pt3[1] << ", " << pt3[2] << endl;


double v1[3] = { pt2[0]-pt1[0], pt2[1]-pt1[1], pt2[2]-pt1[2] };
double v2[3] = { pt3[0]-pt1[0], pt3[1]-pt1[1], pt3[2]-pt1[2] };


// 0, -600, 0
// 645, 0, 0


plane[0] = ( v1[1]*v2[2] ) - ( v1[2]*v2[1] );
// 0, 0

plane[1] = ( v1[2]*v2[0] ) - ( v1[0]*v2[2] );
// 0, 0


plane[2] = ( v1[0]*v2[1] ) - ( v1[1]*v2[0] ); // cross product

// 387000

plane[3] = ( pt1[0]*plane[0] ) + ( pt1[1]*plane[1] ) + (pt1[2]*plane[2]);


plane[4] = 0 - plane[3]; // dist

cout << "Vector 1" << v1[0] << ", " << v1[1] << ", " << v1[2] << endl;
cout << "Vector 2" << v2[0] << ", " << v2[1] << ", " << v2[2] << endl;


cout << plane[0] << "x + " << plane[1] << "y + " << plane[2] << "z + " << plane[3] << endl;
cout << "Distance: " << plane[4] << endl;

}



Eraserhead
Apr 12, 2006, 02:59 PM
I can tell you about cross products (mathematically) Ax+By+Cz=V1 and Dx+Ey+Fz=V2

you solve this by finding the determinant of
|x y z|
|A B C|
|D E F|

which you can solve in many different ways... the solution is x(BF-CE)-y(AF-CD)+z(AE-BD)=V3

you can check this is correct as the dot product of V3 and either V1 or V2 is zero as V3 is perpendicular to V1 and V2.

The dot product of V3 and V1 is (BF-CE)*A+(CD-AF)*B+(AE-BD)*C which should equal zero.
V2 is similar except A B and C are replaced by D E and F respectively, this should also equal zero

Mathematically there is more info on wikipedia if your interested.

How you program all of this is beyond me though.

Thomas Harte
Apr 12, 2006, 05:57 PM
You've made an error on this line:
d = 0 - (pt1[0] * a) + (pt1[1] * b) + (pt1[2] * c);
It should be:
d = 0 - (pt1[0] * a + pt1[1] * b + pt1[2] * c);
Or even:
d = 0 - (pt1[0] * a) - (pt1[1] * b) - (pt1[2] * c);
i.e. do all the adding then negative. What are doing in the "distance from plane" equation is creating an axis that runs perpendicular to the plane, determining how far along that axis your new point is from the origin then subtracting the distance of the the plane to get distance relative to that.

The "+ d" is actually the subtraction, but you've already negatived it. Except in your code, when you aren't negativing it properly.

EDIT:
it's also common to make (a, b, c) a unit vector before calculating d. So take what you're doing with denom, but divide a, b and c by denom prior to calculating d. Then you can cut denom out of all future calculations as you'd be in the position where denom = 1 if you calculated it.

Atlasland
Apr 12, 2006, 06:31 PM
I can tell you about cross products (mathematically) Ax+By+Cz=V1 and Dx+Ey+Fz=V2

you solve this by finding the determinant of
|x y z|
|A B C|
|D E F|

which you can solve in many different ways... the solution is x(BF-CE)-y(AF-CD)+z(AE-BD)=V3

you can check this is correct as the dot product of V3 and either V1 or V2 is zero as V3 is perpendicular to V1 and V2.

The dot product of V3 and V1 is (BF-CE)*A+(CD-AF)*B+(AE-BD)*C which should equal zero.
V2 is similar except A B and C are replaced by D E and F respectively, this should also equal zero

Mathematically there is more info on wikipedia if your interested.

How you program all of this is beyond me though.

Off topic: Are you at university at Oxford Eraserhead?

Eraserhead
Apr 15, 2006, 09:35 AM
Off topic: Are you at university at Oxford Eraserhead?
Nope, I'm at Warwick (its near coventry but we don't talk about that... ;)) I just happen to live in Oxford.

Nibbles
Apr 17, 2006, 10:34 AM
Thanks for the help Math Masters :).

Might need help with some other plane math in a few days.