1

我有下面的代码

NSMutableSet * numberSet = [NSMutableSet setWithCapacity:10];
while ([numberSet count] < 10 ) {
    NSNumber * randomNumber = [NSNumber numberWithInt:( (arc4random() % (190-10+1)) + 10 )];
    [numberSet addObject:randomNumber];
}

这会生成一组 10 个随机数,用于在视图中绘制 5 个点。然后在这些点周围绘制圆圈。

[[UIBezierPath bezierPathWithArcCenter:CGPointMake(a, b) radius:6 startAngle:1 endAngle:10 clockwise:YES] fill];

有没有一种简单的方法可以确保这些数字彼此之间没有一定的差距。例如,我不希望两个圆圈相互交叉。我正在考虑使用相当多的 if 语句,但想知道是否有更简单的方法来实现相同的目标?

谢谢

4

3 回答 3

2

此代码生成 10 个半径为 10 且彼此不相交的圆。我同意 bames53 的观点,即最好的方法是检查生成的圆是否与先前生成的圆相交。

// Seed random generator
srand(time(NULL));  

const float radius = 10;
const int numberOfCircles = 10;

// Defines the area where the center of the circles are allowed 
const float min_x = 0 + radius; 
const float max_x = 320 - radius;
const float min_y = 0 + radius;
const float max_y = 367 - radius;

NSMutableSet * nonInterSectingCircles = [NSMutableSet setWithCapacity:numberOfCircles];

while ([nonInterSectingCircles count] < numberOfCircles ) {

    float x_new = randomNumber(min_x, max_x);
    float y_new = randomNumber(min_y, max_y);

    BOOL intersectsExistingCircle = NO;

    for (NSValue *center in nonInterSectingCircles) {
        CGPoint centerPoint = [center CGPointValue];
        if (distance(x_new, centerPoint.x, y_new, centerPoint.y) < radius * 2) 
            intersectsExistingCircle = YES; 
    }

    if (!intersectsExistingCircle) [nonInterSectingCircles addObject:[NSValue valueWithCGPoint:CGPointMake(x_new, y_new)]];

}

使用以下函数:

float distance(float x1,float x2, float y1, float y2) {

    float dx = (x2 - x1);
    float dy = (y2 - y1);

    return  sqrt(dx * dx + dy * dy);
}

float randomNumber(float min, float max) {

    float random = ((float) rand()) / (float) RAND_MAX;
    random = random * (max - min);
    return min + random;

}
于 2012-07-21T06:52:45.253 回答
1

您可能必须跟踪到目前为止生成的数字,并使用它们来帮助生成每个下一个随机数。例如,如果您想要 5 的间隙,则生成 MIN 和 MAX 之间的第一个数字,将 5 添加到它,然后生成该数字和 MAX 之间的下一个数字。如果您通过 MAX,则需要一些额外的代码来环绕到范围的开头,您就可以开始了。

另一种选择是将可能的数字范围分解为 N 个子集,并在每个子范围内生成一个数字。因此,对于从 1 到 100 的范围,您可以在 1 到 10 中生成一个数字,在 15 到 25 中生成下一个数字,在 30 到 40 中生成下一个数字,等等,确保大致均匀分布但保留一些随机性。

您要使用的确切方法将取决于您实际想要实现的分布类型。

于 2012-07-20T21:58:11.300 回答
1

我认为您最好的选择是生成随机数并丢弃那些落在这些间隙中的随机数。如果您保持数字的排序序列,并且在插入新数字之前检查下一个最高和最低数字是否足够远,这可能会相当有效地完成。

此外,您可能会考虑使用 C++<random>库,因为它为您提供的发行版可能比您制作自己的发行版做得更好(假设示例代码是(arc4random() % (190-10+1)) + 10)。

于 2012-07-20T22:01:09.417 回答