计算球体周围的点

时间:2012-03-20 13:17:21

标签: c++ math geometry particle-system

如何计算球体周围的点数?我的粒子爆炸需要这个。我不希望粒子的点是随机的。我需要它们呈球形。 对于2d圈爆炸,我使用了这个:

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 个答案:

答案 0 :(得分:6)

从球形坐标到笛卡尔坐标的完全转换:

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(θ)

答案 1 :(得分:5)

您有几个选择。

Lat / Lon - 在纬度上从-π/ 2到+π/ 2循环,经度从0到2π循环,无论你喜欢什么间隔。然后从球形坐标转换为笛卡尔坐标。虽然这很容易编码,但它的缺点是点往往聚集在极点。

曲面细分 - 您可以选择一个regular polyhedron,最好是三角形面((icosahedron是我最喜欢的)并递归地找到每个边缘的平分线每张脸。然后,将该面分成四个三角形面,对等分线点进行标准化,使它们位于球体的表面上。虽然这些点在球体上的分布并不是很均匀(如果不使用二十面体作为基础多面体,可以看到它),它看起来比纬度/经度方法分布更均匀。它有一个缺点,代码更难一些。有更详细的说明here

随机点 - 我知道你说你不喜欢选择随机点的想法,但为了完整起见我会把它包含在这里。在Wolfram's site处有一个很好的处理方法。

答案 2 :(得分:3)

如果您可以使用新的c ++ 11标准,则很容易创建高斯分布随机数。然后你可以使用这样的事实:三个1维高斯数字形成一个三维高斯坐标,它均匀分布在恒定半径的球体上(半径是高斯分布的)。如果只想要特定半径的坐标,则必须标准化坐标。这是你如何做到的:

#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维问题。