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 #include <random>
00026 #include "cinder/Vector.h"
00027
00028 namespace cinder {
00029
00030 class Rand {
00031 public:
00032 Rand()
00033 : mBase( 214u ), mHaveNextNextGaussian( false )
00034 {}
00035
00036 Rand( unsigned long seed )
00037 : mBase( seed ), mHaveNextNextGaussian( false )
00038 {}
00039
00041 void seed( unsigned long seedValue );
00042
00044 bool nextBool()
00045 {
00046 return mBase() & 1;
00047 }
00048
00050 int32_t nextInt()
00051 {
00052 return mBase();
00053 }
00054
00056 uint32_t nextUint()
00057 {
00058 return mBase();
00059 }
00060
00062 int32_t nextInt( int32_t v )
00063 {
00064 if( v <= 0 ) return 0;
00065 return mBase() % v;
00066 }
00067
00069 uint32_t nextUint( uint32_t v )
00070 {
00071 if( v == 0 ) return 0;
00072 return mBase() % v;
00073 }
00074
00076 int32_t nextInt( int32_t a, int32_t b )
00077 {
00078 return nextInt( b - a ) + a;
00079 }
00080
00082 float nextFloat()
00083 {
00084 return mFloatGen(mBase);
00085 }
00086
00088 float nextFloat( float v )
00089 {
00090 return mFloatGen(mBase) * v;
00091 }
00092
00094 float nextFloat( float a, float b )
00095 {
00096 return mFloatGen(mBase) * ( b - a ) + a;
00097 }
00098
00100 float posNegFloat( float a, float b )
00101 {
00102 if( nextBool() )
00103 return nextFloat( a, b );
00104 else
00105 return -nextFloat( a, b );
00106 }
00107
00109 Vec3f nextVec3f()
00110 {
00111 float phi = nextFloat( (float)M_PI * 2.0f );
00112 float costheta = nextFloat( -1.0f, 1.0f );
00113
00114 float rho = math<float>::sqrt( 1.0f - costheta * costheta );
00115 float x = rho * math<float>::cos( phi );
00116 float y = rho * math<float>::sin( phi );
00117 float z = costheta;
00118
00119 return Vec3f( x, y, z );
00120 }
00121
00123 Vec2f nextVec2f( )
00124 {
00125 float theta = nextFloat( (float)M_PI * 2.0f );
00126 return Vec2f( math<float>::cos( theta ), math<float>::sin( theta ) );
00127 }
00128
00130 float nextGaussian()
00131 {
00132 if( mHaveNextNextGaussian ) {
00133 mHaveNextNextGaussian = false;
00134 return mNextNextGaussian;
00135 }
00136 else {
00137 float v1, v2, s;
00138 do {
00139 v1 = 2.0f * nextFloat() - 1.0f;
00140 v2 = 2.0f * nextFloat() - 1.0f;
00141
00142 s = v1 * v1 + v2 * v2;
00143 }
00144 while( s >= 1.0f || s == 0.0f );
00145
00146 float m = math<float>::sqrt(-2.0f * math<float>::log(s)/s);
00147
00148 mNextNextGaussian = v2 * m;
00149 mHaveNextNextGaussian = true;
00150
00151 return v1 * m;
00152 }
00153 }
00154
00155
00157 static void randomize();
00158
00160 static void randSeed( unsigned long seedValue );
00161
00163 static bool randBool()
00164 {
00165 return sBase() & 1;
00166 }
00167
00169 static int32_t randInt()
00170 {
00171 return sBase();
00172 }
00173
00175 static uint32_t randUint()
00176 {
00177 return sBase();
00178 }
00179
00181 static int32_t randInt( int32_t v )
00182 {
00183 if( v <= 0 ) return 0;
00184 else return sBase() % v;
00185 }
00186
00188 static uint32_t randUint( uint32_t v )
00189 {
00190 if( v == 0 ) return 0;
00191 else return sBase() % v;
00192 }
00193
00195 static int32_t randInt( int32_t a, int32_t b )
00196 {
00197 return randInt( b - a ) + a;
00198 }
00199
00201 static float randFloat()
00202 {
00203 return sFloatGen(sBase);
00204 }
00205
00207 static float randFloat( float v )
00208 {
00209 return sFloatGen(sBase) * v;
00210 }
00211
00213 static float randFloat( float a, float b )
00214 {
00215 return sFloatGen(sBase) * ( b - a ) + a;
00216 }
00217
00219 static float randPosNegFloat( float a, float b )
00220 {
00221 if( randBool() )
00222 return randFloat( a, b );
00223 else
00224 return -randFloat( a, b );
00225 }
00226
00228 static Vec3f randVec3f()
00229 {
00230 float phi = randFloat( (float)M_PI * 2.0f );
00231 float costheta = randFloat( -1.0f, 1.0f );
00232
00233 float rho = math<float>::sqrt( 1.0f - costheta * costheta );
00234 float x = rho * math<float>::cos( phi );
00235 float y = rho * math<float>::sin( phi );
00236 float z = costheta;
00237
00238 return Vec3f( x, y, z );
00239 }
00240
00242 static Vec2f randVec2f()
00243 {
00244 float theta = randFloat( (float)M_PI * 2.0f );
00245 return Vec2f( math<float>::cos( theta ), math<float>::sin( theta ) );
00246 }
00247
00249 static float randGaussian()
00250 {
00251 static bool sHaveNextNextGaussian = false;
00252 static float sNextNextGaussian;
00253
00254 if( sHaveNextNextGaussian ) {
00255 sHaveNextNextGaussian = false;
00256 return sNextNextGaussian;
00257 }
00258 else {
00259 float v1, v2, s;
00260 do {
00261 v1 = 2.0f * sFloatGen(sBase) - 1.0f;
00262 v2 = 2.0f * sFloatGen(sBase) - 1.0f;
00263
00264 s = v1 * v1 + v2 * v2;
00265 }
00266 while( s >= 1.0f || s == 0.0f );
00267
00268 float m = math<float>::sqrt(-2.0f * math<float>::log(s)/s);
00269
00270 sNextNextGaussian = v2 * m;
00271 sHaveNextNextGaussian = true;
00272
00273 return v1 * m;
00274 }
00275 }
00276
00277 private:
00278 std::mt19937 mBase;
00279 std::uniform_real_distribution<float> mFloatGen;
00280 float mNextNextGaussian;
00281 bool mHaveNextNextGaussian;
00282
00283 static std::mt19937 sBase;
00284 static std::uniform_real_distribution<float> sFloatGen;
00285 };
00286
00288 inline void randSeed( unsigned long seedValue ) { Rand::randSeed( seedValue ); }
00289
00291 inline bool randBool() { return Rand::randBool(); }
00292
00294 inline int32_t randInt() { return Rand::randInt(); }
00295
00297 inline int32_t randInt( int32_t v ) { return Rand::randInt( v ); }
00298
00300 inline int32_t randInt( int32_t a, int32_t b ) { return Rand::randInt( a, b ); }
00301
00303 inline float randFloat() { return Rand::randFloat(); }
00304
00306 inline float randFloat( float v ) { return Rand::randFloat( v ); }
00307
00309 inline float randFloat( float a, float b ) { return Rand::randFloat( a, b ); }
00310
00312 inline float randPosNegFloat( float a, float b ) { return Rand::randPosNegFloat( a, b ); }
00313
00315 inline Vec3f randVec3f() { return Rand::randVec3f(); }
00316
00318 inline Vec2f randVec2f() { return Rand::randVec2f(); }
00319
00321 inline float randGaussian() { return Rand::randGaussian(); }
00322
00323 }