0

Possible Duplicate:
Determine if two rectangles overlap each other?

Considering I have 2 squares for which I know the x and y positions and I also know the size, what would be the formula to use if I wanted to see if the objects collide with eachother.

if(   ((shapeA->getX() - shapeA->getSize()) > (player->getX() - player->getSize())
    && (shapeA->getX() + shapeA->getSize()) < (player->getX() + player->getSize()))
    && (shapeA->getY() - shapeA->getSize()  > player->getY() - player->getSize()
    && (shapeA->getY() + shapeA->getSize()) < (player->getY() + player->getSize()))
                )

This works, but it works strange (not all the time). I must be missing something

Community
  • 1
  • 1
CosminO
  • 5,018
  • 6
  • 28
  • 50
  • You should use the debugger (or just add helpful print statements) to identify the values of all variables involved, and figure out why it doesn't work for the failing cases. – Oliver Charlesworth May 31 '12 at 10:07
  • find the equation of all edges of the squares, and check if two edges are intersecting or not.. – ardiyu07 May 31 '12 at 10:12

4 Answers4

4

It's very easy to check whether a rectangle intersects or touches another rectangle. Have a look at the following picture:

Rectangular intersection

As you can see, two rectangles intersect if the intersections between ([x,x+a] and [X,X+A]) and ([y,y+b] and [Y,Y+B]) both aren't empty.

struct Rectangle{
    bool intersects(const Rectangle&);

    unsigned int a; //!< width of the rectangle
    unsigned int b; //!< height of the rectangle
    unsigned int x; //!< x position
    unsigned int y; //!< y position
};

bool Rectangle::intersects(const Rectangle& oRectangle){        
    return  (x < oRectangle.x + oRectangle.a) && // [x,x+a], [X,X+A] intersection
            (oRectangle.x < x + a)            && // [x,x+a], [X,X+A] intersection
            (y < oRectangle.y + oRectangle.b) && // [y,y+b], [Y,Y+B] intersection
            (oRectangle.y < y + b);              // [y,y+b], [Y,Y+B] intersection
}

So your code should be

if(((shapeA->getX() + shapeA->getSize()) > (player->getX()) // x intersection
    && (shapeA->getX() < (player->getX() + player->getSize())) // x intersection
    && (shapeA->getY() < player->getY() + player->getSize()  // y intersection
    && (shapeA->getY() + shapeA->getSize()) > player->getY())  // y intersection
)
Zeta
  • 103,620
  • 13
  • 194
  • 236
2

Assuming that getX/Y gives the bottom left corner of the square,

shapeMinX = shapeA; shapeMaxX = shapeB;
if (shapeA()->getX() > shapeB()->getX())
  swap (shapeMinX, shapeMaxX);
shapeMinY = shapeA; shapeMaxY = shapeB;
if (shapeA()->getY() > shapeB()->getY())
  swap (shapeMinY, shapeMaxY);

collision = (shapeMinX->getX()+shapeMinX->size() >= shapeMaxX()->getX) || (shapeMinX->getY()+shapeMinY->size() >= shapeMaxY()->getY);
rwst
  • 2,515
  • 2
  • 30
  • 36
  • 2
    This answer lacks explanation (+I doubt you can do this with one `or`, but I could be mistaken, I won't know until you explain). – KillianDS May 31 '12 at 10:17
  • You probably mean `swap(shapeMinX, shapeMaxX)` and not `switch(shapeMinX, shapeMaxX)`. – RedX May 31 '12 at 10:20
2

You do wrong tests, try this:

int left_bound_A=  shapeA->getX()-shapeA->getSize();
int right_bound_A= shapeA->getX()+shapeA->getSize();
int top_bound_A= shapeA->getY()-shapeA->getSize();
int bottom_bound_A= shapeA->getY()+shapeA->getSize();

int left_bound_B=  shapeB->getX()-shapeB->getSize();
int right_bound_B= shapeB->getX()+shapeB->getSize();
int top_bound_B= shapeB->getY()-shapeB->getSize();
int bottom_bound_B= shapeB->getY()+shapeB->getSize();

if( left_bound_A < right_bound_B &&
    right_bound_A > left_bound_B &&
    top_bound_A > bottom_bound_B &&
    bottom_bound_A < top_bound_B ) colide(shapeA,shapeB);

The general way is to test for shape intersection. If you implement a Box or Rectangle class, the code simplify to:

 Box colision= intersect( shapeA->getBoundBox(), shapeB->getBoundBox() );
 if( colision.have_positive_area() )
     colide(shapeA,shapeB,colision);
Arpegius
  • 5,817
  • 38
  • 53
0

Yes, the way to check if two rectangles is simple. Just as a suggestion, if you then want to compute all the possible intersection between the rectangles in a list of rectangles, preorder them by increasing x of their border and then start the comparison exploiting this relation. This question may be of help

Fast hiding of intersecting rectangles can be of interest

Community
  • 1
  • 1
linello
  • 8,451
  • 18
  • 63
  • 109