Tuesday, January 20, 2009

Is a given point inside of a triangle

Often in game programming, we have a point and a triangle and we want to know if the triangle contains the point. This simple test is computationally intensive but can be extended to other polygons like quads or pents. I am using the standard cross-product here that you find in most game programming or calculus books. The concept is this: there will be three triangles formed by the point and the vertices of the triangle (two vertices taken at a time plus the point). At least one of the triangles formed will be in the same winding (counter-clockwise or clockwise) as the supplied triangle. If the point is in the triangle, then all three new triangles will wind the same direction. If that point is outside, two of the triangles will wind one direction and the last will wind the other direction. We simply take the dot-product of all the normals formed by these triangles and if they are all facing the same relative direction, the point is in the triangle.

bool IsPointInTriangle (Vector a, Vector b, Vector c, Vector point)
{
// translate all points to the origin which greatly simplifies the math
a -= point, b -= point, c -= point;

// computing the winding/facing of the triangles formed with
// the point and the vertices of the triangle.
Vector n1 = b.Cross (c);
Vector n2 = c.Cross (a);

// now we have two normals. If we compute the angle between them, then we can tell if they
// face in the same relative direction (a opposed to being opposites)
// is the cos of the angle is positive, then the angle>90∘
if (n1.Dot (n2) < 0 )
{ // and the point cannot be in the triangle
return false;
}

Vector n3 = a.Cross (b); // compute the third normal

// ensure it's winding/facing, is the cos of the angle is positive, then the angle>90∘
if (n1.Dot (n3) < 0 )
{ // and the point cannot be in the triangle
return false;
}

// we now know that the point is on the same side of all of the sides of the triangle.
return true;
}

No comments: