Point-Plane Collision Detection Explained

In my previous postal service I presented a role for detecting collision of a betoken inwards 3D infinite alongside a bird (surface of an object). It plant good plenty inwards my SkyCop demo because all I postulate to banking concern check is if the tip of the main send intersects the surface of other ships. Here's a description of the code, broken into 7 steps to assist you lot sympathise this basic shape of collision detection.

1)Understand the Plane Equation: Ax + By + Cz + D = 0
The bird equation tells us that a betoken (x,y,z) is on a bird having normal vector (A,B,C) in addition to distance D from the origin when Ax + By + Cz + D = 0. If nosotros plug inwards A, B, C, D, x, y, z in addition to larn whatever value other than zero, the betoken (x,y,z) is non on the plane. Also authorities notation that since the dot production of vectors (A,B,C) in addition to (x,y,z) equals Ax + By + Cz, nosotros tin rewrite the Plane Equation as DotProduct(N, P) + D = 0 for N=(A,B,C) in addition to P=(x,y,z).
 
2)Get the collision surface's normal vector.
As noted above, inwards social club to abide by if a betoken is on our collision surface (such as a wall nosotros desire to preclude the thespian from running through), nosotros postulate to know the normal vector perpendicular to the surface. Influenza A virus subtype H5N1 normal vector is computed past times taking the cross production of ii vectors on the plane.

The simplest 2D bird nosotros tin create inwards 3D infinite is a triangle alongside 3 vertices (call them vP1, vP2, in addition to vP3) in addition to I volition focus on a triangular collision surface for simplicity. We compute the normal vector past times generating a vector from vP1 to vP2 in addition to some other from vP2 to vP3 in addition to thus receive got the cross production of those ii vectors to obtain the normal vector. Finally, the normal vector is normalized (made to receive got a length of 1.0) to simplify calculations.
     vN1 = (vP2 - vP1);     vN2 = (vP3 - vP2);     D3DXVec3Cross(&vNormal, &vN1, &vN2);     D3DXVec3Normalize(&vNormal, &vNormal); 
3)Get bird distance using the Plane Equation.
Using our revision of the Plane Equation, DotProduct(N, P) + D = 0, nosotros tin solve for D to larn D = -DotProduct(N, P). So nosotros compute D past times plugging inwards the normal vector in addition to whatever betoken on the plane; whatever of the triangle surface's 3 vertices volition suffice.
     d = - D3DXVec3Dot(&vP1, &vNormal); 
4)Classify the get down in addition to finish points.
Now that we've determined the collision surface's normal vector in addition to distance from the origin (A, B, C, in addition to D) nosotros tin utilization the Plane Equation for something actually cool: determining if a given betoken lies on the plane! When nosotros plug a betoken P=(x,y,z) into the left side of our revised bird equation DotProduct(N, P) + D nosotros larn a lawsuit value, p. If p > 0, the betoken is inwards front end of the plane. If p < 0, the betoken is behind the plane. And of class nosotros know that if p = 0 the betoken lies on the plane.

Since we're solely concerned alongside detecting collisions for moving objects, at that topographic point must move a get down seat where the object moved from (pstart) in addition to a finish seat (pdest) to which the object is moved. The play tricks is realizing that a collision solely occurs if these ii positions receive got dissimilar locations in relation to the plane -- if they're both inwards front end of or both behind the plane, no collision occurred in addition to nosotros tin render from the function.
     p = (D3DXVec3Dot(&vNormal, &pStart) + d);     if ( p > 0.0f ) pStartLoc = PlaneFront;     else if ( p < 0.0f ) pStartLoc = PlaneBack;     else pStartLoc = OnPlane;          p = (D3DXVec3Dot(&vNormal, &pDest) + d);     if( p > 0.0f ) pDestLoc = PlaneFront;     else if (p < 0.0f ) pDestLoc = PlaneBack;     else pDestLoc = OnPlane;              if (pStartLoc == pDestLoc) render false; 
