Hi.

If you're going down this road, I can't recommend enough learning about projection. Get it down cold!

(Similarly, the dot product.)

That would let you do something akin to what XeduR mentions. Choose one of your two rectangles. We want to pretend this one is lined up with the x- and y-axes. Find two of its corners next to each other. I believe you could do, say, **rect:localToContent(rect.width / 2, rect.height / 2)**, until you're more comfortable about the math.

This is where projection comes in. First off, find the four corners of the other rectangle, following the same approach as before.

Now, we want to set up triangles like what you see in the projection link. We already have our segment from the first rectangle, which will be the bottom side. The long, diagonal side will go from one point on the segment (either one, just stick with it, and also use this decision to orient the segment) to one of the corners in the second rectangle.

We do this for all corners and find their projections. The scalar projection is our "component" along the segment, basically our "x" in "first rectangle space". Now, in 2D it happens that rotating a direction **(x, y)** by 90 degrees is as simple as **(-y, x)**. We can find our "y" component (in particular, with the correct sign) as the scalar projection of our rejection from the previous step with this rotated direction.

At this point we have our second rectangle in the "first rectangle space". Because it's probably rotated, you can't do the easier checks from before, although of course you can see if *all* points are left / right / above / below.

What you can do, especially if you only care about overlap (i.e. ignoring one rectangle inside the other without touching), is to just check

all pairs of sides. I have some code handy for that, for two segments **AB** and **CD**:

local M = {}
local function Lerp (x, y, vx, vy, s)
return x + s * vx, y + s * vy
end
function M.Intersect (ax, ay, bx, by, cx, cy, dx, dy)
local vx, vy, wx, wy = bx - ax, by - ay, dx - cx, dy - cy
local vpx, vpy, wpx, wpy = -vy, vx, -wy, wx
local pqx, pqy, vpw = cx - ax, cy - ay, vpx * wx + vpy * wy
-- Common case.
if 1 + vpw^2 ~= 1 then
local s, t = -(wpx * pqx + wpy * pqy) / vpw, -(vpx * pqx + vpy * pqy) / vpw
if s >= 0 and s <= 1 and t >= 0 and t <= 1 then
return Lerp(ax, ay, vx, vy, s)
-- Segments are parallel or degenerate.
else
-- MUCH longer, but if you run into this you can basically do the
-- stuff from the tutorial
end
return false
end
return M

I can elaborate if necessary.

A physics engine, including Box2D if I'm not mistaken, will use something like the separating axis theorem, which also builds on top of projection.

David Eberly also has (C++) code for this at his Geometric Tools site. Relevant to what I said above would be the aligned / oriented box cases.

(A few years ago I was trying to write up a little geometry tutorial and then got carried away; it's a hopeless mess at the moment, but I have delusions of giving it more love again. The "vector basics" and "vector intersections" pages in particular develop some of what I wrote above, but are among the pages most of in need of polish.)