<random> 随机数生成器和均匀分布



我正在尝试构建简单的粒子系统,我是c++程序员的初学者。我可能在随机数生成器方面有问题,但我不确定我是否在代码中犯了一些逻辑错误。我试着做出简单的爆炸般的效果。所有粒子从同一点开始,然后从该点向所有方向射出。所有粒子的位置都与像素对齐(我指的是整数),速度是浮点数。下面我提供一些相关代码:

std::mt19937 generator(std::time(0));//creating random number gen with seed
std::uniform_real_distribution<float> distributionx(0,6);
std::uniform_real_distribution<float> distributionkat(0,360);//distr for random number degrese
float radiany=(distributionkat(generator)*3.1415)/180;//calculating radians to provide to sin/cos function
sf::Vector2f unitvector;
tworzona.pozycja.x=this->pozycjaemitera.x;//assigning starting position, same for all particles
tworzona.pozycja.y=this->pozycjaemitera.y;
//below i calculate starting speed, as far as i know trigonometry this sure ensure that particles will fly in all directions
tworzona.speed.x=distributionx(generator)*cos(radiany);
tworzona.speed.y=distributionx(generator)*sin(radiany);
//below code should calculate unit vector in chosen direction and then i multiply it by random speed
unitvector.x=tworzona.speed.x/sqrt(pow(tworzona.speed.x,2)+pow(tworzona.speed.y,2));
unitvector.y=tworzona.speed.y/sqrt(pow(tworzona.speed.x,2)+pow(tworzona.speed.y,2));
unitvector.x=unitvector.x*distributionx(generator);
unitvector.y=unitvector.y*distributionx(generator);
tworzona.speed.x=unitvector.x;
tworzona.speed.y=unitvector.y;

问题是,有一些可见的线与x和y轴对齐,比如中心在发射器位置的十字。大多数粒子都在这些线附近,当粒子数量增加时,问题变得更加明显,大约9000条粒子线几乎是实心的,爆炸的形状也不是真正的圆形,它更像是站在角落里的正方形。也许我选错了随机数,也许其他地方出了问题,我真的很感激任何帮助。

您对速度的计算不正确。

//below i calculate starting speed, as far as i know trigonometry this sure ensure that particles will fly in all directions
tworzona.speed.x=distributionx(generator)*cos(radiany);
tworzona.speed.y=distributionx(generator)*sin(radiany);

术语注释:"速度"是一个标量值,没有方向。您应该使用术语"速度"来表示同时具有方向和速度的向量。

上述代码的问题在于x和y值是独立生成的。如果将方向radiany与实际分配给speed的方向进行比较,您会发现它们不匹配。

constexpr float pi = 3.1415926535f;
std::uniform_real_distribution<float> speed_distribution(0, 6);
std::uniform_real_distribution<float> direction_distribution(0, 2*pi);
float radians = direction_distribution(generator);
float speed = speed_distribution(generator);
unitvector.x = cos(radians);
unitvector.y = sin(radians);
tworzona.velocity.x = speed * cos(radians);
tworzona.velocity.y = speed * sin(radians);

或者,您可以通过创建矢量分布直接生成随机速度,而不使用正弦和余弦。一个特别的实现看起来像:

const double max_speed = 6.0;
const double max_squared = max_speed * max_speed;

std::uniform_real_distribution<double> d(0.0, max_speed);
double x, y;
do {
  x = d(generator);
  y = d(generator);
} while (x*x+y*y > max_squared);
// x and y are the random velocity, uniformly distributed in all directions,
// speed uniformly distributed between 0 and max_speed.

如果你想得到幻想,你可以把它包装在一个自定义的发行版中,然后你的原始代码可能看起来像:

my_vector_distribution<float, 2> velocity_distribution(6);
tworzona.velocity = velocity_distribution(generator);

所有粒子的位置都与像素对齐(我的意思是整数),速度是浮点数

这是你的问题。无论速度如何,更新后的位置总是会恢复到原始值(当速度<1.0时)或仅增加整数

保持你的位置也作为浮点值,问题就会消失。

我发现很难遵循你的速度更新过程,但这可能是由于你的变量名。"通常"的方法是分配一个初始随机水平和垂直速度(1),其中水平速度线性衰减("空气摩擦"),垂直速度二次增加("重力")。

(1) 我想你指定初始角度和速度的方法还可以。但是,您可以将其拆分为水平和垂直分量,并忘记所有基于矢量的计算。

最新更新