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