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 <boost/random.hpp>
00026 #include <boost/random/uniform_int.hpp>
00027 #include <boost/random/uniform_real.hpp>
00028 #include <boost/random/mersenne_twister.hpp>
00029
00030 #include "cinder/Vector.h"
00031
00032 namespace cinder {
00033
00034 class Rand {
00035 public:
00036 Rand()
00037 : mBase( 214u ), mFloatGen( mBase, boost::uniform_real<float>( 0.0f, 1.0f ) ), mIntGen( mBase, boost::uniform_int<>( 0, 2147483647 ) )
00038 {}
00039
00040 Rand( uint32_t seed )
00041 : mBase( seed ), mFloatGen( mBase, boost::uniform_real<float>( 0.0f, 1.0f ) ), mIntGen( mBase, boost::uniform_int<>( 0, 2147483647 ) )
00042 {}
00043
00045 bool nextBool()
00046 {
00047 return mIntGen() & 1;
00048 }
00049
00051 int32_t nextInt()
00052 {
00053 return mIntGen();
00054 }
00055
00057 int32_t nextInt( int32_t v )
00058 {
00059 return mIntGen() % v;
00060 }
00061
00063 int32_t nextInt( int32_t a, int32_t b )
00064 {
00065 return nextInt( b - a ) + a;
00066 }
00067
00069 float nextFloat()
00070 {
00071 return mFloatGen();
00072 }
00073
00075 float nextFloat( float v )
00076 {
00077 return mFloatGen() * v;
00078 }
00079
00081 float nextFloat( float a, float b )
00082 {
00083 return mFloatGen() * ( b - a ) + a;
00084 }
00085
00087 float posNegFloat( float a, float b )
00088 {
00089 if( nextBool() )
00090 return nextFloat( a, b );
00091 else
00092 return -nextFloat( a, b );
00093 }
00094
00096 Vec3f nextVec3f()
00097 {
00098 float phi = nextFloat( (float)M_PI * 2.0f );
00099 float costheta = nextFloat( -1.0f, 1.0f );
00100
00101 float rho = math<float>::sqrt( 1.0f - costheta * costheta );
00102 float x = rho * math<float>::cos( phi );
00103 float y = rho * math<float>::sin( phi );
00104 float z = costheta;
00105
00106 return Vec3f( x, y, z );
00107 }
00108
00110 Vec2f nextVec2f( )
00111 {
00112 float theta = nextFloat( (float)M_PI * 2.0f );
00113 return Vec2f( math<float>::cos( theta ), math<float>::sin( theta ) );
00114 }
00115
00116
00118 static void randomize();
00119
00121 static bool randBool()
00122 {
00123 return sIntGen() & 1;
00124 }
00125
00127 static int32_t randInt()
00128 {
00129 return sIntGen();
00130 }
00131
00133 static int32_t randInt( int32_t v )
00134 {
00135 if( v == 0 ) return 0;
00136 else return sIntGen() % v;
00137 }
00138
00140 static int32_t randInt( int32_t a, int32_t b )
00141 {
00142 return randInt( b - a ) + a;
00143 }
00144
00146 static float randFloat()
00147 {
00148 return sFloatGen();
00149 }
00150
00152 static float randFloat( float v )
00153 {
00154 return sFloatGen() * v;
00155 }
00156
00158 static float randFloat( float a, float b )
00159 {
00160 return sFloatGen() * ( b - a ) + a;
00161 }
00162
00164 static float randPosNegFloat( float a, float b )
00165 {
00166 if( randBool() )
00167 return randFloat( a, b );
00168 else
00169 return -randFloat( a, b );
00170 }
00171
00173 static Vec3f randVec3f()
00174 {
00175 float phi = randFloat( (float)M_PI * 2.0f );
00176 float costheta = randFloat( -1.0f, 1.0f );
00177
00178 float rho = math<float>::sqrt( 1.0f - costheta * costheta );
00179 float x = rho * math<float>::cos( phi );
00180 float y = rho * math<float>::sin( phi );
00181 float z = costheta;
00182
00183 return Vec3f( x, y, z );
00184 }
00185
00187 static Vec2f randVec2f()
00188 {
00189 float theta = randFloat( (float)M_PI * 2.0f );
00190 return Vec2f( math<float>::cos( theta ), math<float>::sin( theta ) );
00191 }
00192
00193 private:
00194 boost::mt19937 mBase;
00195 boost::variate_generator<boost::mt19937&, boost::uniform_real<float> > mFloatGen;
00196 boost::variate_generator<boost::mt19937&, boost::uniform_int<> > mIntGen;
00197
00198 static boost::mt19937 sBase;
00199 static boost::variate_generator<boost::mt19937&, boost::uniform_real<float> > sFloatGen;
00200 static boost::variate_generator<boost::mt19937&, boost::uniform_int<> > sIntGen;
00201 };
00202
00203 }