# Collision Detection Needs Fixing

Started by Feb 21 2000 09:23 AM

,
2 replies to this topic

###
#1
Members - Reputation: **275**

Posted 21 February 2000 - 09:23 AM

I need help with my function In3DTriangle. It does not correctly check if the point you specify is in the triangle. I have a feeling that it has something to do with my dotproducts. This function checks if the point is in the triangle by creating 3 planes arround the triangle and checking if the point is on all the planes front sides. The other function below works. It is just there for readibility. Sorry for no HTML formatting.
Function In3DTriangle(PointToCheck As D3DVECTOR, CircleRadius As Single, p1 As D3DVECTOR, p2 As D3DVECTOR, p3 As D3DVECTOR) As Boolean
On Error Resume Next
Dim PlaneNormals(2) As D3DVECTOR
Dim OpposingVector As D3DVECTOR
''Check Bounding Circle First
If Not Abs(GetPlaneDistance(PointToCheck, p1, p2, p3)) < CircleRadius Then Exit Function
''Do this for Side One
OpposingVector.X = (p1.X + p3.X) / 2
OpposingVector.Y = (p1.Y + p3.Y) / 2
OpposingVector.Z = (p1.Z + p3.Z) / 2
PlaneNormals(0).X = p2.X - OpposingVector.X
PlaneNormals(0).Y = p2.Y - OpposingVector.Y
PlaneNormals(0).Z = p2.Z - OpposingVector.Z
''Do this for Side Two
OpposingVector.X = (p1.X + p2.X) / 2
OpposingVector.Y = (p1.Y + p2.Y) / 2
OpposingVector.Z = (p1.Z + p2.Z) / 2
PlaneNormals(1).X = p3.X - OpposingVector.X
PlaneNormals(1).Y = p3.Y - OpposingVector.Y
PlaneNormals(1).Z = p3.Z - OpposingVector.Z
''Do this for Side Three
OpposingVector.X = (p2.X + p3.X) / 2
OpposingVector.Y = (p2.Y + p3.Y) / 2
OpposingVector.Z = (p2.Z + p3.Z) / 2
PlaneNormals(2).X = p1.X - OpposingVector.X
PlaneNormals(2).Y = p1.Y - OpposingVector.Y
PlaneNormals(2).Z = p1.Z - OpposingVector.Z
''This is just to fix my vectors
dx.VectorNormalize PlaneNormals(0)
dx.VectorNormalize PlaneNormals(1)
dx.VectorNormalize PlaneNormals(2)
''now check if it is in the triangle
If dx.VectorDotProduct(PointToCheck, PlaneNormals(0)) > 0 And _
dx.VectorDotProduct(PointToCheck, PlaneNormals(1)) > 0 And _
dx.VectorDotProduct(PointToCheck, PlaneNormals(2)) > 0 Then
In3DTriangle = True
End If
End Function
Function GetPlaneDistance(PointToCheck As D3DVECTOR, p1 As D3DVECTOR, p2 As D3DVECTOR, p3 As D3DVECTOR) As Single
On Error Resume Next
Dim V1 As D3DVECTOR, V2 As D3DVECTOR, CP As D3DVECTOR
Dim TempSingle As Single
V1.X = p1.X - p2.X
V1.Y = p1.Y - p2.Y
V1.Z = p1.Z - p2.Z
V2.X = p1.X - p3.X
V2.Y = p1.Y - p3.Y
V2.Z = p1.Z - p3.Z
dx.VectorCrossProduct CP, V1, V2
TempSingle = (V1.X ^ 2 + V1.Y ^ 2 + V1.Z ^ 2)
CP.X = CP.X / TempSingle
CP.Y = CP.Y / TempSingle
CP.Z = CP.Z / TempSingle
GetPlaneDistance = dx.VectorDotProduct(PointToCheck, CP)
End Function
It is using DX7 with Visual Basic. Object DX is valid also.

###
#2
Members - Reputation: **122**

Posted 21 February 2000 - 11:49 AM

Actually you're computing your PlaneNormals wrong, the way you do it only works if all sides are of equal length.

What you wan't to do is to compute the triangles normal first (like you do in GetPlaneDistance) then for each PlaneNormal do a crossproduct with the triangle normal and the edge. There is no need to normalize these as you only want to see if the point is inside or outside.

(I don't know any VB so I write it in pseudo code instead)

Compute the normals like this:

You must also do the testing like this:

Your GetPlaneDistance is also wrong in the last test:

Edited by - Spellbound on 2/21/00 5:52:35 PM

Edited by - Spellbound on 2/22/00 4:53:26 PM

What you wan't to do is to compute the triangles normal first (like you do in GetPlaneDistance) then for each PlaneNormal do a crossproduct with the triangle normal and the edge. There is no need to normalize these as you only want to see if the point is inside or outside.

(I don't know any VB so I write it in pseudo code instead)

Compute the normals like this:

VECTOR E0, E1, E2, TriangleNormal;

VECTOR PlaneNormals[3];

E0 = P1 - P0;

E1 = P2 - P1;

E2 = P0 - P2;

TriangleNormal = Normalize(CrossProduct(E0, E1));

PlaneNormals[0] = CrossProduct(E0, TriangleNormal);

PlaneNormals[1] = CrossProduct(E1, TriangleNormal);

PlaneNormals[2] = CrossProduct(E2, TriangleNormal);

You must also do the testing like this:

VectorDotProduct(PointToCheck - P0, PlaneNormals(0)) > 0

VectorDotProduct(PointToCheck - P1, PlaneNormals(1)) > 0

VectorDotProduct(PointToCheck - P2, PlaneNormals(2)) > 0

Your GetPlaneDistance is also wrong in the last test:

GetPlaneDistance = DotProduct(PointToCheck - P0, CP)

Edited by - Spellbound on 2/21/00 5:52:35 PM

Edited by - Spellbound on 2/22/00 4:53:26 PM

###
#3
Members - Reputation: **275**

Posted 22 February 2000 - 10:35 AM

I figured some calculation was kinda weird. Also I thought I replied to this post? Oh well. I was wondering if GetPlaneDistance was wrong. Is that what you are talking about? I tried and it works. Trust me. Anyhoo, I''ll continue trying to understand the new math concepts you posted for the next hour.