Skip to main content
GameDev.net gamedev.net
🔒 Locked

Ray-Plane intersection

Started by dacris Dec 28, 2002 at 6:35 PM 5 replies 1.4k views
Original Post
dacris
dacris
Anyone know how to figure out the exact point of intersection between a ray (origin, direction) and a plane or axis? Also, how do you find the plane equation of an axis? Thanks in advance.
Yann L
Yann L
I assume by axis you mean plane normal ?

You can''t figure out the full plane equation from it''s normal alone, you need additional information: it''s displacement along the origin. It can be computed, if you know an aribitrary vertex which lies on the plane.

Plane equation: Ax + By + Cz + D = 0, where (A,B,C) is the plane normal vector, (x,y,z) a point on the plane, and D the displacement offset from thre origin along the normal.

For a ray/plane intersection, you plug the ray equation into the plane equation and solve. Here is a piece of code:


  
// Start = start of ray

// Dir = direction of ray (normalized)

// Normal = plane normal (normalized)

// D = Distance of plane from origin along normal (D in the plane equation)

// IntPoint = final pointof intersection

// returns true if an intersection was found, or false if not.

bool RayPlaneIntersect(const fvector3 &Start, const fvector3 &Dir, const fvector3 &Normal, float D, fvector3 *IntPoint)
{
float hd = 0;
float i = Normal * Dir; // dotproduct


if( i==0 ) return( false ); // ray is parallel to plane, no hit


float j = -(Normal * Start + D);
hd = j/i; // compute distance along ray to intersection point

if( hd < EPSILON ) return( false ); // Hit is behind start of ray, no hit

*IntPoint = Start + hd*Dir; // compute the point of intersection, using the ray equation


return( true );
};


/ Yann
ga
ga
quote:
Original post by Yann L
... and D the displacement offset from thre origin along the normal.




this is only true if the normal is normalized, e. g. its length is 1; generally D = - N*X1, where * means the dot product, N is the normal and X1 is an arbitrary point on the plane.

GA
Visit our homepage: www.rarebyte.de.stGA
Yann L
Yann L
As I said above:
"Plane equation: Ax + By + Cz + D = 0, where (A,B,C) is the plane normal vector, (x,y,z) a point on the plane"

D = - N*X1 is exactly the same as Ax + By + Cz + D = 0...
ga
ga
Yann L: you''re right, but from your first post one could think that D is always the distance from the origin to the plane
Visit our homepage: www.rarebyte.de.stGA
Julio
Julio
another implimentation, taken from a site, I don''t remember where.


  
#define EPSILON 0.000001
#define CROSS(dest,v1,v2) \
dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \
dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \
dest[2]=v1[0]*v2[1]-v1[1]*v2[0];
#define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])
#define SUB(dest,v1,v2)
dest[0]=v1[0]-v2[0]; \
dest[1]=v1[1]-v2[1]; \
dest[2]=v1[2]-v2[2];
/*
We present a clean algorithm for determining whether a ray intersects a triangle.
The algorithm translates the origin of the ray and then changes the base to yield a vector (t u v)T, where t is the
distance to the plane in which the triangle lies and (u,v) represents the coordinates inside the triangle.
*/
int
intersect_triangle(double orig[3], double dir[3],
double vert0[3], double vert1[3], double vert2[3],
double *t, double *u, double *v)
{
double edge1[3], edge2[3], tvec[3], pvec[3], qvec[3];
double det,inv_det;

/* find vectors for two edges sharing vert0 */
SUB(edge1, vert1, vert0);
SUB(edge2, vert2, vert0);

/* begin calculating determinant - also used to calculate U parameter */
CROSS(pvec, dir, edge2);

/* if determinant is near zero, ray lies in plane of triangle */
det = DOT(edge1, pvec);

#ifdef TEST_CULL /* define TEST_CULL if culling is desired */
if (det < EPSILON)
return 0;

/* calculate distance from vert0 to ray origin */
SUB(tvec, orig, vert0);

/* calculate U parameter and test bounds */
*u = DOT(tvec, pvec);
if (*u < 0.0 || *u > det)
return 0;

/* prepare to test V parameter */
CROSS(qvec, tvec, edge1);

/* calculate V parameter and test bounds */
*v = DOT(dir, qvec);
if (*v < 0.0 || *u + *v > det)
return 0;

/* calculate t, scale parameters, ray intersects triangle */
*t = DOT(edge2, qvec);
inv_det = 1.0 / det;
*t *= inv_det;
*u *= inv_det;
*v *= inv_det;
#else /* the non-culling branch */
if (det > -EPSILON && det < EPSILON)
return 0;
inv_det = 1.0 / det;

/* calculate distance from vert0 to ray origin */
SUB(tvec, orig, vert0);

/* calculate U parameter and test bounds */
*u = DOT(tvec, pvec) * inv_det;
if (*u < 0.0 || *u > 1.0)
return 0;

/* prepare to test V parameter */
CROSS(qvec, tvec, edge1);

/* calculate V parameter and test bounds */
*v = DOT(dir, qvec) * inv_det;
if (*v < 0.0 || *u + *v > 1.0)
return 0;

/* calculate t, ray intersects triangle */

*t = DOT(edge2, qvec) * inv_det;
#endif
return 1;
}



My Homepage
Everything is relative. Even stupidity.
My HomepageSome shoot to kill, others shoot to mame. I say clear the chamber and let the lord decide. - Reno 911
Yann L
Yann L
quote:
Original post by ga
Yann L: you're right, but from your first post one could think that D is always the distance from the origin to the plane

OK Well, I assumed the normal to be normalized, since denormalized plane normals are pretty uncommon (and are far more often the result of a programmer who forgot to normalize them, rather than the result of an intended operation on non-normalized plane normals...)

But you're right, from a purely mathematical point, I should have mentioned it


[edited by - Yann L on December 31, 2002 1:21:01 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.