Подтвердить что ты не робот

Случайная точка на заданной сфере

Я хочу выбрать случайные точки в данной сфере. Эта страница объясняет это довольно хорошо:

http://mathworld.wolfram.com/SpherePointPicking.html ( "Получить точки, такие, что любая небольшая площадь на сфере..." )

Но я не совсем уверен, правильно ли я использую его в JavaScript, поскольку у меня мало средств для его правильной проверки:

var u = random();
var v = random();
var angle1 = 2 * Math.PI * u;
var angle2 = Math.pow(Math.cos (2 * v - 1), -1);
X = X0 + (radius * Math.sin(angle1) * Math.cos(angle2));
Y = Y0 + (radius * Math.sin(angle1) * Math.sin(angle1));
Z = Z0 + (radius * Math.cos(angle1));

Я особенно неуверен в том, что правильно понял cos (-1), который я реализовал как "Косинус с мощностью -1".

4b9b3361

Ответ 1

Алгоритм куба не даст равномерного распределения по сфере - в частности, области вблизи выступов углов будут иметь самое плотное распределение точек и вблизи центров граней кубов будет самым низким.

Вы можете понять это интуитивно, так как объем куба, проецируемого на лежащую ниже сферу, больше вблизи углов, расположенных вблизи центров кубов. Фактически, объем небольшой части (проектируемой на маленьком круге на сфере) пропорционален куб размера вектора от начала координат через центр малого круга до точки на сфере, с которой он пересекается.

Таким образом, относительный объем на центре поверхности куба (например, 1,0,0)) равен 1, но для угла (например, (1,1,1)) является куб sqrt (3) или 1,73 кубика, около 5,2, поэтому почти в 5 раз плотнее!

Функция spreadпоты() может работать лучше, но я не уверен.

В вас есть несколько ошибок JavaScript - использование функции pow (.., - 1) вместо acos(), смешивание по углам и отсутствие объекта Math для вызова random().,

Вот аналогичный, но правильный JavaScript, чтобы сделать то, что говорит ссылки Wolfram:

/*
Returns a random point of a sphere, evenly distributed over the sphere.
The sphere is centered at (x0,y0,z0) with the passed in radius.
The returned point is returned as a three element array [x,y,z]. 
*/
function randomSpherePoint(x0,y0,z0,radius){
   var u = Math.random();
   var v = Math.random();
   var theta = 2 * Math.PI * u;
   var phi = Math.acos(2 * v - 1);
   var x = x0 + (radius * Math.sin(phi) * Math.cos(theta));
   var y = y0 + (radius * Math.sin(phi) * Math.sin(theta));
   var z = z0 + (radius * Math.cos(phi));
   return [x,y,z];
}

Ответ 2

Я думаю, что более простой алгоритм

  • Выберите случайную точку внутри куба [-1,1]x[-1,1]x[-1,1]
  • Если x*x + y*y + z*z > 1 повторить с 1
  • Нормализовать деление x, y и z на Math.sqrt(x*x + y*y + z*z)

Другими словами, просто выберите случайную точку внутри сферы и проект на сфере. Не беспокойтесь слишком много о "петле", потому что вероятность того, что точка находится вне сферы, составляет около 0,4764, и в среднем для цикла потребуется меньше двух итераций.

Этот алгоритм можно увидеть в действии в этой ссылке. Обратите внимание: если вы используете хром, вокруг экватора будет какая-то обвязка, которая, на мой взгляд, является ошибкой в ​​Math.random или просто случайным генератором низкого качества (отлично работает в Firefox или Safari, но та же проблема видна и в браузере Android). EDIT: эта ошибка теперь исправлена ​​на хромированных и Android-устройствах..

Обратите внимание: если вы ищете метод распределения точек равномерно над сферой, вы можете сделать что-то приятнее, выбрав десять случайных точек, как описано выше, а затем принять только тот, у которого наибольшее расстояние 3d от набора уже выбранных точки. Это все еще глобально случайное (т.е. Вероятность того, что диск с заданным радиусом получит точку, будет одинаковой для всех дисков на сфере), но будет распределять точки лучше, если вам нужно выполнить "выборку" сферы. Эта функция кодируется как spreadPoints() в html файле, указанном ссылкой.

Здесь вы можете увидеть разницу между двумя подходами:

enter image description here

В обеих сферах есть 1000 случайных точек, нарисованных на них: сфера слева использовала равномерные случайные точки, сфера справа сделала выбор, выбрав каждую точку среди десяти случайных кандидатов, чтобы максимизировать расстояние от уже выбранных точек.