Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #pragma once
00024
00025 #pragma push_macro("nil")
00026 #pragma push_macro("Nil")
00027 #undef nil
00028 #undef Nil
00029 #include <boost/random.hpp>
00030 #include <boost/random/uniform_int.hpp>
00031 #include <boost/random/uniform_real.hpp>
00032 #include <boost/random/mersenne_twister.hpp>
00033 #pragma pop_macro("Nil")
00034 #pragma pop_macro("nil")
00035
00036 #include "cinder/Vector.h"
00037
00038 namespace cinder {
00039
00040 class Rand {
00041 public:
00042 Rand()
00043 : mBase( 214u ), mFloatGen( mBase, boost::uniform_real<float>( 0.0f, 1.0f ) ), mIntGen( mBase, boost::uniform_int<>( 0, 2147483647 ) )
00044 {}
00045
00046 Rand( uint32_t seed )
00047 : mBase( seed ), mFloatGen( mBase, boost::uniform_real<float>( 0.0f, 1.0f ) ), mIntGen( mBase, boost::uniform_int<>( 0, 2147483647 ) )
00048 {}
00049
00051 void seed( uint32_t seedValue );
00052
00054 bool nextBool()
00055 {
00056 return mIntGen() & 1;
00057 }
00058
00060 int32_t nextInt()
00061 {
00062 return mIntGen();
00063 }
00064
00066 int32_t nextInt( int32_t v )
00067 {
00068 return mIntGen() % v;
00069 }
00070
00072 int32_t nextInt( int32_t a, int32_t b )
00073 {
00074 return nextInt( b - a ) + a;
00075 }
00076
00078 float nextFloat()
00079 {
00080 return mFloatGen();
00081 }
00082
00084 float nextFloat( float v )
00085 {
00086 return mFloatGen() * v;
00087 }
00088
00090 float nextFloat( float a, float b )
00091 {
00092 return mFloatGen() * ( b - a ) + a;
00093 }
00094
00096 float posNegFloat( float a, float b )
00097 {
00098 if( nextBool() )
00099 return nextFloat( a, b );
00100 else
00101 return -nextFloat( a, b );
00102 }
00103
00105 Vec3f nextVec3f()
00106 {
00107 float phi = nextFloat( (float)M_PI * 2.0f );
00108 float costheta = nextFloat( -1.0f, 1.0f );
00109
00110 float rho = math<float>::sqrt( 1.0f - costheta * costheta );
00111 float x = rho * math<float>::cos( phi );
00112 float y = rho * math<float>::sin( phi );
00113 float z = costheta;
00114
00115 return Vec3f( x, y, z );
00116 }
00117
00119 Vec2f nextVec2f( )
00120 {
00121 float theta = nextFloat( (float)M_PI * 2.0f );
00122 return Vec2f( math<float>::cos( theta ), math<float>::sin( theta ) );
00123 }
00124
00126 float nextGaussian()
00127 {
00128 if (mHaveNextNextGaussian) {
00129 mHaveNextNextGaussian = false;
00130 return mNextNextGaussian;
00131 }
00132 else {
00133 float v1, v2, s;
00134 do {
00135 v1 = 2.0f * nextFloat() - 1.0f;
00136 v2 = 2.0f * nextFloat() - 1.0f;
00137
00138 s = v1 * v1 + v2 * v2;
00139 }
00140 while (s >= 1.0f || s == 0.0f);
00141
00142 float m = math<float>::sqrt(-2.0f * math<float>::log(s)/s);
00143
00144 mNextNextGaussian = v2 * m;
00145 mHaveNextNextGaussian = true;
00146
00147 return v1 * m;
00148 }
00149 }
00150
00151
00153 static void randomize();
00154
00156 static void randSeed( uint32_t seedValue );
00157
00159 static bool randBool()
00160 {
00161 return sIntGen() & 1;
00162 }
00163
00165 static int32_t randInt()
00166 {
00167 return sIntGen();
00168 }
00169
00171 static int32_t randInt( int32_t v )
00172 {
00173 if( v == 0 ) return 0;
00174 else return sIntGen() % v;
00175 }
00176
00178 static int32_t randInt( int32_t a, int32_t b )
00179 {
00180 return randInt( b - a ) + a;
00181 }
00182
00184 static float randFloat()
00185 {
00186 return sFloatGen();
00187 }
00188
00190 static float randFloat( float v )
00191 {
00192 return sFloatGen() * v;
00193 }
00194
00196 static float randFloat( float a, float b )
00197 {
00198 return sFloatGen() * ( b - a ) + a;
00199 }
00200
00202 static float randPosNegFloat( float a, float b )
00203 {
00204 if( randBool() )
00205 return randFloat( a, b );
00206 else
00207 return -randFloat( a, b );
00208 }
00209
00211 static Vec3f randVec3f()
00212 {
00213 float phi = randFloat( (float)M_PI * 2.0f );
00214 float costheta = randFloat( -1.0f, 1.0f );
00215
00216 float rho = math<float>::sqrt( 1.0f - costheta * costheta );
00217 float x = rho * math<float>::cos( phi );
00218 float y = rho * math<float>::sin( phi );
00219 float z = costheta;
00220
00221 return Vec3f( x, y, z );
00222 }
00223
00225 static Vec2f randVec2f()
00226 {
00227 float theta = randFloat( (float)M_PI * 2.0f );
00228 return Vec2f( math<float>::cos( theta ), math<float>::sin( theta ) );
00229 }
00230
00232 static float randGaussian()
00233 {
00234 static bool sHaveNextNextGaussian;
00235 static float sNextNextGaussian;
00236
00237 if (sHaveNextNextGaussian) {
00238 sHaveNextNextGaussian = false;
00239 return sNextNextGaussian;
00240 }
00241 else {
00242 float v1, v2, s;
00243 do {
00244 v1 = 2.0f * sFloatGen() - 1.0f;
00245 v2 = 2.0f * sFloatGen() - 1.0f;
00246
00247 s = v1 * v1 + v2 * v2;
00248 }
00249 while (s >= 1.0f || s == 0.0f);
00250
00251 float m = math<float>::sqrt(-2.0f * math<float>::log(s)/s);
00252
00253 sNextNextGaussian = v2 * m;
00254 sHaveNextNextGaussian = true;
00255
00256 return v1 * m;
00257 }
00258 }
00259
00260 private:
00261 boost::mt19937 mBase;
00262 boost::variate_generator<boost::mt19937&, boost::uniform_real<float> > mFloatGen;
00263 boost::variate_generator<boost::mt19937&, boost::uniform_int<> > mIntGen;
00264 float mNextNextGaussian;
00265 bool mHaveNextNextGaussian;
00266
00267 static boost::mt19937 sBase;
00268 static boost::variate_generator<boost::mt19937&, boost::uniform_real<float> > sFloatGen;
00269 static boost::variate_generator<boost::mt19937&, boost::uniform_int<> > sIntGen;
00270 };
00271
00273 inline void randSeed( uint32_t seedValue ) { Rand::randSeed( seedValue ); }
00274
00276 inline bool randBool() { return Rand::randBool(); }
00277
00279 inline int32_t randInt() { return Rand::randInt(); }
00280
00282 inline int32_t randInt( int32_t v ) { return Rand::randInt( v ); }
00283
00285 inline int32_t randInt( int32_t a, int32_t b ) { return Rand::randInt( a, b ); }
00286
00288 inline float randFloat() { return Rand::randFloat(); }
00289
00291 inline float randFloat( float v ) { return Rand::randFloat( v ); }
00292
00294 inline float randFloat( float a, float b ) { return Rand::randFloat( a, b ); }
00295
00297 inline float randPosNegFloat( float a, float b ) { return Rand::randPosNegFloat( a, b ); }
00298
00300 inline Vec3f randVec3f() { return Rand::randVec3f(); }
00301
00303 inline Vec2f randVec2f() { return Rand::randVec2f(); }
00304
00306 inline float randGaussian() { return Rand::randGaussian(); }
00307
00308 }