2012-10-25 10 views
6

Możliwe Duplikat:
Create random number within an annulusGenerowanie równomiernie przypadkowego punktu w obrębie pierścienia (pierścień)

chciałbym uzyskać równomiernie otrzymany punkt losowy w obrębie annulus, to znaczy obszar leżący wewnątrz okręgu o promieniu R1, ale poza okręgiem o promieniu R2, gdzie R1 > R2 i oba koła są wyśrodkowane w tym samym punkcie. Chciałbym uniknąć stosowania próbkowania odrzucenia.

Jeśli to możliwe, chciałbym, aby rozwiązanie było podobne do this one -używane do obliczania losowych punktów w okręgu - co uważam za niezwykle eleganckie i intuicyjne. Oznacza to, że chciałbym również uniknąć użycia pierwiastka kwadratowego .

+0

Dzięki za edycji, nie wiedziałem, że teren był nazywany pierścienia. ;-) –

+0

Dodano wyjaśnienie, stwierdzając, że chciałbym uniknąć pierwiastka kwadratowego (stąd nie jest to dokładnie duplikat drugiego). –

+0

Chcę, żeby to był przypadek zmiany '[0, R]' w twoim połączonym pytaniu na '[R1, R2]', ale założę się, że to nie jest takie proste. Albo to jest? – AakashM

Odpowiedz

2

EDYTOWANIE:Należy pamiętać, że to rozwiązanie może nie być jednolite. Zobacz komentarze Marka Dickinsona poniżej.

OK, myślę, że to wymyśliłem. Zauważ, że to rozwiązanie jest mocno inspirowane w this answer, i że r1 = R1/R1 i r2 = R2/R1.

Pseudo-kod:

t = 2*pi*random() 
u = random()+random() 
r = if u>1 then 2-u else u 
r = if r<r2 then r2+r*((R1-R2)/R2) else r 
[r*cos(t), r*sin(t)] 

Oto ona w Mathematica.

f[] := Block[{u, t, r}, u = Random[] + Random[]; 
r1 = 1; r2 = 0.3; 
t = Random[] 2 Pi; 
r = If[u > 1, 2 - u, u]; 
r = If[r < r2, r2 + r*((R1 - R2)/R2), r]; 
{r Cos[t], r Sin[t]}] 

ListPlot[Table[f[], {10000}], AspectRatio -> Automatic] 

Distribution of the simple algorithm

Co robi jest przemapować wszystkie numery spadające wewnątrz kręgu do pierścienia, rozkładając je równomiernie. Jeśli ktoś znajdzie problem dotyczący jednolitości tego rozwiązania, prosimy o komentarz.

Porównaj z oceniły tę inne rozwiązanie here:

Distribution of the sqrt algorithm

+4

To jest zgrabna odpowiedź, ale niestety wynik nie jest jednolity. Jeśli spróbujesz z np. 'R2 = 0.95' i' R1 = 1.0', zobaczysz, że punkty bliżej zewnętrznej krawędzi pierścienia są uprzywilejowane. Prawidłowy sposób wygenerowania odpowiedniego "r" polega na wybraniu zmiennych losowych 'u' i' v' z 'u' wybranymi równomiernie w' [R2, R1] 'i' v' wybranymi równomiernie w '[0, R2 + R1 ] ', a następnie weź' r = u' jeśli 'v = u'. –

+0

Mark, dziękuję za komentarz i za alternatywę. Jesteś pewien, że moje rozwiązanie jest niejednolite? Nie mogę tego zauważyć nawet przy R2 = 0,95, jak sugerowałeś: http://i.imgur.com/wmDEo.png –

+0

Całkiem jasne, tak. :-) Oto test, który możesz wykonać: weź 'R2 = 0.5' i' R1 = 1.0' i wygeneruj 10.000 próbek (powiedzmy). Teraz podziel swój pierścień na dwie, dodając okrąg o promieniu 0,75 i policz, ile wygenerowanych próbek znajduje się w pierścieniu zewnętrznym (0,75 <= promień <= 1,0), a ile w pierścieniu wewnętrznym (0,5 <= promień <= 0,75). Jeśli roztwór jest jednorodny, powinieneś uzyskać stosunek zbliżony do 7/5 = 1,4 (powierzchnia pierścienia zewnętrznego = 7/16 pi, powierzchnia pierścienia wewnętrznego = 5/16 pi). Nie testowałem, ale przewiduję, że twoje rozwiązanie da stosunek bliżej 5/3 = 1,66666 ... –

-1

Najprostszym sposobem na to jest użycie rejection sampling. Wygeneruj dużą liczbę punktów równomiernie w kwadracie o długości boku 2 * R2, a następnie odfiltruj te próbki do tych wewnątrz zewnętrznego koła, a nie do wewnętrznego koła.

Nie jest ładna ani wydajna, ale w większości przypadków wystarczająca.

+2

Powiedział, że nie chce używać próbkowania odrzucenia. W przypadku próbkowania odrzucenia można przynajmniej zacząć od punktów jednorodnych w większym kręgu z metodą, z którą się łączył. –

1

To bardzo łatwe. Użyj współrzędnych biegunowych, tj. Wygenerujesz jedną losową wartość dla wartości kątowej theta, a drugą dla odległości od początku. Ponieważ twoje kręgi są zarówno w tym samym pochodzenie, to staje się bardzo łatwe.

ALE UWAGA: można wygenerować wartość theta za pomocą jednolitej funkcji losowej, to jest w porządku, ale na odległość nie można tego zrobić, ponieważ wtedy punkty będą skupiać się wokół punktu początkowego. Musisz wziąć pod uwagę, że obwód koła rośnie w^2 (musisz użyć odwrotności, która jest pierwiastkiem kwadratowym).

Korzystanie munduru rozmieszczone losowo funkcja rnd (0..1) byłoby tak:

theta = 360 * rnd(); 
dist = sqrt(rnd()*(R1^2-R2^2)+R2^2); 

EDIT: o przekształcenie współrzędnych cartesion, wystarczy obliczyć:

x = dist * cos(theta); 
y = dist * sin(theta); 
+0

Wątpię, czy typowe funkcje "cos" i "sin" przyjmują stopnie, częściej radianów. Ale to jest metoda pracy. –

+0

Jeśli to możliwe, chciałbym uniknąć sqrt() jak w odpowiedzi, którą połączyłem. Nie chcę też używać próbkowania odrzucenia. –

+0

Zależy od funkcji. Jeśli nie używasz stopni, ale radianów, po prostu zamień 360 na 2 * PI – flolo

Powiązane problemy