1. Mathematics
For other shapes such as the sphere and cylinder, we have always worked with their "canonical form", i.e. we have centered them at (0,0,0) and set the radius to 1. While it is technically possible to treat triangles the same, we will take a different approach with triangles. In other words, we will directly support triangles with arbitrary vertices P1, P2 and P3.
The reason triangles are so often chosen as primitive shape (think of games) instead of, say, quadrilaterals, is that three points always lie in the same plane. The same canβt be said of quadrilaterals, whose vertices could very easily not lie in the same plane, making the mathematics behind them much more complex.
Given that the three vertices of a triangle lie in a plane, we can take the following approach in finding the intersection between a ray and a triangle: first, we determine where the ray hits the plane in which the triangle lies. Letβs call this point H. Next, we need to determine whether this H lies within the bounds of the triangle, which is the tricky part.
1.1. Ray-Plane Hit
A triangle is uniquely defined by its three vertices P1, P2 and P3, so using only those three points we need to be able to find the intersection of the triangle with an arbitrary ray R(t)=O+βΞβ t.
As explained earlier, our first goal is to find out where the ray R(t) hits the plane containing the triangle. The easiest way to go about this is relying on the following formula: say P is an arbitrary point on the plane and βN is a vector perpendicular on the plane, then if for a point H
then H lies on the plane. To be able to use this formula, we need a point P and vector βN.
Finding a P is easy: we have three of them, namely the triangles vertices P1, P2 and P3. Any one of them will do. To find βN, we need a little extra math.

We compute βu=P2βP1 and βv=P3βP1. Both these vectors are in the plane. Taking their cross product βn=βuΓβv will yield a vector perpendicular on both of them, meaning it will also be perpendicular on the plane.
The formula above thus becomes
The point H should lie on the ray, i.e. H=O+βΞβ t for some t. Plugging this into the equation gives
We only need to solve to t and we know where the ray hits the plane.
1.2. Inside Triangle Test
Now that we know where the hit H occurs between the ray and the plane containing the triangle, we still need to determine whether H lies within the bounds of the triangle.

Letβs say we stand at P1 and look at P2. H will be to the left of us. Next, letβs stand at P2 and look at P3. Again, H will be the to left of us. If we repeat this a last time, i.e. stand at P3 and look at P1, once again, H lies to the left.
So, if we can somehow determine to which side H lies with respect to a triangleβs side, we can find out if H lies inside the triangle.
Maybe the dot product can help us somehow. Let us investigate its sign. For the sake of clarity, we work in 2D. We take an arbitrary vector βv and draw it with its origin at (0,0). Next, for each point P on the plane, we determine the vector βu=Pβ(0,0), i.e. we draw a vector from the origin to P. Next, we compute the dot product βuβ βv. Depending on whether the result is positive, zero or negative, we assign the point P the color green, blue or red, respectively.

As you can see, all points "in front of βv" are green and all points behind βv are red. In other words, the dot product can tell us whether a point lies before or behind us. But this does not help us with our triangle: weβd rather know whether a point is to the left or to the right of us.
Maybe the cross product can help. Thereβs a small problem though: the cross product yields vectors, not numbers, and thereβs no such thing as the "sign of a vector". Weβll just have to draw the resulting vector then. More specifically, in each point P we draw the vector βvΓ(PβO).

The result is quite interesting: the vectors to the left of βv point upwards and those to the right downwards. This makes sense: remember that with the cross product, the direction of the result depends on whether the angle between the operands goes clockwise or counterclockwise.
Consider the following figures:
Say we stand at P1 and look at P2. We then turn slowly to P3. If while turning from P2 to P3 we encounter H, it means H is on the right side of P1P2. To define the "correct turning direction", we first compute P1P2ΓP1P3=(P2βP1)Γ(P3βP1). Next we compute P1P2ΓP1H=(P2βP1)Γ(HβP1). If both directions turn the same way (i.e. both clockwise or both counterclockwise), the cross product vectors will point in the same direction. We can detect this by relying on the dot product, which will be positive if this is the case. In short, H is on the correct side of P1P2 if
2. Summary
Given the following information:
-
The ray R(t)=O+βΞt.
-
Three vertices P1, P2, P3.
Follow these steps:
-
Compute the normal vector on the plane. Since this remains constant, you might want to do this only once, in the constructor.
βn=(P2βP1)Γ(P3βP1)|(P2βP1)Γ(P3βP1)| -
Compute the hit t:
t=(P1βO)β βnβΞβ βn -
Compute the hit position H:
H=O+βΞβ t -
Check if H lies to the right of P1P2:
((P2βP1)Γ(HβP1))β βnβ₯0 -
Check if H lies to the right of P2P3:
((P3βP2)Γ(HβP2))β βnβ₯0 -
Check if H lies to the right of P3P1:
((P1βP3)Γ(HβP3))β βnβ₯0 -
If any of the previous checks fails, H does not lie within the bounds of the triangle.