Рассчитать точки вокруг сферы - PullRequest
1 голос
/ 20 марта 2012

Как я могу рассчитать точки вокруг сферы? Мне нужно это для взрыва частиц. Я не хочу, чтобы точки частицы были случайными. Я нуждаюсь в них в сферическом образце. Для взрыва 2-го круга я использовал это:

float n=many;
float rad = 1;
for (int i = 0; i < n; i++)
{
        float fi = 2*PI*i/n;
        float x1 = rad*sin(fi + PI)+x ;
        float y1 = rad*cos(fi + PI)+y ;
        addparticlesmart(x,y,(x1-x),(y1-y), 0.01f),r,g,b,a,0.02f);
}

Ответы [ 3 ]

6 голосов
/ 20 марта 2012

Полное преобразование из сферических в декартовы координаты:

Cartesian coordinates: (x,y,z)
Spherical coordinates: (r,φ,θ) with r∈[0,∞), φ∈[0,2π), θ∈[0,π]

Then:
x = r*cos(φ)*sin(θ)
y = r*sin(φ)*sin(θ)
z = r*cos(θ)
5 голосов
/ 20 марта 2012

У вас есть несколько вариантов.

Lat / Lon - Цикл по широте от -π / 2 до + π / 2 и долготе от 0 до 2π с любым интервалом, который вам нравится.Затем преобразуйте из сферических в декартовых координат.Хотя это легко кодировать, у него есть недостаток, заключающийся в том, что точки имеют тенденцию кластеризоваться на полюсах.

Тесселяция - Вы можете выбрать правильный многогранник , предпочтительно стреугольные грани (мой любимый для этой цели икосаэдр ) и рекурсивный поиск биссектрисы каждого края каждой грани.Затем вы делите эту грань на четыре треугольные грани, нормализуя биссектрисы, чтобы они лежали на поверхности сферы.Хотя точки не совсем равномерно распределены по сфере (что видно, если вы не используете икосаэдр в качестве базового многогранника), похоже, что оно распределено гораздо более равномерно, чем подход широта / долгота.Недостатком является несколько более сложный код.Более подробное описание доступно здесь .

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

есть хорошая трактовка.
3 голосов
/ 20 марта 2012

Если вы можете использовать новый стандарт c ++ 11, легко создать гауссово распределенные случайные числа.Затем вы можете использовать тот факт, что три одномерных гауссовых числа составляют одну трехмерную гауссову координату, которая равномерно распределена по сфере постоянного радиуса (радиус распределен по Гауссу).Если вы хотите, чтобы координаты были только на определенном радиусе, вы должны нормализовать ваши координаты.Вот как вы можете это сделать:

#include <iostream>
#include <random>
#include <cmath>


using namespace std;

int main (int argC, char* argV[])
{
    //Create random generator
    mt19937 rnd;
    //Create Gaussian distribution
    normal_distribution<double> normDist ( 0.0, 1.0 );
    //Seed random generator
    rnd.seed(time(NULL));

    const double sphereRadius = 1;

    //Create 3 Gauss Random Numbers
    double rndArray[3];
    double rndSqrSum = 0;
    for ( uint i = 0; i < 3; i++ )
    {
        rndArray[i] = normDist( rnd );
        rndSqrSum += rndArray[i] * rndArray[i];
    }

    //Calculate Faktor to get a Sphere of radius sphereRadius
    double faktor = sphereRadius / sqrt( rndSqrSum ) ;

    //The random Coordinates then are:
    double x = rndArray[0]*faktor;
    double y = rndArray[1]*faktor;
    double z = rndArray[2]*faktor;

    cout << "Koordinates are: " << endl << "x: " << x << endl << "y: " << y << endl << "z: " << z << endl << "Radius is: " << sqrt(x*x+y*y+z*z) << endl;

}

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

...