2012-01-12 2 views
1

Im пытается сделать звезды на небе, но распределение звезд не равно.Как рандомизировать точки на поверхности сферы равномерно?

Это то, что я пробовал:

rx = rand(0.0f, PI*2.0f); 
ry = rand(0.0f, PI); 
x = sin(ry)*sin(rx)*range; 
y = sin(ry)*cos(rx)*range; 
z = cos(ry)*range; 

какие результаты:

img http://img716.imageshack.us/img716/3320/sphererandom.jpg

И:

Что приводит к:

img2 http://img710.imageshack.us/img710/5152/squarerandom.jpg

(не делает шар, но opengl не скажет разницы, хотя).

Как вы можете видеть, всегда есть «угол», где в среднем больше очков. Как я могу создавать случайные точки в сфере, где точки будут распределяться равномерно?

+3

http://stackoverflow.com/questions/1841014/uniform-random-monte-carlo-distribution-on-unit-sphere – AakashM

+0

http://stackoverflow.com/questions/5531827/random-point -on-a-given-sphere – AakashM

+0

http://stackoverflow.com/questions/7280184/fast-un iformly-distribution-random-points-on-the-the-the-a-unit-hemisphere – AakashM

ответ

4

вы можете сделать

z = rand(-1, 1) 
rxy = sqrt(1 - z*z) 
phi = rand(0, 2*PI) 
x = rxy * cos(phi) 
y = rxy * sin(phi) 

Здесь рандов (и, v) рисует равномерной случайной из INTERAL [и, v]

+0

Нет. Это можно вычислить математически. –

+0

@ Alexandre C., это не так ?! я протестировал код, и я клянусь: я не мог сказать, что была какая-то концентрация в любом месте! отлично даже для моих глаз ... – Rookie

+1

@Drew, no. Предположим, что z = sin (t), и мы выбираем z равномерно распределенным, поэтому вероятность того, что точка находится в [t, t + dt], равна dP = 0,5dz = 0,5cos (t) dt. Площадь поверхности полосы [t, d + dt] равна dS = 2PIcos (t) dt, поэтому плотность равна dP/dS = (4PI)^- 1, что не зависит от t. –

0

Похоже, что вы можете увидеть, что это декартовы координаты, которые создают концентрации.

Here - это объяснение одного правильного (и неправильного) способа получения правильного распределения.

0

Вам не нужно тригонометрию, если вы можете генерировать случайные гауссовских переменные, вы не можете делать (псевдокод)

x <- gauss() 
y <- gauss() 
z <- gauss() 
norm <- sqrt(x^2 + y^2 + z^2) 

result = (x/norm, y/norm, z/norm) 

Или рисовать точки внутри единичного куба, пока один из них находится внутри единичного шара, а затем нормализуют :

double x, y, z; 

do 
{ 
    x = rand(-1, 1); 
    y = rand(-1, 1); 
    z = rand(-1, 1); 
} while (x * x + y * y + z * z > 1); 

double norm = sqrt(x * x + y * y + z * z); 
x/norm; y /= norm; z /= norm; 
+0

Я думал об этом, но я тоже думал, что это довольно медленно: половина вычислений теряется, потому что они выходят за пределы сферы. im, используя метод icando, и это действительно работает отлично и очень быстро. – Rookie

+0

Я сравнивал только для вас: 88.3ms с методом icando, 128.5ms с вашим! Я рассчитал 500 тыс. очков. Неужели у процессоров грех/cos почему-то оптимизирован в эти дни ...? ой, и я использовал mersenne rand. – Rookie

+0

Я думал, что Мерсенн был лучшим ...PHP использует его, например, и они называют это лучшим и т. Д. – Rookie

Смежные вопросы