可以在它们之间设置间隙生成随机数吗?

时间:2012-07-20 21:48:05

标签: xcode random nsmutablearray draw

我有以下代码

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语句,但想知道是否有更简单的方法来实现同样的事情?

由于

3 个答案:

答案 0 :(得分: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;

}

答案 1 :(得分:1)

您可能需要跟踪到目前为止生成的数字,并使用它们来帮助生成每个下一个随机数。例如,如果您想要间隙为5,则在MIN和MAX之间生成第一个数字,向其中添加5,然后生成该数字与MAX之间的下一个数字。如果你通过MAX,还有一些额外的代码可以包裹到范围的开头,你很高兴。

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

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

答案 2 :(得分:1)

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

您也可以考虑使用C ++ <random>库,因为它为您提供的分发可能比您生成自己的分发做得更好(假设示例代码为(arc4random() % (190-10+1)) + 10)。