Dynamic Circle - Static Circle Collision

Started by
3 comments, last by Ocarinha 8 years, 9 months ago

I'm trying to create a collision between two circles (c1: player moves and c2: static object) and put in the shortest possible distance, away when there is overlap. The below code works, but inaccurately because always push horizontally and vertically: http://postimg.org/image/ik15bv6s1/

Does anyone know the right algorithm to do this?


var distance = Math.sqrt(Math.pow(c1.x - c2.x, 2) + Math.pow(c1.y - c2.y, 2));

// r1, r2 = radius
// Collision test
if (distance <= (r1 + r2)) {

    var distanceToMove = (r1 + r2) - distance;

    if (c1.x < c2.x) {
        c1.x -= distanceToMove;
    } else {
        c1.x += distanceToMove;
    }

    if (c1.y < c2.y) {
        c1.y -= distanceToMove;
    } else {
        c1.y += distanceToMove;
    }

}
Advertisement

Take the difference vector between the two circles (c1 - c2). This is basically a vector that points from c2 toward c1. If you end up needing to move c1, this vector points in exactly the direction you'll want to move c1, though the distance in this direction will need to be adjusted, as described below.

Check the length of this difference vector, and compare against the sum of the radii, as you are already doing.

If the circles overlap, then multiply the difference vector by distanceToMove / distance. This multiplication is because you are first turning the difference vector into a unit vector by dividing it by its length (distance), and then adjusting its length from 1 to the actual distance you want to move by multiplying it by distanceToMove.

Add this adjusted vector to c1. No conditional statements required; the signs will already be correct, based on the original subtraction of c1 - c2.

"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke

If the circles overlap, then multiply the difference vector by distanceToMove / distance. This multiplication is because you are first turning the difference vector into a unit vector by dividing it by its length (distance), and then adjusting its length from 1 to the actual distance you want to move by multiplying it by distanceToMove.

Add this adjusted vector to c1. No conditional statements required; the signs will already be correct, based on the original subtraction of c1 - c2.


Or you could simply multiply by (r1 + r2) / distance. There's no need to calculate the distance needed to move, nor to do any vector addition. Simply scale the vector by a ratio equal to desiredDistance / actualDistance and you're done.

Also, it's a pathological case but c1 and c2 *could* be right on top of each other which would cause a division by zero error. You'll need to handle that case specially.

So am I the only one who doesn't understand the original poster's question?

Pew! Pew! Pew!

Genial, this vector makes ??all the difference, thank you Andy Gainey, I was using an ugly hack and ignoring it happy.png

This topic is closed to new replies.

Advertisement