I've found this approach to be the most instructive:
Say A and B are the rectangles.
A and B
don't collide if either of these conditions hold:
- The left border of B is to the right of the right border of A.
- The top border of B is below the bottom border of A.
- The right border of B is to the left of the left border of A.
- The bottom border of B is above the top border of A.
If neither of these conditions holds, the rectangles are colliding. These conditions are the exact opposite of the individual ones that Sheepolution posted:
- The left border of B is to the right of the right border of A: that's written as B.x > A.x + A.w
- The top border of B is below the bottom border of A: that's written as B.y > A.y + A.h
- The right border of B is to the left of the left border of A: that's written as B.x + B.w < A.x
- The bottom border of B is above the top border of A: that's written as B.y + B.h < A.y
So, the rectangles do NOT collide if:
Code: Select all
(B.x > A.x + A.w) or (B.y > A.y + A.h) or (B.x + B.w < A.x) or (B.y + B.h < A.y)
therefore they DO collide if:
Code: Select all
not ((B.x > A.x + A.w) or (B.y > A.y + A.h) or (B.x + B.w < A.x) or (B.y + B.h < A.y))
(I've simply inserted a 'not').
By De Morgan's laws, not (P1 or P2 or P3 or P4) equals (not P1) and (not P2) and (not P3) and (not P4).
Negating a < only needs changing it to >=, so the above check for whether they DO collide can be simplified to:
Code: Select all
(B.x <= A.x + A.w) and (B.y <= A.y + A.h) and (B.x + B.w >= A.x) and (B.y + B.h >= A.y)
which is basically what Sheepolution posted.
Depending on your boundary conditions, the >= might need to be > and vice versa, and the <= might need to be < and vice versa.