Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

Math.h

Go to the documentation of this file.
00001 /************************************************************** ggt-head beg
00002  *
00003  * GGT: Generic Graphics Toolkit
00004  *
00005  * Original Authors:
00006  *   Allen Bierbaum
00007  *
00008  * -----------------------------------------------------------------
00009  * File:          $RCSfile: Math.h,v $
00010  * Date modified: $Date: 2003/02/23 06:53:52 $
00011  * Version:       $Revision: 1.35 $
00012  * -----------------------------------------------------------------
00013  *
00014  *********************************************************** ggt-head end */
00015 /*************************************************************** ggt-cpr beg
00016 *
00017 * GGT: The Generic Graphics Toolkit
00018 * Copyright (C) 2001,2002 Allen Bierbaum
00019 *
00020 * This library is free software; you can redistribute it and/or
00021 * modify it under the terms of the GNU Lesser General Public
00022 * License as published by the Free Software Foundation; either
00023 * version 2.1 of the License, or (at your option) any later version.
00024 *
00025 * This library is distributed in the hope that it will be useful,
00026 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00028 * Lesser General Public License for more details.
00029 *
00030 * You should have received a copy of the GNU Lesser General Public
00031 * License along with this library; if not, write to the Free Software
00032 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00033 *
00034  ************************************************************ ggt-cpr end */
00035 #ifndef _GMTL_MATH_H_
00036 #define _GMTL_MATH_H_
00037 
00038 #include <math.h>
00039 #include <stdlib.h>
00040 #include <gmtl/Defines.h>
00041 #include <gmtl/Util/Assert.h>
00042 
00043 namespace gmtl
00044 {
00045 
00050 struct RotationOrderBase { enum { IS_ROTORDER = 1 }; };
00051 
00054 struct XYZ : public RotationOrderBase { enum { ID = 0 }; };
00055 
00058 struct ZYX : public RotationOrderBase { enum { ID = 1 }; };
00059 
00062 struct ZXY : public RotationOrderBase { enum { ID = 2 }; };
00063 
00064 namespace Math
00065 {
00070    const float PI = 3.14159265358979323846f; //3.14159265358979323846264338327950288419716939937510;
00071    const float PI_OVER_2 = 1.57079632679489661923f;
00072    const float PI_OVER_4 = 0.78539816339744830962f;
00079 //----------------------------------------------------------------------------
00080 template <typename T>
00081 inline T abs( T iValue )
00082 {
00083     return T( iValue >= ((T)0) ? iValue : -iValue );
00084 }
00085 //----------------------------------------------------------------------------
00086 template <typename T>
00087 inline T ceil( T fValue );
00088 inline float ceil( float fValue )
00089 {
00090 #ifdef NO_CEILF
00091    return float(::ceil(fValue));
00092 #else
00093    return float( ::ceilf( fValue ) );
00094 #endif
00095 }
00096 inline double ceil( double fValue )
00097 {
00098     return double( ::ceil( fValue ) );
00099 }
00100 //----------------------------------------------------------------------------
00101 template <typename T>
00102 inline T floor( T fValue ); // why do a floor of int?  shouldn't compile...
00103 inline float floor( float fValue )
00104 {
00105 #ifdef NO_FLOORF
00106    return float(::floor(fValue));
00107 #else
00108    return float( ::floorf( fValue ) );
00109 #endif
00110 }
00111 inline double floor( double fValue )
00112 {
00113     return double( ::floor( fValue ) );
00114 }
00115 //----------------------------------------------------------------------------
00116 template <typename T>
00117 inline int sign( T iValue )
00118 {
00119    if (iValue > T(0))
00120    {
00121       return 1;
00122    }
00123    else
00124    {
00125       if (iValue < T(0))
00126       {
00127          return -1;
00128       }
00129       else
00130       {
00131          return 0;
00132       }
00133    }
00134 }
00135 //----------------------------------------------------------------------------
00144 template <typename T>
00145 inline T zeroClamp( T value, T eps = T(0) )
00146 {
00147    return ( (gmtl::Math::abs(value) <= eps) ? T(0) : value );
00148 }
00149 
00150 //----------------------------------------------------------------------------
00151 // don't allow non-float types, because their ret val wont be correct
00152 // i.e. with int, the int retval will be rounded up or down.
00153 //      we'd need a float retval to do it right, but we can't specialize by ret
00154 template <typename T>
00155 inline T aCos( T fValue );
00156 inline float aCos( float fValue )
00157 {
00158     if ( -1.0f < fValue )
00159     {
00160         if ( fValue < 1.0f )
00161         {
00162 #ifdef NO_ACOSF
00163             return float(::acos(fValue));
00164 #else
00165             return float( ::acosf( fValue ) );
00166 #endif
00167         }
00168         else
00169             return 0.0f;
00170     }
00171     else
00172     {
00173         return (float)gmtl::Math::PI;
00174     }
00175 }
00176 inline double aCos( double fValue )
00177 {
00178     if ( -1.0 < fValue )
00179     {
00180         if ( fValue < 1.0 )
00181             return double( ::acos( fValue ) );
00182         else
00183             return 0.0;
00184     }
00185     else
00186     {
00187         return (double)gmtl::Math::PI;
00188     }
00189 }
00190 //----------------------------------------------------------------------------
00191 template <typename T>
00192 inline T aSin( T fValue );
00193 inline float aSin( float fValue )
00194 {
00195     if ( -1.0f < fValue )
00196     {
00197         if ( fValue < 1.0f )
00198         {
00199 #ifdef NO_ASINF
00200             return float(::asin(fValue));
00201 #else
00202             return float( ::asinf( fValue ) );
00203 #endif
00204         }
00205         else
00206             return (float)-gmtl::Math::PI_OVER_2;
00207     }
00208     else
00209     {
00210         return (float)gmtl::Math::PI_OVER_2;
00211     }
00212 }
00213 inline double aSin( double fValue )
00214 {
00215     if ( -1.0 < fValue )
00216     {
00217         if ( fValue < 1.0 )
00218             return double( ::asin( fValue ) );
00219         else
00220             return (double)-gmtl::Math::PI_OVER_2;
00221     }
00222     else
00223     {
00224         return (double)gmtl::Math::PI_OVER_2;
00225     }
00226 }
00227 //----------------------------------------------------------------------------
00228 template <typename T>
00229 inline T aTan( T fValue );
00230 inline double aTan( double fValue )
00231 {
00232     return ::atan( fValue );
00233 }
00234 inline float aTan( float fValue )
00235 {
00236 #ifdef NO_TANF
00237    return float(::atan(fValue));
00238 #else
00239    return float( ::atanf( fValue ) );
00240 #endif
00241 }
00242 //----------------------------------------------------------------------------
00243 template <typename T>
00244 inline T atan2( T fY, T fX );
00245 inline float aTan2( float fY, float fX )
00246 {
00247 #ifdef NO_ATAN2F
00248    return float(::atan2(fY, fX));
00249 #else
00250    return float( ::atan2f( fY, fX ) );
00251 #endif
00252 }
00253 inline double aTan2( double fY, double fX )
00254 {
00255     return double( ::atan2( fY, fX ) );
00256 }
00257 //----------------------------------------------------------------------------
00258 template <typename T>
00259 inline T cos( T fValue );
00260 inline float cos( float fValue )
00261 {
00262 #ifdef NO_COSF
00263    return float(::cos(fValue));
00264 #else
00265    return float( ::cosf( fValue ) );
00266 #endif
00267 }
00268 inline double cos( double fValue )
00269 {
00270     return double( ::cos( fValue ) );
00271 }
00272 //----------------------------------------------------------------------------
00273 template <typename T>
00274 inline T exp( T fValue );
00275 inline float exp( float fValue )
00276 {
00277 #ifdef NO_EXPF
00278    return float(::exp(fValue));
00279 #else
00280    return float( ::expf( fValue ) );
00281 #endif
00282 }
00283 inline double exp( double fValue )
00284 {
00285     return double( ::exp( fValue ) );
00286 }
00287 //----------------------------------------------------------------------------
00288 template <typename T>
00289 inline T log( T fValue );
00290 inline double log( double fValue )
00291 {
00292     return double( ::log( fValue ) );
00293 }
00294 inline float log( float fValue )
00295 {
00296 #ifdef NO_LOGF
00297    return float(::log(fValue));
00298 #else
00299    return float( ::logf( fValue ) );
00300 #endif
00301 }
00302 //----------------------------------------------------------------------------
00303 inline double pow( double fBase, double fExponent)
00304 {
00305     return double( ::pow( fBase, fExponent ) );
00306 }
00307 inline float pow( float fBase, float fExponent)
00308 {
00309 #ifdef NO_POWF
00310    return float(::pow(fBase, fExponent));
00311 #else
00312    return float( ::powf( fBase, fExponent ) );
00313 #endif
00314 }
00315 //----------------------------------------------------------------------------
00316 template <typename T>
00317 inline T sin( T fValue );
00318 inline double sin( double fValue )
00319 {
00320     return double( ::sin( fValue ) );
00321 }
00322 inline float sin( float fValue )
00323 {
00324 #ifdef NO_SINF
00325    return float(::sin(fValue));
00326 #else
00327    return float( ::sinf( fValue ) );
00328 #endif
00329 }
00330 //----------------------------------------------------------------------------
00331 template <typename T>
00332 inline T tan( T fValue );
00333 inline double tan( double fValue )
00334 {
00335     return double( ::tan( fValue ) );
00336 }
00337 inline float tan( float fValue )
00338 {
00339 #ifdef NO_TANF
00340    return float(::tan(fValue));
00341 #else
00342    return float( ::tanf( fValue ) );
00343 #endif
00344 }
00345 //----------------------------------------------------------------------------
00346 template <typename T>
00347 inline T sqr( T fValue )
00348 {
00349     return T( fValue * fValue );
00350 }
00351 //----------------------------------------------------------------------------
00352 template <typename T>
00353 inline T sqrt( T fValue )
00354 {
00355 #ifdef NO_SQRTF
00356    return T(::sqrt(((float)fValue)));
00357 #else
00358    return T( ::sqrtf( ((float)fValue) ) );
00359 #endif
00360 }
00361 inline double sqrt( double fValue )
00362 {
00363     return double( ::sqrt( fValue ) );
00364 }
00365 
00366 //----------------------------------------------------------------------------
00372 inline void seedRandom(unsigned int seed)
00373 {
00374    ::srand(seed);
00375 }
00376 
00380 inline float unitRandom()
00381 {
00382    return float(::rand())/float(RAND_MAX);
00383 }
00384 
00388 inline float rangeRandom( float x1, float x2 )
00389 {
00390    float r = gmtl::Math::unitRandom();
00391    float size = x2 - x1;
00392    return float( r * size + x1 );
00393 }
00394 
00395 /*
00396 float SymmetricRandom ()
00397 {
00398     return 2.0*float(rand())/float(RAND_MAX) - 1.0;
00399 }
00400 */
00401 //----------------------------------------------------------------------------
00402 
00403 inline float deg2Rad( float fVal )
00404 {
00405    return float( fVal * (float)(gmtl::Math::PI/180.0) );
00406 }
00407 inline double deg2Rad( double fVal )
00408 {
00409    return double( fVal * (double)(gmtl::Math::PI/180.0) );
00410 }
00411 
00412 inline float rad2Deg( float fVal )
00413 {
00414    return float( fVal * (float)(180.0/gmtl::Math::PI) );
00415 }
00416 inline double rad2Deg( double fVal )
00417 {
00418    return double( fVal * (double)(180.0/gmtl::Math::PI) );
00419 }
00420 //----------------------------------------------------------------------------
00421 
00426 template <class T>
00427 inline bool isEqual( const T& a, const T& b, const T& tolerance )
00428 {
00429    gmtlASSERT( tolerance >= (T)0 );
00430    return bool( gmtl::Math::abs( a - b ) <= tolerance );
00431 }
00432 //----------------------------------------------------------------------------
00434 template <class T>
00435 inline T trunc( T val )
00436 {
00437    return T( (val < ((T)0)) ? gmtl::Math::ceil( val ) : gmtl::Math::floor( val ) );
00438 }
00440 template <class T>
00441 inline T round( T p )
00442 {
00443    return T( gmtl::Math::floor( p + (T)0.5 ) );
00444 }
00445 //----------------------------------------------------------------------------
00447 template <class T>
00448 inline T Min( const T& x, const T& y )
00449 {
00450    return ( x > y ) ? y : x;
00451 }
00453 template <class T>
00454 inline T Min( const T& x, const T& y, const T& z )
00455 {
00456    return Min( gmtl::Math::Min( x, y ), z );
00457 }
00459 template <class T>
00460 inline T Min( const T& w, const T& x, const T& y, const T& z )
00461 {
00462    return gmtl::Math::Min( gmtl::Math::Min( w, x ), gmtl::Math::Min( y, z ) );
00463 }
00464 
00466 template <class T>
00467 inline T Max( const T& x, const T& y )
00468 {
00469    return ( x > y ) ? x : y;
00470 }
00472 template <class T>
00473 inline T Max( const T& x, const T& y, const T& z )
00474 {
00475    return Max( gmtl::Math::Max( x, y ), z );
00476 }
00478 template <class T>
00479 inline T Max( const T& w, const T& x, const T& y, const T& z )
00480 {
00481    return gmtl::Math::Max( gmtl::Math::Max( w, x ), gmtl::Math::Max( y, z ) );
00482 }
00483 //----------------------------------------------------------------------------
00489 template<class T>
00490 inline T factorial(T rhs)
00491 {
00492    T lhs = (T)1;
00493 
00494    for( T x = (T)1; x <= rhs; ++x )
00495    {
00496       lhs *= x;
00497    }
00498 
00499    return lhs;
00500 }
00506 template <class T>
00507 inline T clamp( T number, T lo, T hi )
00508 {
00509    if (number > hi) number = hi;
00510    else if (number < lo) number = lo;
00511    return number;
00512 }
00513 
00522 template <class T, typename U>
00523 inline void lerp( T& result, const U& lerp, const T& a, const T& b )
00524 {
00525     T size = b - a;
00526     result = ((U)a) + (((U)size) * lerp);
00527 }
00542 template <class T>
00543 inline bool quadraticFormula(T& r1, T& r2, const T& a, const T& b, const T& c)
00544 {
00545    const T q = b*b - T(4)*a*c;
00546 
00547    // the result has real roots
00548    if (q >= 0)
00549    {
00550       const T sq = gmtl::Math::sqrt(q);
00551       const T d = T(1) / (T(2) * a);
00552       r1 = (-b + sq) * d;
00553       r2 = (-b - sq) * d;
00554       return true;
00555    }
00556    // the result has complex roots
00557    else
00558    {
00559       return false;
00560    }
00561 }
00562 
00563 } // end namespace Math
00564 } // end namespace gmtl
00565 
00566 #endif

Generated on Mon Apr 7 15:28:54 2003 for GenericMathTemplateLibrary by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002