I'm trying to write some collision detection code.
ATM i have the code properly resolving Ellipsoid v. Ellipsoid collisions, and Box v. Box collisions, but Ellipsoid v. Box collisions doesnt work.
In general how do you test for interesection between these two.
What i've been doing is:
Finding the closest point on the ellipsoid to the box, and vice versa.
vector3 closestVertexOnBox = // Closest vertex on the box to the ellipsoid;
vector3 closestPointOnEllipsoid = // Closest vertex on the ellipsoid to the box
In this case ( ellipsoid v. box ) you have 4 axes.
- The axis from the center of the circle to the nearest point on the box.
- The X,Y,Z standard axes ( assuming its an AABB ) -
Put them all in an array
vector3[] axes = { normalize( closestVertexOnBox - ellipsoid.origin ), unitX, unitY, unitZ }
Then for each axis in that array, Project the vector from the center of each shape, to its vertex closest to the other shape; onto each axis to find the projected half widths.
float minOverlap = infinity
vector3 overlapAxis;
for each axis in axes
{
float prjBoxHalfWidth = Dot ( axis , closestVertexOnBox - box.origin )
float prjEllipsoidHalfWidth = Dot ( axis , closestPointOnEllipsoid - ellipsoid.origin )
If the sum of any of the projected half widths are smaller than the projected distance between the two, then their is no collision
float prjDistance = Dot( axis , box.origin - ellipsoid.origin )
if(prjBoxHalfWidth + prjEllipsoidHalfWidth < prjDistance) return // no collision
Now get the axis with the least overlap out of all of them
float overlap = prjBoxHalfWidth + prjEllipsoidHalfWidth - prjDistance
if(overlap < minOverlap) {
minOverlap = overlap;
overlapAxis = axis;
}
Then resolve the overlap
ellipsoid.origin += overlapAxis * minOverlap/2
box.origin -= overlapAxis * minOverlap/2
Thats pretty much my ( pseduofied ) code. If thats good, then i might have an error, but thats wrong, then what am i not taking into consideration or forgetting.
Answer
How do you store the ellipsoid?
If it has a position, orientation and the radius in local x- and y-axis, it might be easier to calculate the inverse transformation matrix, that transforms the ellipsoid to a circle. Transform the AABB into that space too using that matrix, then you can make simple triangle-circle collision tests.
Edit: In the left image you see the original ellipsoid with the axis aligned box. In the right image both objects are transformed by the ellipsoid's inverse matrix, so the ellipsoid becomes a circle and the AABB becomes 2 triangles. Now its only a matter of 2 triangle-circle tests.
No comments:
Post a Comment