Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

math/random.h

Go to the documentation of this file.
00001 #ifndef MATH_RANDOM_H
00002 #define MATH_RANDOM_H
00003 
00004 /*
00005 
00006   GLT OpenGL C++ Toolkit (LGPL)
00007   Copyright (C) 2000-2002 Nigel Stewart  
00008 
00009   Email: nigels.com@gmail.com   
00010   WWW:   http://www.nigels.com/glt/
00011 
00012   This library is free software; you can redistribute it and/or
00013   modify it under the terms of the GNU Lesser General Public
00014   License as published by the Free Software Foundation; either
00015   version 2.1 of the License, or (at your option) any later version.
00016 
00017   This library is distributed in the hope that it will be useful,
00018   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020   Lesser General Public License for more details.
00021 
00022   You should have received a copy of the GNU Lesser General Public
00023   License along with this library; if not, write to the Free Software
00024   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 */
00027 
00033 #include <iosfwd>
00034 #include <cassert>
00035 #include <cmath>
00036 
00037 #include <glt/config.h>
00038 
00039 #include <math/real.h>
00040 #include <math/vector3.h>
00041 #include <math/matrix4.h>
00042 
00054 class GltRandomLCG 
00055 {
00056 public:
00058     GltRandomLCG(const uint32 seed = 199125);
00060     GltRandomLCG(const GltRandomLCG &rng);
00062     ~GltRandomLCG();
00063 
00065     uint32 rand() const;
00067     uint32 max() const;
00068 
00070     void seed(const uint32 seed = 199125);
00071 
00073     static GltRandomLCG rng;
00074 
00076           GltRandomLCG &base()       { return *this; }
00078     const GltRandomLCG &base() const { return *this; }
00079 
00080 private:
00081     
00082     mutable uint32 _idum;
00083 
00084     const static int32 a;
00085     const static int32 m;
00086     const static int32 q;
00087     const static int32 r;
00088 };
00089 
00111 class GltRandomLFSRMix 
00112 {
00113 public:
00115     GltRandomLFSRMix(const uint32 seed1 = 199125,const uint32 seed2 = 90618,const uint32 seed3 = 189419);
00117     GltRandomLFSRMix(const GltRandomLFSRMix &rng);
00119     ~GltRandomLFSRMix();
00120 
00122     uint32 rand() const;
00124     uint32 max() const;
00125 
00127     static GltRandomLFSRMix rng;
00128 
00130           GltRandomLFSRMix &base()       { return *this; }
00132     const GltRandomLFSRMix &base() const { return *this; }
00133 
00134 private:
00135     
00136     mutable uint32 _regA, _regB, _regC;
00137 };
00138 
00145 template<class R = GltRandomLFSRMix>
00146 class GltRandomDouble
00147 {
00148 public:
00149 
00151     GltRandomDouble(R &random,const double min = 0.0,const double max = 1.0)
00152     : _random(random),
00153       _min(min),
00154       _max(max),
00155       _mult((max-min)/random.max())
00156     {
00157     }
00158 
00160     GltRandomDouble(const double min = 0.0,const double max = 1.0)
00161     : _random(R::rng),
00162       _min(min),
00163       _max(max),
00164       _mult((max-min)/R::rng.max())
00165     {
00166     }
00167 
00169     GltRandomDouble(const GltRandomDouble<R> &gen) 
00170     : _random(gen._random),
00171       _min(gen._min),
00172       _max(gen._max),
00173       _mult(gen._mult)
00174     {
00175     }
00176 
00178     ~GltRandomDouble() 
00179     {
00180     }
00181 
00183     double rand() const 
00184     {
00185         return _min + _mult*double(_random.rand());
00186     }
00187 
00189           R &base()       { return _random; }
00191     const R &base() const { return _random; }
00192     
00193 private:
00194 
00195     R            &_random;
00196     const double  _min;
00197     const double  _max;
00198     const double  _mult;
00199 };
00200 
00207 template<class R = GltRandomLFSRMix>
00208 class GltRandomInteger
00209 {
00210 public:
00211 
00213     GltRandomInteger(R &random,const uint32 min,const uint32 max)
00214     : _random(random),
00215       _min(min),
00216       _max(double(max)+1.0-1.0e-6),
00217       _mult((double(max)+1.0-1.0e-6-double(min))/random.max())
00218     {
00219         assert(min<max);
00220         assert(max<=random.max());
00221     }
00222 
00224     GltRandomInteger(const uint32 min,const uint32 max)
00225     : _random(R::rng),
00226       _min(min),
00227       _max(double(max)+1.0-1.0e-6),
00228       _mult((double(max)+1.0-1.0e-6-double(min))/R::rng.max())
00229     {
00230         assert(min<max);
00231         assert(max<=_random.max());
00232     }
00233 
00235     GltRandomInteger(const GltRandomInteger<R> &gen)
00236     : _random(gen._random),
00237       _min(gen._min),
00238       _max(gen._max),
00239       _mult(gen._mult)
00240     {
00241     }
00242 
00244     ~GltRandomInteger()
00245     {
00246     }
00247 
00249     uint32 rand() const
00250     {
00251         return _min + (uint32) floor(_mult*double(_random.rand()));
00252     }
00253 
00255           R &base()       { return _random; }
00257     const R &base() const { return _random; }
00258 
00259 private:
00260 
00261     R            &_random;
00262     const uint32  _min;
00263     const double  _max;
00264     const double  _mult;
00265 };
00266 
00293 template<class R = GltRandomLFSRMix>
00294 class GltRandomSphere
00295 {
00296 public:
00297 
00299     GltRandomSphere(R &random,const double radius = 1.0)
00300     : _z(random,-1.0,1.0),
00301       _t(random,0,2*M_PI),
00302       _radius(radius)
00303     {
00304     }
00305 
00307     GltRandomSphere(const double radius = 1.0)
00308     : _z(R::rng,-1.0,1.0),
00309       _t(R::rng, 0.0,2*M_PI),
00310       _radius(radius)
00311     {
00312     }
00313 
00315     GltRandomSphere(const GltRandomSphere<R> &gen) 
00316     : _z(gen._z._random),
00317           _t(gen._t._random),
00318       _radius(gen._radius)
00319     {
00320     }
00321 
00323     ~GltRandomSphere() 
00324     {
00325     }
00326 
00328     Vector rand() const
00329     {
00330         const double z = _z.rand();
00331         const double t = _t.rand();
00332         const double r = _radius*sqrt(1.0-z*z);
00333         return Vector(r*cos(t),r*sin(t),_radius*z);
00334     }
00335 
00337           R &base()       { return _z.base(); }
00339     const R &base() const { return _z.base(); }
00340 
00341 private:
00342 
00343     GltRandomDouble<R> _z,_t;
00344     const double    _radius;
00345 };
00346 
00353 template<class R = GltRandomLFSRMix>
00354 class GltRandomOrientation
00355 {
00356 public:
00357 
00359     GltRandomOrientation(R &random)
00360     : _s(random), _a(random,0.0,2*M_PI)
00361     {
00362     }
00363 
00365     GltRandomOrientation()
00366     : _s(R::rng), _a(R::rng,0.0,2*M_PI)
00367     {
00368     }
00369 
00371     GltRandomOrientation(const GltRandomOrientation<R> &gen) 
00372     : _s(gen._s), _a(gen._a)
00373     {
00374     }
00375 
00377     ~GltRandomOrientation() 
00378     {
00379     }
00380 
00382     Matrix rand() const
00383     {
00384         // A is a vector distributed 
00385         // randomly on the unit sphere
00386         
00387         const Vector a(_s.rand());
00388 
00389         // B is orthogonal to A
00390         
00391         Vector b;
00392 
00393         switch (a.dominant())
00394         {
00395         case 0: b = xProduct(a,VectorZ); break; // a in x direction
00396         case 1: b = xProduct(a,VectorZ); break; // a in y direction
00397         case 2: b = xProduct(a,VectorX); break; // a in z direction
00398         }
00399 
00400         // C is orthogonal to both A and B
00401 
00402         Vector c(xProduct(b,a));
00403 
00404         // TODO - Possible to avoid this step?
00405         b.normalize();
00406         c.normalize();
00407 
00408         // Choose an angle in the AB plane
00409 
00410         const real angle = _a.rand();
00411         const real sina  = sin(angle);
00412         const real cosa  = cos(angle);
00413 
00414         return matrixOrient
00415             (
00416                 a,
00417                 sina*b +  cosa*c,
00418                 cosa*b -  sina*c
00419             );
00420     }
00421 
00423           R &base()       { return _s.base(); }
00425     const R &base() const { return _s.base(); }
00426 
00427 private:
00428     GltRandomSphere<R> _s;
00429     GltRandomDouble<R> _a;
00430 };
00431 
00432 #endif 

Generated on Tue Nov 5 11:11:04 2002 for GLT by doxygen1.2.18