Public Group

# Help requested on Ray Triangle Collision

This topic is 2296 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

(Sorry if the post says Ray triangle, I was first trying with a ray first, but that wouldn't work with my airplane, so I'm trying sphere triangle now.)

Hi I am new to 3D and I'm trying to create a sphere triangle collision detection. I want to use this method because I have an airplane flying above a plane which is not flat. What I would want to check is if the airplane is crashing on one of the triangles of my plane. I have been researching all around and recapping my vector math a bit, and came up with this implementation. The problem of this implementation is that the dot product with the vertices gives me a negative number ( (pointB - pointA).Dot(pointA) > 0 && (pointC - pointA).Dot(pointA) > 0) which is smaller than 0, so it returns as a hit, which is not. But the distance to the faces works fine, and the distance to the vertices too. But it actually only finds a hit on one specific point on my plane which is strange. If someone could give me some suggestions what is wrong with this implementation I would be glad.

Below I have the implementation. I load in an obj model and then push all the vertices in the vertex list which is a std vector, and all the triangles in the triangle list. the vertex list is a list of vector3 and the triangle list is a list of triangles which are compound out of three int indices. Thanks in advance.

I got this implementation from this site:
http://realtimecolli...net/blog/?p=103

 // sphere - plane collision. face, edge, vertex acurate bool Game::isColliding(MeshObject* object, float radius, MeshObject* plane) { for(int f = 0; f < plane->mesh->triangleList.size(); f++) { vector3 spherePos = object->position; vector3 vertex0 = plane->mesh->verticeList.at(plane->mesh->triangleList[f].m_Indices[0]); vector3 vertex1 = plane->mesh->verticeList.at(plane->mesh->triangleList[f].m_Indices[1]); vector3 vertex2 = plane->mesh->verticeList.at(plane->mesh->triangleList[f].m_Indices[2]); vector3 pointA = vertex0 - spherePos; vector3 pointB = vertex1 - spherePos; vector3 pointC = vertex2 - spherePos; // -------------*** Face checks ***------------ // facedistance check float distanceFace = abs(pointA.Dot(plane->mesh->triangleList[f].m_Normal)); // face separation check float separatedf; if(distanceFace > radius) { separatedf = 1;}else {separatedf = 0;} // ----------*** end face checks ***------------ // ----------*** Vertex checks ***------------- // vertexdistance check float distanceVertex0 = sqrt(pointA.Dot(pointA)); float distanceVertex1 = sqrt(pointB.Dot(pointB)); float distanceVertex2 = sqrt(pointC.Dot(pointC)); // vertex separation checks float separatedv0; if(distanceVertex0 > radius && (pointB - pointA).Dot(pointA) > 0 && (pointC - pointA).Dot(pointA) > 0) {separatedv0 = 1;}else{separatedv0 = 0;} float separatedv1; if(distanceVertex1 > radius && (pointB - pointA).Dot(pointB) > 0 && (pointC - pointB).Dot(pointB) > 0) {separatedv1 = 1;}else{separatedv1 =0;} float separatedv2; if(distanceVertex2 > radius && (pointC - pointA).Dot(pointC) > 0 && (pointC - pointB).Dot(pointC) > 0) {separatedv2 = 1;}else{separatedv2 =0;} float separatedv = separatedv0 || separatedv1 || separatedv2; // --------*** end vertex check ***------------- // ----------*** Edges checks ***-------------- // B - A vector3 ABEdge = vertex1 - vertex0; float ABT = ((spherePos - pointA).Dot(ABEdge)) / (ABEdge.Dot(ABEdge)); vector3 projA = pointA + ABT * ABEdge; // projection center sphere onto plane edge A vector3 SphereProjA = spherePos - projA; vector3 v2Proj = pointC - projA; float separatedEdgeA; if(sqrt(SphereProjA.Dot(v2Proj)) > radius && SphereProjA.Dot(v2Proj)) {separatedEdgeA = 1;}else{separatedEdgeA = 0;} // C - B vector3 BCEdge = vertex2 - vertex1; float BCT = ((spherePos - pointB).Dot(BCEdge)) / (BCEdge.Dot(BCEdge)); vector3 projB = pointB + BCT * BCEdge; // projection center sphere onto plane edge B vector3 SphereProjB = spherePos - projB; vector3 v0Proj = pointA - projB; float separatedEdgeB; if(sqrt(SphereProjB.Dot(v0Proj)) > radius && SphereProjB.Dot(v0Proj)) {separatedEdgeB = 1;}else{separatedEdgeB = 0;} // A - C vector3 CAEdge = vertex0 - vertex2; float CAT = ((spherePos - pointC).Dot(CAEdge)) / (CAEdge.Dot(CAEdge)); vector3 projC = pointC + CAT * CAEdge; // projection center sphere onto plane edge C vector3 SphereProjC = spherePos - projC; vector3 v1Proj = pointB - projC; float separatedEdgeC; if(sqrt(SphereProjC.Dot(v1Proj)) > radius && SphereProjC.Dot(v1Proj)) {separatedEdgeC = 1;}else{separatedEdgeC = 0;} // edge separation check float separatede = separatedEdgeA || separatedEdgeB || separatedEdgeC; // ----------*** end edge check ***------------------- if(separatedf || separatedv || separatede) { return false; } else { return true; } } } Edited by Veer.

##### Share on other sites
Your implementation resembles more of a "is a point in front of or behind a plane?" test.

If you need ray-triangle intersection testing, I recommend taking using a published and tested method. The Möller-Trumbore test is a good one I prefer. An implementation of that can be found from MathGeoLib (code).

If you are actually looking for a point behind/infrontof test, then try the Plane::SignedDistance function.

##### Share on other sites
I just can't seem to get this implementation right.. does anyone have some other great example of sphere triangle collision? or maybe point out what is wrong with this implementation. Thanks

##### Share on other sites
Christer Ericson has a triangle-sphere collision routine in his book Real-Time Collision detection. The algorithm is implemented in MathGeoLib here.

1. 1
2. 2
3. 3
4. 4
Rutin
15
5. 5

• 14
• 9
• 9
• 9
• 10
• ### Forum Statistics

• Total Topics
632912
• Total Posts
3009197
• ### Who's Online (See full list)

There are no registered users currently online

×