Line > triangle intersection

(I know unity has a physics component, this is for a school assignment)

I’m trying to implement these methods for mesh collision but Its failing.

http://fwheel.net/gdw/wiki/index.pl?LineSegmentTriangleIntersection
http://fwheel.net/gdw/wiki/index.pl?ParametricPlaneEquation

I do think I misunderstood something from either of the two tutorials. And I can’t figure out what exactly.

My code so far:
(Obviously this isn’t about speed or efficiency, it just needs to work =) )

int index = 0;
	for (int i = 0; i < faces.Length; i += 3) {

		{

			Vector3 A = vertices[faces*];*
  •   		Vector3 B = vertices[faces[i+1]];*
    
  •   		Vector3 C = vertices[faces[i+2]];*
    
  •   		Vector3 Adelta = B - A;*
    
  •   		Vector3 Bdelta = C - A;*
    
  •   		Vector3 n = normals[index];*
    
  •   		Vector3 nNormalized = n;*
    
  •   		nNormalized.Normalize ();*
    
  •   		Vector3 negativeN = -(nNormalized);*
    
  •   		for (int j = 0; j < ballArray.Length; j++) {*
    
  •   			Ball b = ballArray[j].GetComponent<Ball> ();*
    

_ Vector3 u = (b.transform.position + (nNormalized * b.radius)) - b.transform.position;_

  •   			Vector3 v = A - b.transform.position;*
    
  •   			float nu = Vector3.Dot(u,nNormalized);*
    
  •   			float nv = Vector3.Dot(v,nNormalized);*
    
  •   			if(nu == 0)*
    
  •   			{*
    
  •   				continue;*
    
  •   			}*
    
  •   			float r = (nv/nu);*
    
  •   			if(r >= 0 && r <= 1)*
    
  •   			{*
    

_ Vector3 interSectionPoint = b.transform.position + r * u;_

  •   				Vector3 w = interSectionPoint - A;			*
    

_ float sParamTop = (Vector3.Dot(Adelta,Bdelta) * Vector3.Dot(w,Bdelta)) - (Vector3.Dot(Bdelta,Bdelta) * Vector3.Dot(w,Adelta));_
_ float tParamTop = (Vector3.Dot(Adelta,Bdelta) * Vector3.Dot(w,Adelta)) - (Vector3.Dot(Adelta,Adelta) * Vector3.Dot(w,Bdelta));_
_ float dominator = (Vector3.Dot(Adelta,Bdelta) * Vector3.Dot(Adelta,Bdelta)) - (Vector3.Dot(Adelta,Adelta) * Vector3.Dot(Bdelta,Bdelta)); _

  •   				float s = sParamTop/dominator;*
    
  •   				float t = sParamTop/dominator;*
    
  •   				if( s>=0 && t>=0 && s+t<=1)*
    
  •   				{*
    
  •   					//print("true");*
    
  •   					b.reflect(n);*
    
  •   				}*
    
  •   			}*
    
  •   			continue;*
    
  •   		}		*
    
  •   		index++;*
    
  •   	}*
    
  •   }*
    

Thank you for reading

Ok, I’m a bit confused about your line direction…
As far as i understand the normal array contains the face-normals (which could be calculated easily). Your testing line segment start at the balls position and goes along the facenormal of the face you’re testing. That doesn’t make much sense to me.

This line is funny:

Vector3 u = (b.transform.position + (nNormalized * b.radius)) - b.transform.position;

It’s the same as

Vector3 u = nNormalized * b.radius;

I would recommend to rename your variable so they help to understand what they actually hold.

u is your line direction vector (the vector between start and end point)

Since your line direction is always the same as the face normal, this:

float nu = Vector3.Dot(u,nNormalized);

equals this:

float nu = b.radius;

That’s a really strange case of intersection. Do you actually want a line-triangle or a sphere-triangle intersection?


edit

I’ve uploaded my test scene if you’r interested :wink:

UnityPackage

You can drag the sphere around during playmode when you switch to the scene-view. If there’s an intersection point with the plane it will show as yellow 3D-cross

If the barycentric coordinates are within 0…1 (so it’s inside the triangle) it will show the cross in magenta

This is a great post.

Do you have the final working script. I am making a game and need exactly this test. Would really appreciated it if someone can provide a working version.

Cheers.