# 2D Rects collision problems

This topic is 2123 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi! I've written my own simple function to detect collisions of rectangles and it works not accurate and not always. So here is my code:

bool GameLogic::IsRectsCollide(float* rect1, float* rect2, float eps)
{
float r1_left = rect1[0];
float r1_top = rect1[1];
float r1_right = rect1[2];
float r1_bottom = rect1[3];
float r2_left = rect2[0];
float r2_top = rect2[1];
float r2_right = rect2[2];
float r2_bottom = rect2[3];
if (r2_right - r2_left < r1_right - r1_left)
{
swap(r1_left, r2_left);
swap(r1_top, r2_top);
swap(r1_right, r2_right);
swap(r1_bottom, r2_bottom);
}

if ( ( r1_left >= r2_left && r1_left <= r2_right && r1_top >= r2_bottom && r1_top <= r2_top ) ||
( r1_right >= r2_left && r1_right <= r2_right && r1_top >= r2_bottom && r1_top <= r2_top ) ||
( r1_right >= r2_left && r1_right <= r2_right && r1_bottom >= r2_bottom && r1_bottom <= r2_top ) ||
( r1_left >= r2_left && r1_left <= r2_right && r1_bottom >= r2_bottom && r1_bottom <= r2_top ) )
{
return true;
}

return false;
}


Image shows typical fail...

##### Share on other sites

I would not design the code like that. It is much more complicated doing it your way and harder to maintain in the future and even unreadable. It does not need to be that way.

Why not design a data structure called Rectangle with data members x and y and width and height? And have your ship bounded by a rectangle object?

The swap operations and arrays make things more complicated.

psuedo code:

Rectangle rectangle = new Rectangle(x,y,width,height);

public boolean intersects(Rectangle other)

{

}

// collision algorithm

if(rectangle.intersects(asteroids.getRectangle())

{

}

Edited by warnexus

##### Share on other sites

For rectangles it's very simple.

// Assuming left right top and bottom are not flipped or invalid
if (r1_left < r2_right && r1_right > r2_left && r1_top < r2_bottom && r1_bottom > r2_top)
return true;  // Collision
return false;  // No collision

 - I suppose if the edges are equal they would be touching but not necessarily colliding.

Edited by achild

##### Share on other sites

It's way less complicated for simple rectangle collision:

IF:
1st's top IS HIGHER THAN 2nd's bottom AND
1st's bottom IS LOWER THAN 2nd's top AND
1st's right IS MORE RIGHT THAN 2nd's left AND
1st's left IS LESS RIGHT THAN 2nd's right
THEN: WE HAVE COLLISION

##### Share on other sites

Wrote it quite some time ago, but it has everything you need.

##### Share on other sites

Thanks, I've fixed it.

##### Share on other sites

For rectangles it's very simple.

// Assuming left right top and bottom are not flipped or invalid
if (r1_left < r2_right && r1_right > r2_left && r1_top < r2_bottom && r1_bottom > r2_top)
return true;  // Collision
return false;  // No collision

 - I suppose if the edges are equal they would be touching but not necessarily colliding.

It is correct, but there is performance problem and need to be optimized.
In your "if" statement you have 3 &&, which means that all comparisons must be done before return correct answer. In practical case "return false" state is more frequent than "return true" and if you will rewrite your code to determine "non collided" situations in earlier stage it will increase efficiency.
for example:

if( ( r1_left > r2_right ) || ( r1_right < r2_left ) || (r1_top > r2_bottom ) || ( r1_bottom > r2_top ) )
return false;
return true;

in this case if first comparison( r1_left > r2_right ) is false it will immediately return false.
Edited by koiava

##### Share on other sites

Lazy evaluation of && does that already (bails out immediately if one of the operands is false).

EDIT: Likewise || immediately bails out with true if any operand is true. That's why in C you can do

if(ptr && ptr->dereference_it)

without causing a null pointer access violation.

right.

##### Share on other sites

no need a fancy code, here a simple solution:

bool point_in_rect(int x, int y, rect r)
{
if(x<r.left) return false;
if(x>r.right) return false;
if(y<r.top) return false;
if(y>r.down) return false;
return true;
}
bool rect_collision(rect r1, rect r2)
{
if(point_in_rect(r1.top, r1.left,r2)) return true;
if(point_in_rect(r1.down, r1.left,r2)) return true;
if(point_in_rect(r1.top, r1.right,r2)) return true;
if(point_in_rect(r1.down, r1.right,r2)) return true;
if(point_in_rect(r2.top, r2.left,r1)) return true;
if(point_in_rect(r2.down, r2.left,r1)) return true;
if(point_in_rect(r2.top, r2.right,r1)) return true;
if(point_in_rect(r2.down, r2.right,r1)) return true;
return false;
}
Edited by ngoaho91

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 11
• 15
• 21
• 26
• 11
×

## Important Information

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!