I am trying to implement a platformer where both the player and the level are made up of arbitary polygons. One requirement is that the player can stand still on slopes, and walk up and down them freely without resistance.

For collision detection, I have been using the Separating Axis Theorem (SAT) to calculate overlap between the player and environment. The problem is with the resolution phase. The SAT gives the axis of minimum overlap and the amount you need to move an object along the normal in order to resolve this overlap. This method leads to the player sliding downwards when gravity is applied on a slope, or encountering resistance when moving horizontally into a slope.

To solve this, I want to resolve the collision by applying the minimum y-offset:

SAT method versus proposed method

And an answer to a similar question here seems to provide some of the ground work of how to do it, but I don't feel I have all the information I need. How would such a method work for arbitary polygons? From which point do I need to be calculating the overlap from? Do I have all the information I need already from calculating the separating axis or do I need to compute further values?


2 Answers 2


The minimum y offset can be calculated with the minimum overlap:

SAT slopes

The blue line is the MTV from the SAT algorithm, the red line is the minimum Y offset.

phy::vect2D c =  phy::_poly_collision(p1,p2);

if(c.y != 0 && c.x != 0) {
    p1.y_pos += ((c.x*c.x) / c.y) + c.y;
} else {
    p1.x_pos += c.x; 
    p1.y_pos += c.y;

Your collision detection should be performed during each frame before the actual displacement takes place. Knowing how much you are displacing in each axis, allows you to calculate your overlap based on how far off the collision was. For instance, if your character falls 10 units due to gravity, but a collision occurs 5 units away, there is a 5 unit overlap that you need to compensate for.

Additionally, when I recently wrote character physics for an object, I broke down the collision tests into vertical and horizontal tests. I first checked and compensated for horizontal collisions, and afterwards vertical. This provided the correct movement behavior I desired.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .