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 inline float toRadians( float x ) 00114 { 00115 return x * 0.017453292519943295769f; // ( x * PI / 180 ) 00116 } 00117 00118 inline double toRadians( double x ) 00119 { 00120 return x * 0.017453292519943295769; // ( x * PI / 180 ) 00121 } 00122 00123 inline float toDegrees( float x ) 00124 { 00125 return x * 57.295779513082321f; // ( x * 180 / PI ) 00126 } 00127 00128 inline 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