I suck at math and this routine was coded for me years...ago. Just wondering if it could be optimized any? Thx.
You pass the parameters and it returns True or False if the two rotated rects are colliding.
public static function RotatedRectsCollide(x1:Number, y1:Number, x1width:Number, y1height:Number, protation1:Number, x2:Number, y2:Number, x2width:Number, y2height:Number, protation2:Number):Boolean
{
var rotation1:Number = protation1 * prepi; // (Math.PI / 180);
var rotation2:Number = protation2 * prepi; // (Math.PI / 180);
var Ax : Number, Ay : Number, Bx : Number, By : Number; // vertices of the rotated rr2
var Cx : Number, Cy : Number; // center of rr2
var BLx : Number, BLy : Number, TRx : Number, TRy : Number; // vertices of rr2 (bottom-left, top-right)
var ang : Number = rotation1 - rotation2; // orientation of rotated rr1 relative to rr2
var cosa : Number = Math.cos(ang); // precalc trig values
var sina : Number = Math.sin(ang);
var cosa2 : Number = Math.cos(rotation2);
var sina2 : Number = Math.sin(rotation2);
var t : Number, t2 : Number, x : Number, a : Number; // temps
var dx : Number; // deltaX for linear equations
var ext1 : Number, ext2 : Number; // min/max vertical values
x1width *= 0.5;
y1height *= 0.5;
x2width *= 0.5;
y2height *= 0.5;
// move rr2 to make rr1 cannonic
t = x2 - x1;
Cy = y2 - y1;
// rotate rr2 clockwise by rr2->ang to make rr2 axis-aligned
BLx = TRx = t * cosa2 + Cy * sina2;
BLy = TRy = -t * sina2 + Cy * cosa2;
// calculate vertices of (moved and axis-aligned := 'ma') rr2
BLx -= x2width;
BLy -= y2height;
TRx += x2width;
TRy += y2height;
// calculate vertices of (rotated := 'r') rr1
Bx = Ax = -y1height * sina;
t = x1width * cosa;
Ax += t;
Bx -= t;
By = Ay = y1height * cosa;
t = x1width * sina;
Ay += t;
By -= t;
t = sina * cosa;
// verify that A is vertical min/max, B is horizontal min/max
if (t < 0)
{
// BUGFIX: this used to mess up 't' which is used later for if (t == 0)
t2 = Ax; Ax = Bx; Bx = t2;
t2 = Ay; Ay = By; By = t2;
}
// verify that B is horizontal minimum (leftest-vertex)
if (sina < 0)
{
Bx = -Bx;
By = -By;
}
// if rr2(ma) isn't in the horizontal range of
// colliding with rr1(r), collision is impossible
if (Bx > TRx || Bx > -BLx) return false;
// if rr1(r) is axis-aligned, vertical min/max are easy to get
if (t == 0)
{
ext1 = Ay;
ext2 = -ext1;
}
// else, find vertical min/max in the range [BL.x, TR.x]
else
{
x = BLx - Ax;
a = TRx - Ax;
ext1 = Ay;
// 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 = Ax;
if (x < 0)
{
dx -= Bx;
ext1 -= By;
x = a;
}
else
{
dx += Bx;
ext1 += By;
}
ext1 *= x;
ext1 /= dx;
ext1 += Ay;
}
x = BLx + Ax;
a = TRx + Ax;
ext2 = -Ay;
// if the second vertical min/max isn't in (BLx, TRx), then
// find the local vertical min/max on BLx or on TRx
if (a * x > 0)
{
dx = -Ax;
if (x < 0)
{
dx -= Bx;
ext2 -= By;
x = a;
}
else
{
dx += Bx;
ext2 += By;
}
ext2 *= x;
ext2 /= dx;
ext2 -= Ay;
}
}
// check whether rr2(ma) is in the vertical range of colliding with rr1(r)
// (for the horizontal range of rr2)
return !((ext1 < BLy && ext2 < BLy) || (ext1 > TRy && ext2 > TRy));
}