сравнить новое значение CGPoint со значением CGPoint в массиве

Я создаю несколько кругов со случайными позициями. то, что я хочу предотвратить, это то, что круги не перекрывают друг друга. поэтому я хочу сравнить только что сгенерированное значение CGPoint с теми, которые находятся в массиве, и заставить его генерировать новое значение, если значение находится в области радиуса одной из CGPoints.

Я получил большую часть этого, за исключением перекрывающейся вещи. Я прокомментировал часть того, что пробовал, но это на самом деле не работает (ошибочная логика). Я не уверен, как перебирать отдельные значения CGPoint и сравнивать их.

ОБНОВЛЕНИЕ: я немного изменил код и добавил проверку, будет ли перекрываться точка CGPoint. Проблема в том, что всякий раз, когда я хочу попробовать что-то вроде

while (!xPointOk || !yPointOk) {

// generate new values

}

Я продолжаю падать в бесконечный цикл.

- (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];

    }

}

person Ramin Afshar    schedule 08.04.2012    source источник


Ответы (1)


Ваш тест должен завершиться неудачно, если новая точка находится на расстоянии меньше окружности от любой из существующих точек, поэтому вы можете использовать базовый триггер для ее обработки.

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);

Другие вещи, которые вам необходимо учитывать, — это количество повторных попыток, чтобы остановить бесконечное количество повторных попыток.

person Warren Burton    schedule 08.04.2012
comment
привет, я попытался включить твой код в свой. но у меня, похоже, не получилось. Хотя я понимаю, что ваш способ определенно более эффективен. смогу ли я заставить его работать без использования триггера? - person Ramin Afshar; 08.04.2012
comment
Это псевдокод. Не просто копировать/вставлять. Адаптируйте то, что вы там видите, к своей программе. И нет, вам нужно будет использовать базовую тригонометрию, чтобы решить эту проблему. - person Warren Burton; 08.04.2012
comment
да у меня сейчас работает. Благодарность! хотя мне нужно выучить некоторые базовые триггеры :) - person Ramin Afshar; 09.04.2012