# 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