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.Normalize();
edge1 = p + edge1;
var edge2 = GetEdge(PreviousIndex(closest));
edge2.Normalize();
edge2 = p + edge2;
if ((point  edge1).LengthSquared() < (point  edge2).LengthSquared())
{
return closest;
}
else
{
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.
