So erzeugen Sie einen zufälligen Punkt innerhalb eines Kreises mit dem Radius R :
r = R * sqrt(random())
theta = random() * 2 * PI
(Angenommen, es random()
wird einheitlich ein Wert zwischen 0 und 1 angegeben.)
Wenn Sie dies in kartesische Koordinaten konvertieren möchten, können Sie dies tun
x = centerX + r * cos(theta)
y = centerY + r * sin(theta)
Warum sqrt(random())
?
Schauen wir uns die Mathematik an, die dazu führt sqrt(random())
. Nehmen wir der Einfachheit halber an, dass wir mit dem Einheitskreis arbeiten, dh R = 1.
Der durchschnittliche Abstand zwischen Punkten sollte gleich sein, unabhängig davon, wie weit wir vom Zentrum entfernt sind. Dies bedeutet zum Beispiel, dass wir beim Betrachten des Umfangs eines Kreises mit Umfang 2 doppelt so viele Punkte finden sollten wie die Anzahl der Punkte am Umfang eines Kreises mit Umfang 1.
Da der Umfang eines Kreises (2π r ) linear mit r wächst , sollte die Anzahl der Zufallspunkte linear mit r wachsen . Mit anderen Worten wächst die gewünschte Wahrscheinlichkeitsdichtefunktion (PDF) linear. Da ein PDF eine Fläche von 1 haben sollte und der maximale Radius 1 ist, haben wir
Wir wissen also, wie die gewünschte Dichte unserer Zufallswerte aussehen soll. Nun: Wie erzeugen wir einen solchen Zufallswert, wenn wir nur einen einheitlichen Zufallswert zwischen 0 und 1 haben?
Wir verwenden einen Trick namens inverse Transformationsabtastung
- Erstellen Sie aus dem PDF die kumulative Verteilungsfunktion (CDF).
- Spiegeln Sie dies entlang y = x
- Wenden Sie die resultierende Funktion auf einen einheitlichen Wert zwischen 0 und 1 an.
Klingt kompliziert? Lassen Sie mich ein Blockzitat mit einer kleinen Nebenspur einfügen, die die Intuition vermittelt:
Angenommen, wir möchten einen zufälligen Punkt mit der folgenden Verteilung generieren:
Das ist
- 1/5 der Punkte gleichmäßig zwischen 1 und 2 und
- 4/5 der Punkte gleichmäßig zwischen 2 und 3.
Die CDF ist, wie der Name schon sagt, die kumulative Version der PDF. Intuitiv: Während PDF ( x ) die Anzahl der Zufallswerte bei x beschreibt , beschreibt CDF ( x ) die Anzahl der Zufallswerte unter x .
In diesem Fall würde die CDF folgendermaßen aussehen:
Um zu sehen, wie nützlich dies ist, stellen Sie sich vor, wir schießen Kugeln von links nach rechts in gleichmäßig verteilten Höhen. Wenn die Kugeln die Linie treffen, fallen sie zu Boden:
Sehen Sie, wie die Dichte der Kugeln auf dem Boden unserer gewünschten Verteilung entspricht! Wir sind fast da!
Das Problem ist, dass für diese Funktion die y- Achse die Ausgabe und die x- Achse die Eingabe ist . Wir können nur "Kugeln vom Boden direkt nach oben schießen"! Wir brauchen die Umkehrfunktion!
Deshalb spiegeln wir das Ganze wider; x wird zu y und y wird zu x :
Wir nennen das CDF -1 . Um Werte entsprechend der gewünschten Verteilung zu erhalten, verwenden wir CDF -1 (random ()).
… Also zurück zur Erzeugung zufälliger Radiuswerte, bei denen unser PDF 2 x entspricht .
Schritt 1: Erstellen der CDF:
Da wir mit Real arbeiten, wird die CDF als Integral der PDF ausgedrückt.
CDF ( x ) = ∫ 2 x = x 2
Schritt 2: Spiegeln Sie die CDF entlang y = x :
Mathematisch kocht diese zu tauschen unten x und y und die Lösung für y :
CDF : y = x 2
Swap: x = y 2
Lösung: y = √ x
CDF -1 : y = √ x
Schritt 3: Wenden Sie die resultierende Funktion auf einen einheitlichen Wert zwischen 0 und 1 an
CDF -1 (random ()) = √random ()
Welches ist, was wir ableiten wollten :-)