5)Get the ray.
At this betoken nosotros know that an intersection did occur! Great, but at that topographic point is a pocket-size problem; nosotros don't know where it occurred, which is every bit important. The bird that was crossed is an infinitely expanding bird inwards 3D space, ofttimes called a hyperplane, thus nosotros postulate to banking concern check if the collision occurred inside the bounds of our collision surface's borders. Computing the vector, called a "ray", from our object's get down seat (pstart) to its finish seat (pdest) helps create upwards one's hear where the collision occurred. The vector is normalized to simplify calculations.
     ray = pDest - pStart;     D3DXVec3Normalize(&ray, &ray); 
6)Get the intersection point.
Vector math tells us that nosotros tin access points along a ray from pstart to pdest using the formula (pstart + ray * t). Since nosotros know that a betoken along our ray from pstart to pdest definitely intersects the plane, nosotros utilization the bird equation to create upwards one's hear the value of t below. Note that I've plugged the intersection betoken (pstart + ray * t) into the Plane Equation instead of a generic (x,y,z) because nosotros know that betoken lies on the plane. I've likewise renamed pstart to "s" in addition to the ray to "r" for brevity.
  • A(sx + rx*t) + B(sy + ry*t) + C(sz + rz*t) + D = 0
  • A*sx + A*rx*t + B*sy + B*ry*t + C*sz + C*rz*t + D = 0
  • DotProduct(N, s) + t*DotProduct(N, r) + D = 0
  • t = - (DotProduct(N, s) + D) / DotProduct(N, r)
We've already computed the normal vector N=(A,B,C) as good as the bird distance D in addition to the ray thus nosotros tin calcuate t. Then nosotros plug it into our formula to larn the actual intersection betoken on the plane.
     t = - (d + D3DXVec3Dot(&vNormal, &pStart))          / D3DXVec3Dot(&vNormal, &ray);          intersect = pStart + (ray * t); 
7)Determine if intersection striking the collision surface!
We're close there! We determined the intersection betoken where our object collided on a hyperplane corresponding to the collision surface. So the terminal query is, "Does the intersection betoken autumn inside the bounds of our collision surface?" In social club to answer that query nosotros compute vectors from the intersection betoken to the surface vertices in addition to mensurate the angles betwixt those vectors. If nosotros shape a consummate circle, nosotros know the betoken lies inside the bounds of our collision surface!
     v1 = intersect - vP1;     v2 = intersect - vP2;     v3 = intersect - vP3;     D3DXVec3Normalize(&v1, &v1);     D3DXVec3Normalize(&v2, &v2);     D3DXVec3Normalize(&v3, &v3);          // Angles simply about intersection should full 360 degrees (2 PI)     thetaSum = acos(D3DXVec3Dot(&v1, &v2))               + acos(D3DXVec3Dot(&v2, &v3))               + acos(D3DXVec3Dot(&v3, &v1));          if (fabs(thetaSum - (2 * D3DX_PI)) < 0.1)         render true;     else         render false; 
There are a twosome caveats to this method of collision detection. The root is that the triangle surface vertices vP1-vP3 must move specified inwards clockwise social club thus the surface normal vector is computed correctly. We likewise receive got to allow for a pocket-size margin of mistake inwards the calculation of the amount of angles due to the lack of floating-point precision. Finally, I've read that this method should solely move used on convex (as opposed to concave) polygons which practise non plication inward on themselves.

I know this is really low-level in addition to at that topographic point are belike simpler ways to practise it (bounding boxes/spheres come upwards to mind...), but it's kinda peachy to run across how the math makes it work! Please experience complimentary to postal service comments/questions to permit me know what you lot intend of this tutorial. I promise it provides a clearer agreement of what's going on under-the-hood inwards basic point-plane collision detection.

Subscribe to receive free email updates:

0 Response to "Point-Plane Collision Detection Explained"

Post a Comment