2D Collision Simulation on Polygons

Project Summary

This project is a 2D collision simulation on polygons using PBD. It explores the dynamics of collisions between various shapes in a two-dimensional space.

Presentation

Image Gallery

Forces are colored according to their sign and magnitude. Pulling forces are blue, while pushing forces are red.

Design

I started this project from my finished Assignment 4 (Inverse Kinematics), because that project already had a set up for a 2D camera, which is what I wanted in my project. I also copied the code for the springs from Assignment 5 (Cloth Sim) into my project, because my polygons are essentially cloths with very, very rigid springs. I did some refactoring and put the behavior for the springs into the Spring class, and made that class inherit from a base class Constraint. This would make it much easier to add new types of constraints, such as the Pin.

The Pin constraint works similiar to fixing a particle, but it can be overcome with enough force. It can be used to make objects that rotate around a fixed point, like see-saws and swings.

I will show you some header files to demonstrate the interfaces of the objects, but keep in mind they may be edited for brevity. For instance, the Polygon class has some geometric helper methods that I won't show you here.

Constraint Class

The Constraint class, described earlier, provides methods for satisfying the constraint, and drawing it.

class Constraint {
public:
    virtual void satisfyConstraint(double h) = 0;
    virtual void draw() = 0;
};

Polygon Class

The Polygon class holds Particles and Constraints. It has a constructor that takes in a list of points. It will automatically generate the particles and springs connecting them. There is also a method willIntersect that will check if a particle will intersect this polygon. If it will, it returns true and outputs the particles making up the intersected edge to b1 and b2, and the point p where the intersection normal intersects this edge.

class Polygon {
public:
    Polygon(const std::vector<Eigen::Vector2d>& vertices);
    bool willIntersect(std::shared_ptr<Particle> a, std::shared_ptr<Particle>& b1, std::shared_ptr<Particle>& b2, Eigen::Vector2d& p);
    std::vector<std::shared_ptr<Particle>> particles;
    std::vector<std::shared_ptr<Constraint>> constraints;
};

PBD versus Rigid Body - What I Learned

PBD works better than rigid body, in my opinion, for the following reasons:

I know this because when I started my project, I implemented rigid body, and encountered these problems. I then switched to PBD.

References

Sources

Libraries