# 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);

// 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:

--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 ??

I would appreciate any help

TL-DR:

1. Get vector from circle2 to circle1.
3. Use that heading to determine which Cartesian quadrant the collision occurred in.
4. Based on the direction circle1 is heading, turn left or right based on which side of circle2 circle1 touched to steer away from the other circle.

If you have the x and y of both circles, you could see which 'quadrant' of the non-moving circle the moving circle hits, and go from there.

Use some simple vector math. Get a vector in (x, y) from the centre of the non-moving circle to the moving one. It will be handy ot know that the vector going from A to B is $$\vec{C} = \vec{B} - \vec{A}$$ and the heading of a vector (in computing, anyways, I'm not sure about regular linear algebra) is atan2(c.y, c.x);. This is a built in Javascript function. This is how p5.js does it, and where I got this from.

Get vector which points from circle1 to circle2:

let vecBetweenX = circle2.x - circle1.x;
let vecBetweenY = circle2.y - circle1.y;


let heading = Math.atan2(vecBetweenY, vecBetweenX);
// or in degrees:


Based on how the atan2 function returns angles, get it's quadrant by checking where in the unit circle it falls:

let quadrant;
else if (heading <= -1 * Math.PI / 2 && heading >= -1 * Math.PI) quadrant = 1;

// or in degrees:



This tells you which quarter of the non-moving circle the moving circle has hit, with

• quadrant = 0 being the top right;
• quadrant = 1 being the top left;
• quadrant = 2 being the bottom left;
• quadrant = 3 being the bottom right.

Then, based on what direction the moving circle is headed, change the angle. I'm not sure how you're implementing the angle of the moving circle, so here's some pseudo-code, assuming you're going to increase or decrease circle1.angle when you want to turn.

if ( /*circles touch*/ ) {
if (circle.angle == /*moving right*/ ) {
/* should only ever touch quadrant 1 or 2 if it's moving right */
angle += (quadrant == 1 /*touch top left*/) ? /*turn left*/ : /*turn right*/;

} else if (circle.angle == /*moving left*/ ) {
/* should only ever touch quadrant 0 or 3 if it's moving right */
angle += (quadrant == 0 /*touch top right*/) ? /*turn right*/ : /*turn left*/;

} else if (circle.angle == /*moving down*/ ) {
/* should only ever touch quadrant 0 or 1 if it's moving down */
angle += (quadrant == 0 /*touch right-hand-side*/) ? /*turn left*/ : /*turn right*/;

} else if (circle.angle == /*moving up*/ ) {
/* should only ever touch quadrant 2 or 3 if it's moving up */
angle += (quadrant == 2 /*touch left-hand-side*/) ? /*turn left*/ : /*turn right*/;
}
}


I hope I understood what you're asking. This is the most intuitive solution that comes to my mind without using an actual physics engine/rigid collisions.

• yo good omrning i really am trying to follow ur example but if i do something like this [pseudocode with me and ob both being circles that have collided] let vecBetweenX = me.position.x - ob.position.x; let vecBetweenY = me.position.y - ob.position.y; let heading = Math.atan2(vecBetweenY, vecBetweenX); var rt= me.rotation.x+heading var ax = Math.cos(rt)*speed*forward var ay = Math.sin(rt)*speed*forward difx = -ax dify = -ay me.position.x +=difx me.position.y += dify Jul 5, 2022 at 12:59
• then it just shifts around the circle and soetimes goes inside it unpredictably? Jul 5, 2022 at 13:00