I'm trying to build simple particle system, I'm beginner c++ coder. I have problems probably with random number generator but I'm not sure if I did not make some logic error in my code. I tried to made simple explosion like effect. All particles starts in the same point and then going out in all directions from that point. All particles have positions aligned to pixels (I mean int numbers) and speed which is floating point number. Below I provide some relevant code:
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;
The problem is that there are visible lines aligned to x and y axis, like cross with center in emiter position. Majority of particles are near those lines, problem becomes more visible when number of particles increase, around 9000 particles lines are almost solid, also shape of explosion is not really circular, its more like square standing on the corner. Maybe I chose wrong random number gen, maybe something else is wrong, I really appreciate any help.
Your calculation of the velocity is not correct.
//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);
A note on terminology: 'speed' is a scalar value, and does not have direction. You should use the term 'velocity' to denote a vector with both direction and speed.
The problem with the above code is that the x and y values are independently generated. If you were to compare the direction radiany
to the direction you actually assign to speed
you would see that they don't match up.
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);
Alternatively you can generate a random velocity directly, without using sine and cosine, by creating a vector distribution. An ad hoc implementation would look like:
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.
If you wanted to get fancy you could wrap this up in a custom distribution and then your original code might look like:
my_vector_distribution<float, 2> velocity_distribution(6);
tworzona.velocity = velocity_distribution(generator);