I am making a game in HTML5, Canvas, and this is my code for resolving collision between two moving circles:
function resCCCol(a, b) {
var dx = a.x - b.x;
var dy = a.y - b.y;
var dist = dx * dx + dy * dy;
var vx = b.vx - a.vx;
var vy = b.vy - a.vy;
var dot = dx * vx + dy * vy;
if (dot > 0) {
var scale = dot / dist;
var cx = dx * scale;
var cy = dy * scale;
var mass = a.r + b.r;
var cw1 = 2 * b.r / mass;
var cw2 = 2 * a.r / mass;
a.vx += cw1 * cx
a.vy += cw1 * cy
b.vx -= cw2 * cx
b.vy -= cw2 * cy
}
}
If I set the coordinates so that the circles overlap but still have their velocity both at 0, the circles won't push out each other, that is the problem. How do I fix this?
EDIT: Fiddle: http://jsfiddle.net/yP7xf/2/, click "Glitch it!" to see the glitch, as you see they won't separate.
When two circles overlap with no velocity your
resCCCol()
method won't work sincedot
is0
. Even if you change theif
statement to execute ondot >= 0
, you're still left with 0 velocity.You should handle cases when
dot === 0
. The easiest way is to simply give them a set velocity when the velocity is0
:This, of course, will only propel them away from each other towards opposite corners of the screen, but you could easily implement something that better adheres to the laws of physics (ignoring the fact that two objects can't take up the same space).
I'm not sure what the purpose of
dot
is (maybe I'm missing some maths knowledge here), but two circles colliding happens ifdist < sum(radii)
. Should this occur, you should deflect the circles, but ensure they have at least some small speed to ensure they separate.It's not entirely clear what the best way to handle this would be, and I think it would be better to make sure you don't end up in this situation in the first place (by making sure they don't ever overlap with zero velocity), but a quick and dirty fix is to check
dot === 0
and if so, give them some velocity. For example:http://jsfiddle.net/yP7xf/5/
Now what velocity should you give them? That's something you'll need to work out. Probably you want them to move apart so you can probably calculate some vector based on a line from the center of one to the center of the other and send one in one direction along that vector and the other in the other at whatever speed you think is appropriate. But if they are laid exactly on top of each other (centers at the same point), then you'll need to account for that case too.