Jump to content
  • Advertisement
Sign in to follow this  
Grain

Random with Normal Distribution(bell curve)

This topic is 4809 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

How would I go about making a random function that gives me numbers with normal distribution? As apposed to the flat even distribution that the rand() function gives. I’ve looked up the formula but they all seem very complex and I'm having a hard time translating it into code. Also what do you think would be the best interface for the function. Pass it the center value and the standard deviation value or give it a min max range, or something else.

Share this post


Link to post
Share on other sites
Advertisement
Thanks I got the Gaussian distributor working correctly from that other thread.
using this method

float gaussRandom(float mean, float deviation)
{
float x1, x2, w, y1;
static float y2;
static bool use_last = false;

if (use_last)
{
y1 = y2;
use_last = false;
}
else
{
do {
x1 = 2.0f * random(0.0f,1.0f) - 1.0f;
x2 = 2.0f * random(0.0f,1.0f) - 1.0f;
w = x1 * x1 + x2 * x2;
} while ( w >= 1.0f );

w = sqrt( (-2.0f * log( w ) ) / w );
y1 = x1 * w;
y2 = x2 * w;
use_last = true;
}

return (mean + (y1 * deviation));
}





However there is a problem with my even distribution random function isn’t working correctly. I get this very bizarre step on the left side of the distribution. And its skewing my bell curve.

Image Hosted by ImageShack.us

Here’s the code what am I doing wrong?


float random( float Min, float Max )
{

float Range = (Max - Min);
unsigned int Num = rand() % 10000;
float Rnd = Num/10000.0f;

return( (Range*Rnd) + Min );
}


Share this post


Link to post
Share on other sites
Using the modulo operator to restrict your random number range will not yield a uniform distribution, unless the size of that range is a power of 2. Rely on RAND_MAX instead:

float random(float min, float max)
{
float r = rand() / (float) RAND_MAX;
return min+r*(max-min);
}


Alternatively, as Sicrane mentioned, you can just use boost::random.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster

rand() function gives random numbers between -32768 and 32768 (something like that). Check RAND_MAX.

If you modulate that result with 10000 that'll give you more results at the lower end. like 2768 / 10000 of the numbers will have higher probability of appearing.

For example to get correct random between 0 - 1 would be like
float r = fabsf((float)rand()/(float)RAND_MAX);

Hope this helps

Share this post


Link to post
Share on other sites
Ok thanks, that worked.

Now could someone tell me what is the purpose of the do while loop that checks for w greater than 1.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
if you mean:

while( fVariable > 1.0f )
{
fVariable -= 1.0f;
}

It's used to restrict values to a range, in this case [0..1]. When the iteration stops the new value will be correctly clamped into range.

Warning: If the values can go a long way out though, this is a slow way of doing it.

Is this what you were interested in? Your original question is rather vague



Share this post


Link to post
Share on other sites
No I meant this

do {
x1 = 2.0f * random(0.0f,1.0f) - 1.0f;
x2 = 2.0f * random(0.0f,1.0f) - 1.0f;
w = x1 * x1 + x2 * x2;
} while ( w >= 1.0f );


I commented out the do and while() lines leaving the code inside and It still gives me a perfect bell curve only its a little lower and flatter.

Share this post


Link to post
Share on other sites
it tries random values for x1,x2 on rectangle (-1,-1)..(1,1) , then computes squared radius (distance from 0,0 to x1,x2) and tries again with new x1,x2 if radius is greater than 1.
I.e. at end of this block of code you get x1,x2 uniformly distributed in the unit circle.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!