Möller–Trumbore intersection algorithm
The Möller–Trumbore ray-triangle intersection algorithm, named after its inventors Tomas Möller and Ben Trumbore, is a fast method for calculating the intersection of a ray and a triangle in three dimensions without needing precomputation of the plane equation of the plane containing the triangle.[1] Among other uses, it can be used in computer graphics to implement ray tracing computations involving triangle meshes.[2]
C++ implementation
The following is an implementation of the algorithm in C++:
bool RayIntersectsTriangle(Vector3D rayOrigin,
Vector3D rayVector,
Triangle* inTriangle,
Vector3D& outIntersectionPoint)
{
const float EPSILON = 0.0000001;
Vector3D vertex0 = inTriangle->vertex0;
Vector3D vertex1 = inTriangle->vertex1;
Vector3D vertex2 = inTriangle->vertex2;
Vector3D edge1, edge2, h, s, q;
float a,f,u,v;
edge1 = vertex1 - vertex0;
edge2 = vertex2 - vertex0;
h = rayVector.crossProduct(edge2);
a = edge1.dotProduct(h);
if (a > -EPSILON && a < EPSILON)
return false; // This ray is parallel to this triangle.
f = 1.0/a;
s = rayOrigin - vertex0;
u = f * s.dotProduct(h);
if (u < 0.0 || u > 1.0)
return false;
q = s.crossProduct(edge1);
v = f * rayVector.dotProduct(q);
if (v < 0.0 || u + v > 1.0)
return false;
// At this stage we can compute t to find out where the intersection point is on the line.
float t = f * edge2.dotProduct(q);
if (t > EPSILON) // ray intersection
{
outIntersectionPoint = rayOrigin + rayVector * t;
return true;
}
else // This means that there is a line intersection but not a ray intersection.
return false;
}
Java implementation
The following is an implementation of the algorithm in Java using javax.vecmath
from Java 3D API:
public class MollerTrumbore {
private static final double EPSILON = 0.0000001;
public static boolean rayIntersectsTriangle(Point3d rayOrigin,
Vector3d rayVector,
Triangle inTriangle,
Point3d outIntersectionPoint) {
Point3d vertex0 = inTriangle.getVertex0();
Point3d vertex1 = inTriangle.getVertex1();
Point3d vertex2 = inTriangle.getVertex2();
Vector3d edge1 = new Vector3d();
Vector3d edge2 = new Vector3d();
Vector3d h = new Vector3d();
Vector3d s = new Vector3d();
Vector3d q = new Vector3d();
double a, f, u, v;
edge1.sub(vertex1, vertex0);
edge2.sub(vertex2, vertex0);
h.cross(rayVector, edge2);
a = edge1.dot(h);
if (a > -EPSILON && a < EPSILON) {
return false; // This ray is parallel to this triangle.
}
f = 1.0 / a;
s.sub(rayOrigin, vertex0);
u = f * (s.dot(h));
if (u < 0.0 || u > 1.0) {
return false;
}
q.cross(s, edge1);
v = f * rayVector.dot(q);
if (v < 0.0 || u + v > 1.0) {
return false;
}
// At this stage we can compute t to find out where the intersection point is on the line.
double t = f * edge2.dot(q);
if (t > EPSILON) // ray intersection
{
outIntersectionPoint.set(0.0, 0.0, 0.0);
outIntersectionPoint.scaleAdd(t, rayVector, rayOrigin);
return true;
} else // This means that there is a line intersection but not a ray intersection.
{
return false;
}
}
}
See also
- Badouel intersection algorithm
- MATLAB version of this algorithm (highly vectorized)
- Baldwin-Weber ray-triangle intersection algorithm
- Schlick–Subrenat algorithm[3] for ray-quadrilateral intersection
Links
- Fast Minimum Storage Ray-Triangle Intersection
- Optimizations on the basic algorithm by Möller & Trumbore, code from journal of graphics tools
References
- Möller, Tomas; Trumbore, Ben (1997). "Fast, Minimum Storage Ray-Triangle Intersection". Journal of Graphics Tools. 2: 21–28. doi:10.1080/10867651.1997.10487468.
- "Ray-Triangle Intersection". lighthouse3d. Retrieved 2017-09-10.
- Ray Intersection of Tessellated Surfaces: Quadrangles versus Triangles, Schlick C., Subrenat G. Graphics Gems 1993
This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.