计算球体周围的点

Calculate points around a sphere

本文关键字:周围 计算      更新时间:2023-10-16

如何计算球体周围的点?我的粒子爆炸需要这个。我不希望粒子的点都是随机的。我需要它们呈球形。对于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);
}

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

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

您有几个选项。

Lat/Lon-从-π2到+π2和从0到2π在你喜欢的任何时间间隔。然后将球面坐标转换为笛卡尔坐标。虽然这很容易编码,但它的缺点是点往往聚集在极点。

镶嵌-你可以选择一个正多面体,最好是三角形面(二十面体是我最喜欢的),并递归地找到每个面的每条边的平分线。然后将该面划分为四个三角形面,对平分点进行标准化,使它们位于球体表面上。虽然点在球体上的分布并不均匀(如果不使用二十面体作为基本多面体,就可以看出这一点),但它似乎比lat/lon方法分布得更均匀。它有一个缺点,编码起来有点困难。此处提供了更详细的描述。

随机点-我知道你说过你不喜欢挑选随机点的想法,但为了完整起见,我会在这里包括它。在Wolfram的网站上,它得到了很好的处理。

如果您可以使用新的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个维度的问题。