# Understanding Overlap: in 1 or 2 dimensions

October 9, 2022

## tl;dr

``````if (RectA.Left < RectB.Right && RectA.Right > RectB.Left &&
RectA.Top > RectB.Bottom && RectA.Bottom < RectB.Top)
``````

which is correct but not especially obvious.

A LOT of people think the stackoverflow answer is wrong and try to “fix” it 🤣

## Step by step: in one dimension

Let’s simplify the problem:

• let’s focus only on one dimension – the x axis
• let’s use rectangles – just ignore their heights
(it’s easier to visualize than line segments)

How can 2 rectangles overlap in one dimension? There seems to be a lot of cases 🤔

• left of B could be inside A
• (or) right of B could be inside A  Both sides of B are inside A. But neither of A’s sides are inside B. We need symmetry…

What are we left with?

• left of B could be inside A
• (or) right of B could be inside A
• (or) left of A could be inside B
• (or) right of A could be inside B

Simple? Did we cover all the cases? (no! read until the end)

Personally, that’s when I turned to stackoverflow.

## A different perspective

If overlap is hard to pin down, let’s try to define the opposite: what does it look like when rectangles do NOT overlap? in English:

• A is to the left of B
• (or) A is to the right of B

let’s turn this to pseudo-code:

``````no_overlap = a.right < b.left || a.left > b.right
// in other words, overlap is the inverse
overlap = !(a.right < b.left || a.left > b.right)
``````

De Morgan’s Laws say that:

• not (A or B) = (not A) and (not B)
• not (A and B) = (not A) or (not B)
``````// unchanged, from above
overlap = !(a.right < b.left || a.left > b.right)

// applying De Morgan: conditions inverted, || becomes &&
overlap = !(a.right < b.left) && !(a.left > b.right)

// flipping > and < comparisons
overlap = a.right > b.left && a.left < b.right

// reorganizing order of conditions (to match stackoverflow...)
overlap = a.left < b.right && a.right > b.left
``````

Looping back to the beginning, check the first line of answer:

``````if (RectA.Left < RectB.Right && RectA.Right > RectB.Left &&
RectA.Top > RectB.Bottom && RectA.Bottom < RectB.Top)
``````

The same “to-the-left-of” or “to-the-right-of” cases apply. You also need to consider “above” and “below” cases.

(top and bottom are relative to … the direction of your y-axis) 😬

``````// unchanged, from above
overlap = !(a.right < b.left || a.left > b.right ||
a.bottom > b.top || a.top < b.bottom)

// applying De Morgan: conditions inverted, || becomes &&
overlap = !(a.right < b.left) && !(a.left > b.right) &&
!(a.bottom > b.top) && !(a.top < b.bottom)

// flipping > and < comparison
overlap = a.right > b.left && a.left < b.right &&
a.bottom < b.top && a.top > b.bottom

// reorganizing order of conditions (to match stackoverflow...)
overlap = a.left < b.right && a.right > b.left &&
a.top > b.bottom && a.bottom < b.top
``````

Back to this:

``````if (RectA.Left < RectB.Right && RectA.Right > RectB.Left &&
RectA.Top > RectB.Bottom && RectA.Bottom < RectB.Top)
``````

## Edge Case

What case did we miss earlier? • 2 rectangles
• same dimensions
• exactly on top of each other

In that case, neither rectangles is inside the other… but the stackoverflow solution works for all cases 😄

## Discussion

Depending on your situation, the width of your rectangle boundary (1 pixel, or whatever units) might make a difference: consider changing `<`/`>` to `<=`/`>=` if needed.

If you’re still not convinced, try this interactive tool.