Skip to content
Advertisement

detect collision between two circles and sliding them on each other

I’m trying to detect collision between two circles like this:

var circle1 = {radius: 20, x: 5, y: 5}; //moving
var circle2 = {radius: 12, x: 10, y: 5}; //not moving

var dx = circle1.x - circle2.x;
var dy = circle1.y - circle2.y;
var distance = Math.sqrt(dx * dx + dy * dy);


if (distance < circle1.radius + circle2.radius) {
    // collision detected

}else{ 
    circle1.x += 1 * Math.cos(circle1.angle);
    circle1.y += 1 * Math.sin(circle1.angle);
}

Now when collision is detected I want to slide the circle1 from on the circle2 (circle1 is moving) like this:

enter image description here
–circle1———————————circle2————————-

I could do this by updating the angle of circle1 and Moving it toward the new angle when collision is detected.

Now My question is that how can I detect whether to update/increase the angle or update/decrease the angle based on which part of circle2 circle1 is colliding with ?? (circle one comes from all angles)

I would appreciate any help

Advertisement

Answer

This will depend a bit on how you are using these circles, and how many will ever exist in a single system, but if you are trying to simulate the effect of two bodies colliding under gravity where one roles around to the edge then falls off (or similar under-thrust scenario), then you should apply a constant acceleration or velocity to the moving object and after you compute it’s movement phase, you do a displacement phase where you take the angle to the object you are colliding with and move it back far enough in that direction to reach circle1.radius + circle2.radius.

[edit] To get that redirection after falling though (not sure if you intended this or if it’s just your sketch), there is probably going to be another force at play. Most likely it will involve a “stickiness” applied between the bodies. Basically, on a collision, you need to make sure that on the next movement cycle, you apply Normal Movement, then movement towards the other body, then the repulsion to make sure they don’t overlap. This way it will stick to the big circle until gravity pulls way at enough of a direct angle to break the connection.

[edit2] If you want to make this smoother and achieve a natural curve as you fall away you can use an acceleration under friction formula. So, instead of this:

circle1.x += 1 * Math.cos(circle1.angle);
circle1.y += 1 * Math.sin(circle1.angle);

You want to create velocity properties for your object that are acted on by acceleration and friction until they balance out to a fixed terminal velocity. Think:

// constants - adjust these to get the speed and smoothness you desire
var accelerationX = 1;
var accelerationY = 0;
var friction = 0.8; 

// part of physics loop
circle1.velX += (accelerationX * Math.cos(circle1.angle)) - (friction * circle1.velX);
circle1.velY += (accelerationY * Math.sin(circle1.angle)) - (friction * circle1.velX);
circle1.x += circle1.velX;
circle1.y += circle1.velY;

This way, when things hit they will slow down (or stop), then speed back up when they start moving again. The acceleration as it gets back up to speed will achieve a more natural arc as it falls away.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement