Created
August 27, 2014 17:04
-
-
Save kittykatattack/befdddc4985a9a43bf68 to your computer and use it in GitHub Desktop.
A function that bounces apart two moving circles
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
# movingCircleCollision | |
Use it to make two moving circles bounce off each other. | |
Parameters: | |
a. A sprite object with `x`, `y` `centerX`, `centerY` and `radius` properties. | |
b. A sprite object with `x`, `y` `centerX`, `centerY` and `radius` properties. | |
The sprites can contain an optional mass property that should be greater than 1. | |
*/ | |
movingCircleCollision = function(c1, c2) { | |
var combinedRadii, overlap, xSide, ySide, | |
//`s` refers to the collision surface | |
s = {}, | |
p1A = {}, p1B = {}, p2A = {}, p2B = {}, | |
hit = false; | |
//Apply mass, if the circles have mass properties | |
c1.mass = c1.mass || 1; | |
c2.mass = c2.mass || 1; | |
//Set `global` to a default value of `true` | |
if(global === undefined) global = true; | |
//Calculate the vector between the circles’ center points | |
s.vx = c2.centerX - c1.centerX; | |
s.vy = c2.centerY - c1.centerY; | |
//Find the distance between the circles by calculating | |
//the vector's magnitude (how long the vector is) | |
s.magnitude = Math.sqrt(s.vx * s.vx + s.vy * s.vy); | |
//Add together the circles' combined half-widths | |
combinedRadii = c1.radius + c2.radius; | |
//Figure out if there's a collision | |
if (s.magnitude < combinedRadii) { | |
//Yes, a collision is happening | |
hit = true; | |
//Find the amount of overlap between the circles | |
overlap = combinedRadii - s.magnitude; | |
//Add some "quantum padding" to the overlap | |
overlap += 0.3; | |
//Normalize the vector. | |
//These numbers tell us the direction of the collision | |
s.dx = s.vx / s.magnitude; | |
s.dy = s.vy / s.magnitude; | |
//Find the collision vector. | |
//Divide it in half to share between the circles, and make it absolute | |
s.vxHalf = Math.abs(s.dx * overlap / 2); | |
s.vyHalf = Math.abs(s.dy * overlap / 2); | |
//Find the side that the collision if occurring on | |
(c1.x > c2.x) ? xSide = 1 : xSide = -1; | |
(c1.y > c2.y) ? ySide = 1 : ySide = -1; | |
//Move c1 out of the collision by multiplying | |
//the overlap with the normalized vector and adding it to | |
//the circle's positions | |
c1.x = c1.x + (s.vxHalf * xSide); | |
c1.y = c1.y + (s.vyHalf * ySide); | |
//Move c2 out of the collision | |
c2.x = c2.x + (s.vxHalf * -xSide); | |
c2.y = c2.y + (s.vyHalf * -ySide); | |
//1. Calculate the collision surface's properties | |
//Find the surface vector's left normal | |
s.lx = s.vy; | |
s.ly = -s.vx; | |
//2. Bounce c1 off the surface (s) | |
//Find the dot product between c1 and the surface | |
var dp1 = c1.vx * s.dx + c1.vy * s.dy; | |
//Project c1's velocity onto the collision surface | |
p1A.x = dp1 * s.dx; | |
p1A.y = dp1 * s.dy; | |
//Find the dot product of c1 and the surface's left normal (s.l.x and s.l.y) | |
var dp2 = c1.vx * (s.lx / s.magnitude) + c1.vy * (s.ly / s.magnitude); | |
//Project the c1's velocity onto the surface's left normal | |
p1B.x = dp2 * (s.lx / s.magnitude); | |
p1B.y = dp2 * (s.ly / s.magnitude); | |
//3. Bounce c2 off the surface (s) | |
//Find the dot product between c2 and the surface | |
var dp3 = c2.vx * s.dx + c2.vy * s.dy; | |
//Project c2's velocity onto the collision surface | |
p2A.x = dp3 * s.dx; | |
p2A.y = dp3 * s.dy; | |
//Find the dot product of c2 and the surface's left normal (s.l.x and s.l.y) | |
var dp4 = c2.vx * (s.lx / s.magnitude) + c2.vy * (s.ly / s.magnitude); | |
//Project c2's velocity onto the surface's left normal | |
p2B.x = dp4 * (s.lx / s.magnitude); | |
p2B.y = dp4 * (s.ly / s.magnitude); | |
//Calculate the bounce vectors | |
//Bounce c1 | |
//using p1B and p2A | |
c1.bounce = {}; | |
c1.bounce.x = p1B.x + p2A.x; | |
c1.bounce.y = p1B.y + p2A.y; | |
//Bounce c2 | |
//using p1A and p2B | |
c2.bounce = {}; | |
c2.bounce.x = p1A.x + p2B.x; | |
c2.bounce.y = p1A.y + p2B.y; | |
//Add the bounce vector to the circles' velocity | |
//and add mass if the circle has a mass property | |
c1.vx = c1.bounce.x / c1.mass; | |
c1.vy = c1.bounce.y / c1.mass; | |
c2.vx = c2.bounce.x / c2.mass; | |
c2.vy = c2.bounce.y / c2.mass; | |
} | |
return hit; | |
}; |
Author
kittykatattack
commented
Aug 27, 2014
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment