4

I'm programming a game, and i need to detect intersections between two CGRects. To do this, i've no problem. I do like this :

CGRect rect1 = CGRectMake (x1, y1, a1, b1);
CGRect rect2 = CGRectMake (x2, y2, a2, b2);
if (CGRectIntersectsRect(rect1, rect2))
{
    //do some stuff...
}

So i've no problem. But i would if it was possible to know the precise point of intersection from this two CGRect ? And if it's possible, how to ?

Thanks !

user2057209
  • 345
  • 1
  • 6
  • 19
  • What exactly do you mean by point of intersection? As @H2CO3 points out in the comments, you'll have _two_ intersection points. I'll leave it to the more formally mathematically minded to decide if two rectangles having only one point in common can be said to intersect each other. – Monolo Jun 22 '13 at 20:12
  • I think about getting an approximative point of intersection from two CGRects. – user2057209 Jun 22 '13 at 20:20
  • 1
    As you probably are aware, digital computers don't tend to do anything "approximative", so you would need to be much more specific. To me it sounds like you need a whole new question instead of piling a new spec on top of this question. – Monolo Jun 22 '13 at 20:24
  • I know that there is no approximation in computers, but precision in computer langage could be approximative for user experience. With speed, you couldn't see if a point of intersection is two pixels high or not. That's what i would mean by approximative. – user2057209 Jun 22 '13 at 21:36

2 Answers2

12

Use the CGRectIntersection() function to get the common part of two intersecting rectangles. From the result of that function call, you can calculate the edges of the rectangle using the CGRectGet[Max|Min][X|Y]() functions.

  • So for example, i could detect the intersection with CGRectIntersectsRect() function, and after, get a rectangle with CGRectIntersection() function. So for example i could take the origin of the return rectangle as a point, true ? – user2057209 Jun 22 '13 at 19:51
  • @user2057209 Yes, but pay attention to the relative position of the two original rectangles. Out of the 4 points of the intersection, only two will be actual intersection points. –  Jun 22 '13 at 19:53
  • "Return Value : A rectangle that represents the intersection of the two specified rectangles." So i will have only one rectangle to work with, no ? – user2057209 Jun 22 '13 at 20:03
  • 1
    @user2057209 And that rectangle has 4 corners, and only 2 of those corners are actual intersection points. (Draw it on paper and you'll get it.) –  Jun 22 '13 at 20:04
  • Ah ok i was thinking about using the origin of the new rectangle to get an approximative intersection point. – user2057209 Jun 22 '13 at 20:11
1

I think I'm trying to do the same thing your doing. I wanted to get the specific overlap between two rects. I found CGRectUnion to be super helpful as it gives the smallest rect containing the two rects. If the size is larger than your "max" then you know the rect is overlapping to the right or bottom. If the origin is negative then you know the rect is overlapping to the top or left. I wrote this function to give the resulting offset needed to correct the overlap.

CGPoint GetOffsetBetweenFrames(CGRect maxBounds, CGRect frame)
{
    CGRect frameUnion = CGRectUnion(maxBounds, frame);

    CGPoint offset = CGPointZero;
    if (CGRectGetMinX(frameUnion) < 0)
        offset.x = -frameUnion.origin.x;
    else if (CGRectGetWidth(frameUnion) > CGRectGetWidth(maxBounds))
        offset.x = -(CGRectGetWidth(frameUnion) - CGRectGetWidth(maxBounds));

    if (CGRectGetMinY(frameUnion) < 0)
        offset.y = -frameUnion.origin.y;
    else if (CGRectGetHeight(frameUnion) > CGRectGetHeight(maxBounds))
        offset.y = -(CGRectGetHeight(frameUnion) - CGRectGetHeight(maxBounds));

    return offset;
}

Oh, also quick edit: To apply the offset its as simple as:

offset = GetOffsetBetweenFrames(maxBounds, frame);
frame = CGRectOffset(frame, offset.x, offset.y);
Andy Poes
  • 1,682
  • 15
  • 19