1

I'm working on a breakout clone and I've been trying to figure out how to get the intersection rect of two colliding rects so I can measure how deep the ball entered the block in both x and y axis and decide which component of the velocity I'll reverse.

I figured I could calculate the depth for each case like this:

ball collision with blocks

But if I had the intersection rect than I woudn't have to worry if the ball hits the block from the left/right or top/bottom (since I would be only reversing the x and y axis respectively), thus saving me a lot of typing.

I've looked on Pygame's docs but seems it doesn't have a function for that. How would I go about solving this problem?

bzrr
  • 1,490
  • 3
  • 20
  • 39
  • There are **lots** of duplicates of this question (e.g. [Rectangle intersection](http://stackoverflow.com/questions/7675201/rectangle-intersection)). Please use the search facility before posting a new question... – Oliver Charlesworth Dec 10 '13 at 02:35
  • I don't know anything about Pygame, but I imagine it provides some way to get the coordinates/size of the rectangles? In which case it should be relatively simple to translate any of the solutions presented in any of the [existing questions](http://stackoverflow.com/search?q=rectangle+intersection)) to use Pygame... – Oliver Charlesworth Dec 10 '13 at 02:40

1 Answers1

6

Assuming you have rectangles r1 and r2, with .left, .right, .top, and .bottom edges, then

left = max(r1.left, r2.left);
right = min(r1.right, r2.right);
top = max(r1.top, r2.top);
bottom = min(r1.bottom, r2.bottom);

(with the usual convention that coordinates increase top to bottom and left to right). Finally, check that left<right and top<bottom, and compute the area:

Area = (right - left) * (top - bottom);

Alternatively, you can use the clip() function. From the docs you linked in your question:

clip(Rect) -> Rect Returns a new rectangle that is cropped to be completely inside the argument Rect. If the two rectangles do not overlap to begin with, a Rect with 0 size is returned.

Floris
  • 45,857
  • 6
  • 70
  • 122
  • You are welcome. A bit ironic that I found the `clip()` answer in the docs you linked… sometimes you need another set of eyes. Bit of a strange name - but when I saw they had `union()` I figured it _had_ to be there, so I read more closely. – Floris Dec 10 '13 at 03:19
  • Yes! You know, I never ask questions before doing a google search and looking in the docs first. It bothers me when I can't solve problems like these on my own. I probably thought ``clip`` was like ``set_clip`` which has a completely different behavior. Maybe I should delete the question, you think? – bzrr Dec 10 '13 at 03:29
  • 2
    It's up to you. If anyone else searches "rectangle intersection pygame" they find lots of hits to the boolean test - very few for the "area of overlap". Maybe this question will eventually make the list… You had trouble finding the answer - so might others. – Floris Dec 10 '13 at 03:34
  • 1
    Hmm. I don't this code is right. `top = max(r1.top, r2.top);` should be `min` and then we need to check if either `(right - left)` or `(top - bottom)` is negative (no intersection.) Also, is ending lines with a semicolon a pygame thing? – BenB Feb 03 '16 at 20:38
  • @BenB - actually with coordinates increasing top to bottom, it should have been `bottom = min(r1.top, r2.top);`. I added the check - good point. As for the semicolons: that's a hangover from writing mostly Matlab and C... – Floris Feb 03 '16 at 20:57
  • So probably we should get rid of the semicolons ;) I would have gone to the standard graphing conventions of y increasing bottom to top. Is there a convention I'm not aware of? – BenB Feb 03 '16 at 22:19
  • Yes, [the convention is top-left = (0,0)](http://gamedev.stackexchange.com/questions/83570/why-is-the-origin-in-computer-graphics-coordinates-at-the-top-left) – Floris Feb 03 '16 at 22:26