Detect if two rectangles overlap (objects collide)

Hi,

I need to detect if two rectangles overlap. The first rectangle is an object, and the second one is an obstacle.
0, 0 coordinates is the bottom left corner, with X increasing as you go right, and Y increasing as you go up.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#define TOTAL_OBJECTS 1000
#define TOTAL_OBSTACLES 1000

struct object{
float x;
float y;
};
object objects[1000];

struct obstacle{
float x;
float y;
};
obstacle obstacles[1000];

//RectA : Rectangle 1
//RectB: Rectangle 2
// Adaptation from https://stackoverflow.com/a/306332
int CollisionTest(int RectAX1, int RectAX2, int RectAY1, int RectAY2, int RectBX1, int RectBX2, int RectBY1, int RectBY2) {

	return (RectAX1 < RectBX2 && RectAX2 > RectBX1 && RectAY1 > RectBY2 && RectAY2 < RectBY1);
}


// The code below is in a separate function called 30 times per second
for(int i = 0; i < TOTAL_OBJECTS; i++){
  for(int j = 0; j < TOTAL_OBSTACLES; j++){
// 30x20 are both the obstacle and object dimensions
   if(CollisionTest(objects[i].x, objects[i].x + 30, objects[i].y, 
   objects[i].y + 20, obstacles[j].x, obstacles[j].x + 30, obstacles[j].y,
   obstacles[j].y + 20){
   objects[i].y -= 1 // If this is reached, the object colliding with the obstacle should //move one unit down. However, this line of code is never executed.
   }}}

The line with objects[i].y -= 1 is never executed when a collision occurs.
Any help would be greatly appreciated.
Last edited on
You should not call CollisionTest() if i == j.
j should be reset to 0 every iteration of the TOTAL_OBJECTS loop, so they shouldn't be the same.

Here is some psuedocode of what I was intending to do, not sure if I have done it right:

1
2
3
4
5
6
for(every object (variable i)){
    for(every obstacle (variable j)){
    // detect if object (i) is touching obstacle (j)
    // do this for every obstacle
    }
}
Erm...
https://pastebin.com/z4xXLL5k (I had to use pastebin because the site was destroying my formatting.)
i == j exactly TOTAL_OBJECTS times.
Last edited on
The data is incomplete. You need more than two points to define a rectangle. You can only define a line with two points.

If the line is thru the rectangle's diagonal, its still not clear even if its a rectangle or a square, because there's no way to know what angle the sides are at.
zaphraud wrote:
You need more than two points to define a rectangle.

No, you only need two points to define a rectangle.
Aligned rectangles can be defined with just a corner and two sizes, or (equivalently) with two corners.
The X and Y are in the bottom left corner, and the width+height define the size, with X increasing towards the right and Y increasing towards the top.

I have changed my code, however it still does not work:
1
2
3
4
5
6
7
8
9
for(int i = 0; i < TOTAL_OBJECTS; i++){
  for(int j = 0; j < TOTAL_OBSTACLES; j++){
   if(i != j){
// 30x20 are both the obstacle and object dimensions
   if(CollisionTest(objects[i].x, objects[i].x + 30, objects[i].y, 
   objects[i].y + 20, obstacles[j].x, obstacles[j].x + 30, obstacles[j].y,
   obstacles[j].y + 20){
   objects[i].y -= 1 // If this is reached, the object colliding with the obstacle should //move one unit down. However, this line of code is never executed.
   }}}}
Last edited on
It wasn't working due to my plain stupidity. CollisionTest() does not check coordinates as if 0, 0 was the bottom left. I had to make a new boolean function from scratch taking this into account and it now works perfectly.
Thank you all!
return (RectAX1 < RectBX2 && RectAX2 > RectBX1 && RectAY1 > RectBY2 && RectAY2 < RectBY1);
You're original code always returns false because the underlined part says "if Rect A is above Rect B and Rect A is below Rect B." Clearly that's impossible.

To me, it's easier to write and understand the code for when rectangles don't overlap and then negate it. They don't overlap if rectA is above, below, right, or left of rectB:
1
2
3
4
5
noOverlap = (rectA.bottom > rectA.top ||  // rectA above rectB
                   rectA.top < rectB.bottom ||    // rectB below rectB
                   rectA.left > rectB.right ||        // rectA to the right of rectB
                   rectA.right < rectB.left);          // rectA to the left of rectB
bool overlap = !noOverlap;


The code may need slight modification for when rectangles are adjacent to each other.
Topic archived. No new replies allowed.