@.oisyn Yep!
The first "building block" of my project is an object called 'CollisionRectangle' that has four points: UL (upper left), UR (upper right), LL (lower left), and LR (lower right). You build it by passing a center x/y, a width/height, and a rotation and these four points are generated.
UL UR
+---------------------------+
| |
| -y |
| |
| (0,0) |
| |
| +y |
| |
+---------------------------+
LL LR
My collision starts off like the following (pseudocode):
function RectanglesAreColliding(CollisionRectangle a, CollisionRectangle b)
{
// calculate the axes
var axis1 = a.UR - a.UL;
var axis2 = a.UR - a.LR;
var axis3 = b.UL - b.LL;
var axis4 = b.UL - b.UR;
return CheckAxis(a, b, axis1) &&
CheckAxis(a, b, axis2) &&
CheckAxis(a, b, axis3) &&
CheckAxis(a, b, axis4);
}
This is where I was talking about how I thought that I might be getting incorrect results because I wasn't normalizing these axes, but normalizing them made no difference. Also, if I don't check 'axis2' here I get the same results which is leading me to believe that I'm not using the right axis.
My 'CheckAxis' is as follows (again, pseudocode, it's shorter):
function CheckAxis(CollisionRectangle a, CollisionRectangle b, Vector2 axis)
{
var a_proj_ul = Project(a.UL, axis);
var b_proj_ul = Project(b.UL, axis);
/* so on and so forth, project each of the 4 corners of each rectangle
onto the axis */
// find "values" for each of the projected points (used to use
// square magnitude)
//
// thanks to SmokingRope for pointing out I need to use the
// dot product between the projection and axis here instead!
var a_ul = Dot(a_proj_ul, axis);
var b_ul = Dot(b_proj_ul, axis);
/* so on and so forth for each projection... */
// find the min and max "value" for each rect
var a_min = Math.Min(Math.Min(a_ul, a_ur), Math.Min(a_ll, a_lr));
var a_max = Math.Max(Math.Max(a_ul, a_ur), Math.Max(a_ll, a_lr));
var b_min = Math.Min(Math.Min(b_ul, b_ur), Math.Min(b_ll, b_lr));
var b_max = Math.Max(Math.Max(b_ul, b_ur), Math.Max(b_ll, b_lr));
// check for overlap on this axis
return b_min <= a_max || b_max <= a_min;
}