2016-10-05 8 views
0

Я использую spherical coordinate system article Википедии для создания сферы, сделанной из частиц в Three.js. На основании этой статьи, я создал небольшой Polarizer класс, который принимает в полярных координатах с setPolar(rho, theta, phi) и возвращает соответствующий х, у, г3D: избежать защемления на полюсах при создании сферы из полярных координат

Вот setPolar() функцию:

// Rho: radius 
// theta θ: polar angle on Y axis 
// phi φ: azimuthal angle on Z axis 

Polarizer.prototype.setPolar = function(rho, theta, phi){ 
    // Limit values to zero 
    this.rho = Math.max(0, rho); 
    this.theta = Math.max(0, theta); 
    this.phi = Math.max(0, phi); 

    // Calculate x,y,z 
    this.x = this.rho * Math.sin(this.theta) * Math.sin(this.phi); 
    this.y = this.rho * Math.cos(this.theta); 
    this.z = this.rho * Math.sin(this.theta) * Math.cos(this.phi); 

    return this; 
} 

Я использую его положение моих частиц следующим образом:

var tempPolarizer = new Polarizer(); 

for(var i = 0; i < geometry.vertices.length; i++){ 
    tempPolarizer.setPolar(
    50,       // Radius of 50 
    Math.random() * Math.PI, // Theta ranges from 0 - PI 
    Math.random() * 2 * Math.PI // Phi ranges from 0 - 2PI 
); 

    // Set new vertex positions 
    geometry.vertices[i].set(
    tempPolarizer.x, 
    tempPolarizer.y, 
    tempPolarizer.z 
); 
} 

Он прекрасно работает, за исключением того, что я получаю высокую плотность частиц, или «ущемления» на полюсах:

PolarPinching

Я в тупике относительно того, как избежать этого. Я думал о передаче взвешенного случайного числа на широту, но я надеюсь оживить частицы без долготы, также замедляя и группируя их на полюсах.

Есть ли другая формула для создания сферы, где полюса не получают столько же веса? Должен ли я использовать кватернионы вместо этого?

+1

Я хотел бы посмотреть здесь http://stackoverflow.com/questions/5531827/random-point-on-a-given-sphere для двух возможных решений, а также, в более общем плане, икосаэдр сфера дополнительный в three.js, который может быть полезен в зависимости от того, как вам нужно проверить распределение шума. Пример: https://codepen.io/Mombasa/pen/fvgqb – Radio

+0

http://mathworld.wolfram.com/SpherePointPicking.html – WestLangley

+0

@Radio, это именно то, что я искал! Я должен был использовать что-то похожее на взвешенный генератор случайных чисел, который имел более высокую вероятность приблизиться к 0,5, чем к 0 или 1. – Marquizzo

ответ

1

Чтобы избежать высокой плотности на полюсах, мне пришлось снизить вероятность приближения тета (широты) до 0 и PI. Мой ввод

Math.random() * Math.PI, для theta дает равную вероятность для всех значений (оранжевый).

Math.acos((Math.random() * 2) - 1) идеально взвешивает выход сделать 0 и PI менее вероятно, вдоль поверхности сферы (желтый)

enter image description here

enter image description here

Теперь я не могу даже сказать, где полюса!

2
  1. Для случайной выборки равномерной

    использование случайной точки в единичном кубе, обрабатывать его в качестве вектора и установить его длину, чтобы радиус вашей сферы. Например, что-то вроде этого в C++:

    x = 2.0*Random()-1.0; 
    y = 2.0*Random()-1.0; 
    z = 2.0*Random()-1.0; 
    m=r/sqrt(x*x+y*y+z*z); 
    x*=m; 
    y*=m; 
    z*=m; 
    

    где случайный обратный номер в <0.0,1.0>.Для получения дополнительной информации см:

  2. Для равномерного неслучайной выборки

    см связанные QA S: