Войти
ПрограммированиеФорумОбщее

Как получить случайное направление? (5 стр)

Страницы: 14 5 6 7 8 Следующая »
#60
15:58, 17 авг. 2012

wawan
Ответы не читай, сразу свое пиши

ALPINE
Продолжайте думать )


#61
15:58, 17 авг. 2012

Может все-таки FAQ'у поверим? Там в первой ссылке даже вывод есть.

#62
16:51, 17 авг. 2012

Aslan
> Проекция сферы на описанный цилиндр сохраняет площади, этим и пользуюсь Проверенно )
На цилиндр это хорошо, но как у тебя выпадет точка в окрестностях (0,0, 1)? Или ты делаешь нормирование не через (x,y,z)/sqrt(x^2+y^2+z^2), а через частичное нормирование (x,y,z)=(x*sqrt(1-z^1),y*sqrt(1-z^1),z)?
Ghost2
> Может все-таки FAQ'у поверим? Там в первой ссылке даже вывод есть.
FAQ надо переписать в понятном для непосвящённых виде примерно так.

1. Способ через проекцию на сферу равномерно распределённых в пространстве точек. Способ заключается в том, что из равномерно заполненного пространства точек выбираются охваченные сферой точки, которые потом нормализуются как векторы с началом в нулевой точке. Чтобы исключить деление на ноль из выбранных точек исключают близкие к нулевой точке, которые находятся ближе к ней некоторого произвольного расстояния, которое должно быть меньше радиуса первой сферы. Таким образом для получения нужного распределения достаточно равномерно заполнить равномерно точками описанный вокруг сферы единичного радиуса куб и затем исключить из множества охваченных сферой точек близкие к её центру точки с расстоянием до центра, например, 0.01. Непрерывный алгоритм получения точек по данному способу выглядит так.

:1 // Точка начала поиска

(x,y,z)=(2*rnd()-1,2*rnd()-1,2*rnd()-1) // Получаем случайную точку в описанном кубе

r2=x^2+y^2+z^2 // Получаем квадрат расстояния до центра сферы

if (0.01^2<r2<1) // Проверяем нахождение точки между сферами
 {
  return (x,y,z)/sqrt(r2) // Возвращаем нормированное значение вектора
 }
else
 {
  goto :1 // Повторяем заново
 }
2. Способ через сферические координаты. Этот способ заключается в распределении точек по сфере единичного радиуса после изменения закона распределения по координатам. Алгоритм получения случайных векторов выглядит так.
u = rnd()*2*PI // Получаем случайный угол в плоскости xy

z = 2*rnd() - 1 // Получаем случайную координату z

r = sqrt(1 - z^2) // Изменяем закон распределения по расстоянию до оси z

x = cos(u) * r // Получаем координату x

y = sin(u) * r // Получаем координату y

return (x,y,z) // Возвращаем случайный вектор

#63
22:14, 17 авг. 2012

Алексей Патрашов
Насколько сжатие по Y, настолько и растяжение вдоль окружности
Нормирую - делю на длину вектора (который заканчивается на поверхности цилиндра, x^2+y^2=1
Я так рисовал звезды, вроде равномерно легли

> проекцию на сферу равномерно распределённых в пространстве точек
Проблема только в том, что вы можете получить лишь точки, распределённые в кубе )

Есть общий способ, через интеграл плотности распределения, не могу вспомнить название

#64
23:14, 17 авг. 2012

Aslan
> Есть общий способ, через интеграл плотности распределения
Я так понял, что это:
Алексей Патрашов
> r = sqrt(1 - z^2)
как раз результат интегрирования.

#65
23:35, 17 авг. 2012

Mikle
Я же написал http://www.gamedev.ru/code/forum/?id=165422&page=4#m58
Делишь на sqrt(1+z^2)

Общий метод - когда надо получить значение на отрезке с заданным распределение

#66
1:11, 18 авг. 2012

Aslan
> Я так рисовал звезды, вроде равномерно легли
Задумался...
Mikle
> как раз результат интегрирования.
Оно самое и есть. На странице 47 и 48 я почти такой же случай с преобразованием равномерного распределения к заданному виду и разбирал, только для другого применения.

#67
5:46, 18 авг. 2012

Господа, а как вам такой вариант - берем случайное направление в плоскости XY, а затем эту плоскость вращаем на произвольной угол вокруг оси, перпендикулярной выбранному направлению и лежащей в той же плоскости XY. Это размажет полюса и получим равномерное распределение.

