Created
August 19, 2012 17:57
-
-
Save yetanotherportfolio/3396752 to your computer and use it in GitHub Desktop.
javscript collision detection with rotated rect and such
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
//code inspired by http://www.ragestorm.net/tutorial?id=22 | |
var Vect = function(x, y) | |
{ | |
this.x = x || 0; | |
this.y = y || 0; | |
} | |
var Rect = function(pos, size, angle) | |
{ | |
this.pos = pos || new Vect(); | |
this.size = size || new Vect(); | |
this.angle = angle || 0; | |
}; | |
function AddVectors2D(v1, v2) | |
{ | |
v1.x += v2.x; | |
v1.y += v2.y; | |
} | |
function SubVectors2D(v1, v2) | |
{ | |
v1.x -= v2.x; | |
v1.y -= v2.y; | |
} | |
function RotateVector2DClockwise(v, ang) | |
{ | |
var t, | |
cosa = Math.cos(ang), | |
sina = Math.sin(ang); | |
t = v.x; | |
v.x = t*cosa + v.y*sina; | |
v.y = -t*sina + v.y*cosa; | |
} | |
function toRadian(angle) | |
{ | |
return angle * Math.PI /180; | |
} | |
/** | |
* int RotRectsCollision(Rect * rr1, Rect * rr2) | |
*/ | |
function RotRectsCollision(rr1, rr2) | |
{ | |
var A = new Vect();// vertices of the rotated rr2 | |
var B = new Vect(); | |
var C = new Vect();// center of rr2 | |
var BL = new Vect();// vertices of rr2 (bottom-left, top-right) | |
var TR = new Vect(); | |
var ang = toRadian(rr1.angle - rr2.angle); // orientation of rotated rr1 | |
var cosa = Math.cos(ang); // precalculated trigonometic - | |
var sina = Math.sin(ang); // - values for repeated use | |
var t, x, a; // temporary variables for various uses | |
var dx; // deltaX for linear equations | |
var ext1, ext2; // min/max vertical values | |
// move rr2 to make rr1 cannonic | |
C.x = rr2.pos.x; | |
C.y = rr2.pos.y; | |
SubVectors2D(C, rr1.pos); | |
// rotate rr2 clockwise by rr2.angle to make rr2 axis-aligned | |
RotateVector2DClockwise(C, toRadian(rr2.angle)); | |
// calculate vertices of (moved and axis-aligned := 'ma') rr2 | |
BL = TR = C; | |
SubVectors2D(BL, rr2.size); | |
AddVectors2D(TR, rr2.size); | |
// calculate vertices of (rotated := 'r') rr1 | |
A.x = -rr1.size.y*sina; | |
B.x = A.x; | |
t = rr1.size.x*cosa; | |
A.x += t; | |
B.x -= t; | |
A.y = rr1.size.y*cosa; | |
B.y = A.y; | |
t = rr1.size.x*sina; | |
A.y += t; | |
B.y -= t; | |
t = sina*cosa; | |
// verify that A is vertical min/max, B is horizontal min/max | |
if (t < 0) | |
{ | |
t = A.x; | |
A.x = B.x; | |
B.x = t; | |
t = A.y; | |
A.y = B.y; | |
B.y = t; | |
} | |
// verify that B is horizontal minimum (leftest-vertex) | |
if (sina < 0) | |
{ | |
B.x = -B.x; | |
B.y = -B.y; | |
} | |
// if rr2(ma) isn't in the horizontal range of | |
// colliding with rr1(r), collision is impossible | |
if (B.x > TR.x || B.x > -BL.x) | |
return 0; | |
// if rr1(r) is axis-aligned, vertical min/max are easy to get | |
if (t == 0) | |
{ | |
ext1 = A.y; | |
ext2 = -ext1; | |
} | |
// else, find vertical min/max in the range [BL.x, TR.x] | |
else | |
{ | |
x = BL.x-A.x; | |
a = TR.x-A.x; | |
ext1 = A.y; | |
// if the first vertical min/max isn't in (BL.x, TR.x), then | |
// find the vertical min/max on BL.x or on TR.x | |
if (a*x > 0) | |
{ | |
dx = A.x; | |
if (x < 0) | |
{ | |
dx -= B.x; | |
ext1 -= B.y; | |
x = a; | |
} | |
else | |
{ | |
dx += B.x; | |
ext1 += B.y; | |
} | |
ext1 *= x; | |
ext1 /= dx; | |
ext1 += A.y; | |
} | |
x = BL.x+A.x; | |
a = TR.x+A.x; | |
ext2 = -A.y; | |
// if the second vertical min/max isn't in (BL.x, TR.x), then | |
// find the local vertical min/max on BL.x or on TR.x | |
if (a*x > 0) | |
{ | |
dx = -A.x; | |
if (x < 0) | |
{ | |
dx -= B.x; | |
ext2 -= B.y; | |
x = a; | |
} | |
else | |
{ | |
dx += B.x; | |
ext2 += B.y; | |
} | |
ext2 *= x; | |
ext2 /= dx; | |
ext2 -= A.y; | |
} | |
} | |
// check whether rr2(ma) is in the vertical range of colliding with rr1(r) | |
// (for the horizontal range of rr2) | |
return !((ext1 < BL.y && ext2 < BL.y) || | |
(ext1 > TR.y && ext2 > TR.y)); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment