Add random([[min], max]) and random_normal([o]).

Little helpers for drawing numbers from bounded uniform and Gaussian
distributions.
This commit is contained in:
vrld
2012-09-10 19:45:54 +02:00
parent e9dcc16f16
commit 50fd169e07
2 changed files with 69 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
#include "math.h"
#include <limits>
#include <cmath>
namespace
{
// The BoxMuller transform generates two random numbers, one of which we cache here.
// A value +infinity is used to signal the cache is invalid and that new numbers have
// to be generated.
float last_randnormal = std::numeric_limits<float>::infinity();
}
namespace love
{
float random_normal(float o)
{
// number in cache?
if (last_randnormal != std::numeric_limits<float>::infinity())
{
float r = last_randnormal;
last_randnormal = std::numeric_limits<float>::infinity();
return r * o;
}
// else: generate numbers using the Box-Muller transform
float a = sqrt(-2.0f * log(random()));
float b = LOVE_M_PI * 2.0f * random();
last_randnormal = a * cos(b);
return a * sin(b) * o;
}
} // namespace love
+36
View File
@@ -22,6 +22,7 @@
#define LOVE_MATH_H #define LOVE_MATH_H
#include <climits> // for CHAR_BIT #include <climits> // for CHAR_BIT
#include <cstdlib> // for rand() and RAND_MAX
/* Definitions of useful mathematical constants /* Definitions of useful mathematical constants
* M_E - e * M_E - e
@@ -80,6 +81,41 @@ inline float next_p2(float x)
return static_cast<float>(next_p2(static_cast<int>(x))); return static_cast<float>(next_p2(static_cast<int>(x)));
} }
/**
* Draws a random number from a uniform distribution.
* @returns Uniformly distributed random number in [0:1).
*/
inline float random()
{
return float(rand()) / (float(RAND_MAX) + 1.0f);
}
/**
* Draws a random number from a uniform distribution.
* @return Uniformly distributed random number in [0:max).
*/
inline float random(float max)
{
return random() * max;
}
/**
* Draws a random number from a uniform distribution.
* @return Uniformly distributed random number in [min:max).
*/
inline float random(float min, float max)
{
return random(max - min) + min;
}
/**
* Draws a random number from a normal/gaussian distribution.
* @param o Standard deviation of the distribution.
* @returns Normal distributed random number with mean 0 and variance o^2.
*/
float random_normal(float o = 1.);
#define random_gaussion random_normal
} // love } // love
#endif // LOVE_MATH_H #endif // LOVE_MATH_H