Участвуют два рандомных угла: a1 (0° .. 360°) и a2 ( -90° .. +90° ).

Случайное направление в плоскости XY, вектор нормализованный:

[ cos(a1) ]
[ sin(a1) ]
[    0    ]

Поворачиваем вокруг ( cos(a1+90°), sin(a1+90°) ) на угол a2

[ 1    0        0    ]   [ cos(a1+90°) -sin(a1+90°) 0 ]   [ cos(a1) ]
[ 0 cos(a2) -sin(a2) ] x [ sin(a1+90°)  cos(a1+90°) 0 ] x [ sin(a1) ]
[ 0 sin(a2)  cos(a2) ]   [      0          0        1 ]   [    0    ]

от +90° градусов можно избавиться, воспользовавшись формулами приведения.

#68
6:25, 18 авг. 2012

P.S. посчитал,

dir_x = -cos(a1)*sin(a1)
dir_y = -sin(a1)*sin(a1)*cos(a2)
dir_z = cos(a2)

achumack, нарисуй картинку?

#69
11:19, 18 авг. 2012

Алексей Патрашов
А у меня так вышло:

  a = Rnd() * 2 * Pi
  b = Rnd() * 2 - 1
  x = Sin(a) * b
  y = Cos(a) * b
  If b > 0 Then
    z = Sqr(1 - b * b)
  Else
    z = -Sqr(1 - b * b)
  End If
Возможно оно приводится к твоему варианту.
Там вообще арксинус получился в промежуточных вычислениях, но он благополучно сократился.
#70
11:30, 18 авг. 2012

Алексей Патрашов
Прошу прощения, я сам забыл что делал )
Точка проецируется с поверхности цилиндра на сферу, т.е. получается
r=sqrt(1-z^2)  // радиус малой окружности на сфере
Вектор (cos(fi)*r,sin(fi)*r,z), уже нормализован

#71
13:59, 18 авг. 2012

Ошибся в вычислениях, вот правильный вариант:

[-2*cos(a1)*sin(a1)]
[(cos(a1)^2-sin(a1)^2)*cos(a2)]
[(cos(a1)^2-sin(a1)^2)*sin(a2)]

Математический пакет Maxima строит параметрическую функцию от двух переменных вот так:

Сфера из рандомных точек (построено в Maxima) | Как получить случайное направление?

Это сфера, а скопление на полюсах это _скорее всего_ из-за способа построения. Надо проверять на реальном приложении.

#72
14:06, 18 авг. 2012

ALPINE
Это ничем не отличается от "широта, долгота", неверно

#73
14:25, 18 авг. 2012

Aslan
По идее должно отличаться, т.к. мы наклоняем ось Z, вокруг которой строятся параллели.

Но я сейчас не поленился и посмотрел на результат в приложени (выводит 10.000 точек моим способом). Полюса все равно видны

Сфера из рандомных точек | Как получить случайное направление?
#74
14:53, 18 авг. 2012

Ура! Не зря старался:

Сфера из рандомных точек с равномерной плотностью | Как получить случайное направление?

Участвуют три угла:

-180° <= a1 < +180°
0° <= a2 <= 90°
0° <= a3 <= 90°

Алгоритм:
1) выбрать случайное направление в плоскости XY: { cos(a3), sin(a3), 0 }
2) повернуть ось Z на случайный угол a2 вокруг случайного вектора { cos(a1), sin(a1), 0 }, лежащего в плоскости XY

Листинг для Maxima (на лиспе):

rotx(a) := matrix(
 [1,0,0], 
 [0,cos(a),-sin(a)], 
 [0,sin(a),cos(a)]
);

rotz(a) := matrix(
 [cos(a),-sin(a),0], 
 [sin(a),cos(a),0], 
 [0,0,1]
);

vec_dir2(a) := matrix(
[ cos(a) ],
[ sin(a) ],
[ 0 ]
);

calc_dir(a1, a2, a3) := rotx(a1) . rotz(a2) . vec_dir2(a3);

Результат перемножения матриц:

vx = cos(a2)*cos(a3)-sin(a2)*sin(a3);
vy = cos(a1)*(cos(a2)*sin(a3)+sin(a2)*cos(a3));
vz = sin(a1)*(cos(a2)*sin(a3)+sin(a2)*cos(a3));

:)

Страницы: 14 5 6 7 8 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.