pythonpymunk

What's the difference between ContactPoint and ContactPointSet.points in pymunk?


I'm learning pymunk through the documentation and i'm making tests with collisions.

I found out that the CollisionHandlers execute 4 custom callback functions every Space.step() command for each collision between objects. So when i'm editing a custom callback function like begin, in my case, i can use the Arbiter to get information about the points colliding of the two shapes involved in the collision.

I understood that to get this kind of information i have to use the attribute contact_point_set of the Arbiter but here is the problem: the attribute points of the ContactPointSet object contains a list of a maximum of two points (because two shapes can overlap). But each of those two ContactPoints contains other two points: point_a and point_b (so in total we have 4 points...?). So what points are what in the collision? And of which shapes? Also both the object ContactPoint and ContactPointSet have their distance attributes so which distance is the one between the colliding points of the first and the second shape?

On the documentation i found this regarding ContactPointSet:

points is the array of contact points. Can be at most 2 points.

While regarding ContactPoint:

Contains information about a contact point.

point_a and point_b are the contact position on the surface of each shape.

distance is the penetration distance of the two shapes. Overlapping means it will be negative.

And i don't understand why are there 4 points and 2 distances, and also how a point can contain other points.


Solution

  • Its a bit complicated.

    If a circle collide with a circle (easiest case), there will be one Contact Point. This contains point a and b. The a and b points will be how deep the two shapes overlap, on the "edge" of the two shapes in the deepest point.

    For the more complex shapes there might be two contact points. For example, if a smaller box lies on top of a bigger box perfectly flat, there will be one Contact Point at the bottom left and bottom right corners of the small box, with point a and b being how much overlap there is.

    For more technical details, there's an overview of the collision detection algorithm used on the Howlingmoonsoftware / Chipmunk2D blog. It seems to be down at the moment, but you can find it in the waybackmachine at https://web.archive.org/web/20161004195055/http://howlingmoonsoftware.com/wordpress/enhanced-collision-algorithms-for-chipmunk-6-2

    I have also just added (since you are not the first to ask about this) a simple demo of the contact points to Pymunk, much easier to get a feel by actually moving a shape around. That demo is available here: https://github.com/viblo/pymunk/blob/master/pymunk/examples/collisions.py (will be included with the rest of examples in the next release of pymunk)

    Here is a picture of that example code, with a box colliding with a circle, and the Collision point with a,b and distance drawn:

    example