1

私は以下のコードを持っています

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

これにより、ビューに5つのポイントをプロットするために使用する10個の乱数のセットが生成されます。これらのポイントの周りには円が描かれています。

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

数字が互いに特定のギャップ内にないことを確認する簡単な方法はありますか?たとえば、2つの円が互いに交差することは望ましくありません。私はかなりの数の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を通過した場合に範囲の先頭にラップアラウンドするための少し余分なコードがあれば、準備は完了です。

もう1つの方法は、可能な数の範囲をN個のサブセットに分割し、各サブ範囲で1つの数を生成することです。したがって、1から100の範囲では、1から10に1つの数値、15から25に次の数値、30から40に次の数値などを生成できます。これにより、ほぼ均等な分布が保証されますが、ある程度のランダム性は保持されます。

使用する正確なアプローチは、実際にどのような種類の配布を実現するかによって異なります。

于 2012-07-20T21:58:11.300 に答える
1

乱数を生成し、それらのギャップにあるものを破棄するのが最善の選択肢だと思います。これは、番号の並べ替えられたシーケンスを保持し、新しい番号を挿入する前に、次に大きい番号と最小の番号が十分に離れているかどうかを確認する場合、おそらくかなり効率的に実行できます。

また、C ++<random>ライブラリの使用を検討することもできます。これは、独自のディストリビューションを作成するよりもおそらく優れた仕事をするディストリビューションを提供するためです(サンプルコードが(arc4random() % (190-10+1)) + 10)。

于 2012-07-20T22:01:09.417 に答える