Simulator
Simulator

Reputation: 166

CGRectIntersectsRect for multiple CGRect

I have 8 UIImageView, which have to be placed randomly. I generate a random x,y pos for each imageView, then I need to check if any of the imageViews are intersecting. If they are intersecting, it goes back to calculating random x,y pos again(do..while loop). Now the only method I know of is CGRectIntersectsRect, which can only compare 2 CGRect. Is there a way I can check if all those imageViews intersect at once (inside the while condition)?

Here's what I already worked out for 3 images-

 do {

        xpos1 = 60 + arc4random() % (960 - 60 + 1);
        ypos1 = 147 + arc4random() % (577 - 147 + 1);



        xpos2 = 60 + arc4random() % (960 - 60 + 1);
        ypos2 = 147 + arc4random() % (577 - 147 + 1);



        xpos3 = 60 + arc4random() % (960 - 60 + 1);
        ypos3 = 147 + arc4random() % (577 - 147 + 1);

        } while (CGRectIntersectsRect(CGRectMake(xpos1, ypos1,120, 120), CGRectMake(xpos2, ypos2,120, 120)) || CGRectIntersectsRect(CGRectMake(xpos2, ypos2,120,120), CGRectMake(xpos3, ypos3, 120, 120)) || CGRectIntersectsRect(CGRectMake(xpos1, ypos1,120,120), CGRectMake(xpos3, ypos3, 120, 120)) );

    image1.center=CGPointMake(xpos1, ypos1);
    image2.center=CGPointMake(xpos2, ypos2);
    image3.center=CGPointMake(xpos3, ypos3);

Upvotes: 0

Views: 272

Answers (2)

Martin R
Martin R

Reputation: 539715

A simple algorithm would be to start with one rectangle, and then iteratively find new rectangles that do not intersect with any of the previous ones:

int numRects = 8;
CGFloat xmin = 60, xmax = 960, ymin = 147, ymax = 577;
CGFloat width = 120, height = 120;
CGRect rects[numRects];

for (int i = 0; i < numRects; i++) {
    bool intersects;
    do {
        // Create random rect:
        CGFloat x = xmin + arc4random_uniform(xmax - xmin + 1);
        CGFloat y = ymin + arc4random_uniform(ymax - ymin + 1);
        rects[i] = CGRectMake(x, y, width, height);

        // Check if it intersects with one of the previous rects:
        intersects = false;
        for (int j = 0; j < i; j++) {
            if (CGRectIntersectsRect(rects[i], rects[j])) {
                intersects = true;
                break;
            }
        }

    // repeat until new rect does not intersect with previous rects:
    } while (intersects);
}

This should answer your question ("how to check for intersection with multiple rectangles"), but note that this method is not perfect. If the rectangles would fill "much" of the available space and the first rectangles are placed "badly" then the algorithm might not terminate because it cannot find an admissible rectangle at some point.

I don't think that can happen with the dimensions used in your case, but you might keep that in mind. A possible solution could be to count the number of tries that were made, and if it takes too long than start over from the beginning.

Also, if you have to create many rectangles then the inner loop (that checks for the intersection) can be improved by sorting the rectangles, so that less comparisons have to be made.

Upvotes: 2

Sunny Shah
Sunny Shah

Reputation: 13020

Say you have generated point

 CGFloat x = (CGFloat) (arc4random() % (int) self.view.bounds.size.width);
CGFloat y = (CGFloat) (arc4random() % (int) self.view.bounds.size.height);
CGPoint point=CGPointMake(x, y);
while ([self checkPointExist:point]) {
     x = (CGFloat) (arc4random() % (int) self.view.bounds.size.width);
    y = (CGFloat) (arc4random() % (int) self.view.bounds.size.height);
    point=CGPointMake(x, y);

}

-(BOOL)checkPointExist:(CGPoint)point{
for(UIView *aView in [self.view subviews])
{
    if(CGRectContainsPoint(aView.frame, point))
    {
        return TRUE;//    There is already imageview. generate another point
    }
}
return FALSE;

}

Upvotes: 0

Related Questions