I'm trying to implement at line-plane intersection algorithm. According to Wikipedia I need three non-colinear points on the plane to do that.
I therefore tried implementing this algorithm in C++, however. Something is definitely wrong, cause it makes no sense that I can choose whatever x and y coordinates and they'll fit in the plane. What if the plane is vertical and along the x-axis? No point with y=1 would then be in the plane.
I realize that this problem has been posted a lot on StackOverflow, and I see lots of solutions where the plane is defined by 3 points. But I only have a normal and a position. And I can't test my line-plane intersection algorithm before I sort out my non-colinear point finder.
The problem right now, is that I'm dividing by normal.z, and that obviously won't work when normal.z is 0.
I'm testing with this plane: Plane* p = new Plane(Color(), Vec3d(0.0,0.0,0.0), Vec3d(0.0,1.0,0.0)); // second parameter : position, third parameter : normal
The current code gives this incorrect answer:
{0 , 0 , 0} // alright, this is the original
{12.8377 , 17.2728 , -inf} // obviously this is not a non-colinear point on the given plane
Here's my code:
std::vector<Vec3d>* Plane::getThreeNonColinearPoints() {
std::vector<Vec3d>* v = new std::vector<Vec3d>();
v->push_back(Vec3d(position.x, position.y, position.z)); // original position can serve as one of the three non-colinear points.
srandom(time(NULL));
double rx, ry, rz, start;
rx = Plane::fRand(10.0, 20.0);
ry = Plane::fRand(10.0, 20.0);
// Formula from here: http://en.wikipedia.org/wiki/Plane_(geometry)#Definition_with_a_point_and_a_normal_vector
// nx(x-x0) + ny(y-y0) + nz(z-z0) = 0
// |-----------------| <- this is "start"
//I'll try to insert position as x0,y0,z0 and normal as nx,ny,nz, and solve the equation
start = normal.x * (rx - position.x) + normal.y * (ry - position.y);
// nz(z-z0) = -start
start = -start;
// (z-z0) = start/nz
start /= normal.z; // division by zero
// z = start+z0
start += position.z;
rz = start;
v->push_back(Vec3d(rx, ry, rz));
// TODO one more point
return v;
}
I realize that I might be trying to solve this totally wrong. If so, please link a concrete implementation of this. I'm sure it must exist, when I see so many line-plane intersection implementations.
Thanks in advance.
Where
N=(Nx,Ny,Nz)
is the normal, you could project the pointsN
,(Ny,Nz,Nx)
,(Nz,Nx,Ny)
onto the plane: they're guaranteed to be distinct.Alternatively, if
P
andQ
are on the plane,P+t(Q-P)xN
is also on the plane for anyt!=0
wherex
is the cross product.Alternatively if
M!=N
is an arbitrary vector,K=MxN
andL=KxN
are colinear with the plane and any pointp
on the plane can be written asp=Origin+sK+tL
for somes,t
.A plane can be defined with several ways. Typically a point on the plane and a normal vector is used. To get the normal vector from three points (
P1
,P2
,P3
) take the cross product of the side of the triangleThe reverse, to go from a point
P1
and normalN
to three points, you start from any directionG
not along the normalN
such thatDOT(G,N)!=0
. The two orthogonal directions along the plane are thenA line is defined by a point and a direction. Typically two points (
Q1
,Q2
) define the lineThe intersection of the line and plane are defined by the point on the line
r=Q1+t*E
that intersects the plane such thatDOT(r-P1,N)=0
. This is solved for the scalar distancet
along the line asand the location as
NOTE: The
DOT()
returns the dot-product of two vector,CROSS()
the cross-product, andUNIT()
the unit vector (with magnitude=1).One approach you may find easy to implement is to see where the plane intersects the coordinate axes. For the plane given by the equation
aX + bY + cZ - d = 0
hold two variables at 0 and solve for the third. So the solutions would be (assuminga
,b
,c
, andd
are all non-zero):You will need to consider the cases where one or more of the coefficients are 0 so you don't get a degenerate or colinear solutions. As an example if exactly one of the coefficients is 0 (say
a=0
) you instead useIf exactly two of the coefficients are 0 (say
a=0
andb=0
) you can use:If
d=0
, the plane intersects the three axes at the origin, and so you can use:You will need to work out simular cases for
d
and exactly one other coefficient being 0, as well asd
and two others being 0. There should be a total of 16 cases, but there are a few things that come to mind which should make that somewhat more manageable.