Skip to content

Instantly share code, notes, and snippets.

@werelax
Created March 23, 2014 00:04
Show Gist options
  • Save werelax/9716346 to your computer and use it in GitHub Desktop.
Save werelax/9716346 to your computer and use it in GitHub Desktop.
circle collision detection
function dynamicCollision(agent1, agent2) {
function getAngle(v) {
return Math.atan2(v.y, v.x);
}
function normalize(v) {
var m = vdistance({ x: 0, y: 0 }, v);
return { x: v.x/m, y: v.y/m };
}
function dotProduct(v1, v2) {
return (v1.x * v2.x) + (v1.y * v2.y);
}
function collidingDistance(a1, a2) {
return (a1.s >= (vdistance(a1, a2) - (a1.r + a2.r)));
}
function makeStationary(a1, a2) {
var v1 = { x: cos(a1.d)*a1.s, y: sin(a1.d)*a1.s },
v2 = { x: cos(a2.d)*a2.s, y: sin(a2.d)*a2.s },
v = { x: v1.x - v2.x, y: v1.y - v2.y },
a = Object.create(a1);
a.s = vdistance({ x: 0, y: 0 }, v);
a.d = getAngle(v);
return a;
}
var origA1 = agent1;
agent1 = makeStationary(agent1, agent2);
if (!collidingDistance(agent1, agent2)) { return false; }
var n = { x: 1 * cos(agent1.d), y: sin(agent1.d) },
c = { x: (agent2.x - agent1.x), y: (agent2.y - agent1.y) },
d = dotProduct(c, n);
// going towards
if (d <= 0) { return false; }
// not close enough
var f = pow2(vdistance({x: 0, y:0}, c)) - pow2(d),
r2 = pow2(agent1.r + agent2.r);
if (f > r2) { return false; }
// collision point
var t = r2 - f,
maxTravel = d - sqrt(t);
// not fast enough for the collision
if (maxTravel > agent1.s) { return false; }
// ok, they collide!! now... wat?
var ratio = (agent1.s == 0)? 0 : maxTravel / agent1.s;
agent1.destination.x = origA1.x + ((origA1.s * ratio) * cos(origA1.d));
agent1.destination.y = origA1.y + ((origA1.s * ratio) * sin(origA1.d));
return { a1: origA1, a2: agent2, d: maxTravel };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment