Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

include/cinder/CinderMath.h

Go to the documentation of this file.
00001 /*
00002  Copyright (c) 2010, The Barbarian Group
00003  All rights reserved.
00004 
00005  Redistribution and use in source and binary forms, with or without modification, are permitted provided that
00006  the following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and
00009     the following disclaimer.
00010     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
00011     the following disclaimer in the documentation and/or other materials provided with the distribution.
00012 
00013  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00014  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00015  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
00016  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00017  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00018  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00019  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00020  POSSIBILITY OF SUCH DAMAGE.
00021 */
00022 
00023 #pragma once
00024 
00025 #include "cinder/Cinder.h"
00026 #include <math.h>
00027 #include <limits.h>
00028 #if defined( CINDER_MSW )
00029 #undef min
00030 #undef max
00031 #endif
00032 
00033 namespace cinder { 
00034 
00035 template<typename T>
00036 struct math
00037 {
00038     static T    acos  (T x)     {return ::acos (double(x));}    
00039     static T    asin  (T x)     {return ::asin (double(x));}
00040     static T    atan  (T x)     {return ::atan (double(x));}
00041     static T    atan2 (T x, T y)    {return ::atan2 (double(x), double(y));}
00042     static T    cos   (T x)     {return ::cos (double(x));}
00043     static T    sin   (T x)     {return ::sin (double(x));}
00044     static T    tan   (T x)     {return ::tan (double(x));}
00045     static T    cosh  (T x)     {return ::cosh (double(x));}
00046     static T    sinh  (T x)     {return ::sinh (double(x));}
00047     static T    tanh  (T x)     {return ::tanh (double(x));}
00048     static T    exp   (T x)     {return ::exp (double(x));}
00049     static T    log   (T x)     {return ::log (double(x));}
00050     static T    log10 (T x)     {return ::log10 (double(x));}
00051     static T    modf  (T x, T *iptr)
00052     {
00053         double ival;
00054         T rval( ::modf (double(x),&ival));
00055     *iptr = ival;
00056     return rval;
00057     }
00058     static T    pow   (T x, T y)    {return ::pow (double(x), double(y));}
00059     static T    sqrt  (T x)     {return ::sqrt (double(x));}
00060     static T    ceil  (T x)     {return ::ceil (double(x));}
00061     static T    abs  (T x)      {return ::fabs (double(x));}
00062     static T    floor (T x)     {return ::floor (double(x));}
00063     static T    fmod  (T x, T y)    {return ::fmod (double(x), double(y));}
00064     static T    hypot (T x, T y)    {return ::hypot (double(x), double(y));}
00065     static T    signum (T x)        {return ( x >0.0 ) ? 1.0 : ( ( x < 0.0 ) ? -1.0 : 0.0 ); }
00066     static T    min(T x, T y)               {return ( x < y ) ? x : y; }
00067     static T    max(T x, T y)               {return ( x > y ) ? x : y; }
00068     static T    clamp(T x, T min=0, T max=1)    {return ( x < min ) ? min : ( ( x > max ) ? max : x );}
00069 };
00070 
00071 
00072 template<>
00073 struct math<float>
00074 {
00075     static float    acos  (float x)         {return ::acosf (x);}   
00076     static float    asin  (float x)         {return ::asinf (x);}
00077     static float    atan  (float x)         {return ::atanf (x);}
00078     static float    atan2 (float x, float y)    {return ::atan2f (x, y);}
00079     static float    cos   (float x)         {return ::cosf (x);}
00080     static float    sin   (float x)         {return ::sinf (x);}
00081     static float    tan   (float x)         {return ::tanf (x);}
00082     static float    cosh  (float x)         {return ::coshf (x);}
00083     static float    sinh  (float x)         {return ::sinhf (x);}
00084     static float    tanh  (float x)         {return ::tanhf (x);}
00085     static float    exp   (float x)         {return ::expf (x);}
00086     static float    log   (float x)         {return ::logf (x);}
00087     static float    log10 (float x)         {return ::log10f (x);}
00088     static float    modf  (float x, float *y)   {return ::modff (x, y);}
00089     static float    pow   (float x, float y)    {return ::powf (x, y);}
00090     static float    sqrt  (float x)         {return ::sqrtf (x);}
00091     static float    ceil  (float x)         {return ::ceilf (x);}
00092     static float    abs  (float x)          {return ::fabsf (x);}
00093     static float    floor (float x)         {return ::floorf (x);}
00094     static float    fmod  (float x, float y)    {return ::fmodf (x, y);}
00095     #if !defined(_MSC_VER)
00096     static float    hypot (float x, float y)    {return ::hypotf (x, y);}
00097     #else
00098     static float hypot (float x, float y)   {return ::sqrtf(x*x + y*y);}
00099     #endif
00100     static float signum (float x)       {return ( x > 0.0f ) ? 1.0f : ( ( x < 0.0f ) ? -1.0f : 0.0f ); }
00101     static float min(float x, float y)                  {return ( x < y ) ? x : y; }
00102     static float max(float x, float y)                  {return ( x > y ) ? x : y; }
00103     static float clamp(float x, float min=0, float max=1)   {return ( x < min ) ? min : ( ( x > max ) ? max : x );}
00104 };
00105 
00106 #ifndef M_PI
00107  #define M_PI           3.14159265358979323846 
00108 #endif
00109 
00110 const double EPSILON_VALUE = 4.37114e-05;
00111 #define EPSILON EPSILON_VALUE
00112 
00113 static float toRadians( float x )
00114 {
00115     return x * 0.017453292519943295769f; // ( x * PI / 180 )
00116 }
00117 
00118 static double toRadians( double x )
00119 {
00120     return x * 0.017453292519943295769; // ( x * PI / 180 )
00121 }
00122 
00123 static float toDegrees( float x )
00124 {
00125     return x * 57.295779513082321f; // ( x * 180 / PI )
00126 }
00127 
00128 static double toDegrees( double x )
00129 {
00130     return x * 57.295779513082321; // ( x * 180 / PI )
00131 }
00132 
00133 template<typename T, typename L>
00134 T lerp( const T &a, const T &b, L factor )
00135 {
00136     return a + ( b - a ) * factor;
00137 }
00138 
00139 template<typename T, typename L>
00140 T bezierInterp( T a, T b, T c, T d, L t)
00141 {
00142     L t1 = static_cast<L>(1.0) - t;
00143     return a*(t1*t1*t1) + b*(3*t*t1*t1) + c*(3*t*t*t1) + d*(t*t*t);
00144 }
00145 
00146 template<typename T, typename L>
00147 T bezierInterpRef( const T &a, const T &b, const T &c, const T &d, L t)
00148 {
00149     L t1 = static_cast<L>(1.0) - t;
00150     return a*(t1*t1*t1) + b*(3*t*t1*t1) + c*(3*t*t*t1) + d*(t*t*t);
00151 }
00152 
00153 template<typename T>
00154 T constrain( T val, T minVal, T maxVal )
00155 {
00156     if( val < minVal ) return minVal;
00157     else if( val > maxVal ) return maxVal;
00158     else return val;
00159 }
00160 
00161 // Don Hatch's version of sin(x)/x, which is accurate for very small x.
00162 // Returns 1 for x == 0.
00163 template <class T>
00164 T sinx_over_x( T x )
00165 {
00166     if( x * x < 1.19209290E-07F )
00167     return T( 1 );
00168     else
00169     return math<T>::sin( x ) / x;
00170 }
00171 
00172 // There are faster techniques for this, but this is portable
00173 inline uint32_t log2floor( uint32_t x )
00174 {
00175     uint32_t result = 0;
00176     while( x >>= 1 )
00177         ++result;
00178     
00179     return result;
00180 }
00181 
00182 inline uint32_t log2ceil( uint32_t x )
00183 {
00184     uint32_t isNotPowerOf2 = (x & (x - 1));
00185     return ( isNotPowerOf2 ) ? (log2floor( x ) + 1) : log2floor( x );
00186 }
00187 
00188 inline uint32_t nextPowerOf2( uint32_t x )
00189 {
00190     x |= (x >> 1);
00191     x |= (x >> 2);
00192     x |= (x >> 4);
00193     x |= (x >> 8);
00194     x |= (x >> 16);
00195     return(x+1);
00196 }
00197 
00198 } // namespace cinder