2
votes

I have implementen the separating axis theorem in java. The collision detection itself works great. But i am stuck when it comes to resolve the collision.

my method to get the translation looks like this:

public float getOverlap(final Projection other) {
    float start = m_min > other.m_min ? m_min : other.m_min;
    float end = m_max < other.m_max ? m_max : other.m_max;
    float translation = end - start;
    return translation;
}

Lets say the projection of the two rectangles in the picture looks like this.

R1.min = 2
R1.max = 8
R2.min = 5
R2.max = 11

Separating axis translation

When i check R1 vs. R2 the translation will be 3 When i checl R2 vs. R1 the translation also will be 3

now i add the translation to the normalized axis

Normalized axis = Vector(1,0)
Translation Vector = Vector(1,0)*3 = Vector (3,0)

And now R1 and R2 both move 3 points to the right, but they are suposed to move in different directions. R1 should move Vector(-3,0), R2 should move Vector(3,0).

how can i compute the right direction?

2

2 Answers

0
votes

My solution:

I substract the center vector R1 from center Vector R2, build the dot product to the tested axis and invert the translation if the dotproduct is smaller then 0

Vector centerR1(R1.x,R1.y);
Vector centerR2(R2.x,R2.y);

Vector R1toR2 = centerR2 - centerR1;

if(R1toR2.dot(axis)<0){
  translation = -translation
}

"When the vector (R1toR2) points in an negative direction, invert the translation"

0
votes

Just gonna post another answer here that solved it for me.

The solution with the dot product didn't work for me, although you seem to check if the dot is < 0 in your answer whereas everywhere else I've seen the check to be >= 0, so I'm not sure would that change anything.

I decided that I would return either a positive or negative overlap in my getOverlap function, and this would indicate the direction of resolution. This would depend on whether the first object's min is less than the second object's min or not.

// Check for overlap of two 1 dimensional lines
function getLineOverlap(min1, max1, min2, max2) {
    let min = Math.max(min1, min2);
    let max = Math.min(max1, max2);

    // if negative, no overlap
    let result = Math.max(max - min, 0);

    // add positive/negative sign depending on direction of overlap
    return result * ((min1 < min2) ? 1 : -1);
};

If this still doesn't work, you might need to multiply your resulting resolution vector by -1.

I got this solution from this stackoverflow answer.