This project has moved and is read-only. For the latest updates, please go here.

How to determine collision with a specific polygon face

Topics: Developer Forum
Jul 9, 2010 at 7:15 PM

Say I have a rectangle fixture/body and I want to know which of the 4 faces of the rectangle another body collided with. How would I do this? I tried using the LocalNormal of the contact manifold, but that did not seem to be the consistent result I expected. Is there some other way to do this?

Jul 11, 2010 at 9:26 PM

Here's an extension I added to the vertices class to figure out which edge is the closest to a given point:


public int GetClosestEdge(Vector2 point)
    int closest = -1;
    float lowestDistance = float.MaxValue;

    for (int i = 0; i < this.Count; i++)
        var diff = point - this[i];
        var dist = diff.LengthSquared();
        if (dist < lowestDistance)
            lowestDistance = dist;
            closest = i;

    var p = this[closest];
    var edge1 = GetEdge(closest);
    edge1 = p + edge1;

    var edge2 = -GetEdge(PreviousIndex(closest));
    edge2 = p + edge2;

    if ((point - edge1).LengthSquared() < (point - edge2).LengthSquared())
        return closest;
        return PreviousIndex(closest);

Basically it works by first finding the closest vertex to the given point. Once you have that it needs to make a choice whether to take the edge leading to that vertex or the edge leading away. The way it makes a choice is to calculate the point along each edge that is one unit away from the closest vertex; whichever point is closer the given point is chosen as the closest edge.


This may not be the most optimal way of finding the closest edge to a point, but I gave up trying to get the contact list in OnCollision to produce any meaningful results. Sometimes it would use vertexes in one polygon, sometimes in the other; most of the time the vertex index it would return is an invalid index and doesn't belong to either of the polygons involved in the collision.


So basically I do this:


int edge = body2.WorldVertices.GetClosestEdge(contactList[0].Positon);


And in all my tests it seems to get the edge that the collision occurred on.

Jul 11, 2010 at 10:29 PM

Ok thanks, I'll give it a try. But where's the implementation of GetEdge(). It's not built in to the engine. Is that your function?

Jul 11, 2010 at 10:40 PM

Oh I should mention this is in FP3.0. It appears as though your implementation is for FP2.x.

Jul 12, 2010 at 4:22 AM

Ah yeah, this is 2.1.3. Sorry; I figured most people would be using that since 3.0 isn't stable yet.


Unfortunately I don't have any experience with 3.0. Maybe it's implementation provides useful collision data on the geometry OnCollision event?