Question

I'm generating a number of circles with random positions. what I want to prevent is the circles from overlapping each other. so I want to compare the newly generated CGPoint value to the ones that are in the array and have it generate a new value if the value finds itself in the radius area of one of the CGPoints.

I got most of it except for the overlapping thing. I've commented the part out of something I tried, but that doesn't really work(flawed logic). I'm not sure how to iterate through the individual values of the CGPoint and comparing them.

UPDATE: I've change the code a bit more and added a check to see whether the CGPoint will overlap or not. Problem is whenever I want to try something like

while (!xPointOk || !yPointOk) {

// generate new values

}

I keep falling in an infinite loop.

- (void) positionCircles 
{

    //generate random Y value within a range
    int fromNumberY = 500;
    int toNumberY = 950;
    int randomNumberY =(arc4random()%(toNumberY-fromNumberY+1))+fromNumberY;

    //generate random Y value within a range
    int fromNumberX = 0;
    int toNumberX = 700;
    int randomNumberX = (arc4random()%(toNumberX-fromNumberX+1))+fromNumberX;

    //array to hold all the the CGPoints
    positionsArray = [[NSMutableArray alloc] init];
    CGPoint circlePositionValue;

    CGFloat radius = 70;

    CGRect position = CGRectMake(randomNumberX,randomNumberY, radius, radius);

    [self makeColors];



    // create a circle for each color in color array
    for (int i = 0; i < [colors count];i++)
    {
        // generate new position before placing new cirlce
        randomNumberX = (arc4random()%(toNumberX-fromNumberX+1))+fromNumberX;
        randomNumberY = (arc4random()%(toNumberY-fromNumberY+1))+fromNumberY;

        circlePositionValue = CGPointMake(position.origin.x, position.origin.y);

        for (NSValue *value in positionsArray) {


            BOOL xPointOk = (randomNumberX < value.CGPointValue.x - radius) || 
                             (randomNumberX > value.CGPointValue.x + radius);

            BOOL yPointOk = (randomNumberY < value.CGPointValue.y - radius) || 
                             (randomNumberY > value.CGPointValue.y + radius);


            NSLog(@"xPoint: %i - %f", randomNumberX , value.CGPointValue.x);
            NSLog(@"xPoint ok? %@", xPointOk?@"yes":@"no");

            NSLog(@"yPoint: %i - %f", randomNumberY , value.CGPointValue.y);
            NSLog(@"yPoint ok? %@", yPointOk?@"yes":@"no");
            NSLog(@"___");

        }

        position.origin.x = randomNumberX;
        position.origin.y = randomNumberY;
        [positionsArray addObject:[NSValue valueWithCGPoint:circlePositionValue]];

        Circle *myCircle = [[Circle alloc] initWithFrame:position radius:radius color:[colors objectAtIndex:i]];
        myCircle.label.text = [NSString stringWithFormat:@"%i", i];
        [self.view addSubview:myCircle];

    }

}
Was it helpful?

Solution

Your test should fail when the new point is less than the circumference away from any of the existing points so you can use basic trig to work it out.

BOOL far_enough_away = NO;
CGPoint newpoint = CGZeroPoint;
while(!far_enough_away)
{
    newpoint = randomisation_thingy();
    far_enough_away = YES;
    for(NSValue *existing in positionsArray)
    {
        CGPoint pointb = [existing pointValue];
        CGFloat deltay = pointb.y-newpoint.y;
        CGFloat deltax = pointb.x-newpoint.x;
        CGFloat distance = sqrt(pow(deltax,2) + pow(deltay,2));
        //fail if closer than desired radius
        if(distance < circumference )
        {
           //sadness - try again
           far_enough_away = NO;
           break;
        }
    }
}
create_a_new_circle_at_point(newpoint);

Other things you need to consider are how many times to retry to stop an infinite number of retries.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top