00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #pragma once
00026
00027 #include "cinder/Cinder.h"
00028 #include <cmath>
00029 #include <climits>
00030 #if defined( CINDER_MSW )
00031 #undef min
00032 #undef max
00033 #include <float.h>
00034 #endif
00035
00036 namespace cinder {
00037
00038 template<typename T>
00039 struct math
00040 {
00041 static T acos (T x) {return ::acos (double(x));}
00042 static T asin (T x) {return ::asin (double(x));}
00043 static T atan (T x) {return ::atan (double(x));}
00044 static T atan2 (T y, T x) {return ::atan2 (double(y), double(x));}
00045 static T cos (T x) {return ::cos (double(x));}
00046 static T sin (T x) {return ::sin (double(x));}
00047 static T tan (T x) {return ::tan (double(x));}
00048 static T cosh (T x) {return ::cosh (double(x));}
00049 static T sinh (T x) {return ::sinh (double(x));}
00050 static T tanh (T x) {return ::tanh (double(x));}
00051 static T exp (T x) {return ::exp (double(x));}
00052 static T log (T x) {return ::log (double(x));}
00053 static T log10 (T x) {return ::log10 (double(x));}
00054 static T modf (T x, T *iptr)
00055 {
00056 double ival;
00057 T rval( ::modf (double(x),&ival));
00058 *iptr = ival;
00059 return rval;
00060 }
00061 static T pow (T x, T y) {return ::pow (double(x), double(y));}
00062 static T sqrt (T x) {return ::sqrt (double(x));}
00063 #if defined( _MSC_VER )
00064 static T cbrt( T x ) { return ( x > 0 ) ? (::pow( x, 1.0 / 3.0 )) : (- ::pow( -x, 1.0 / 3.0 ) ); }
00065 #else
00066 static T cbrt( T x ) { return ::cbrt( x ); }
00067 #endif
00068 static T ceil (T x) {return ::ceil (double(x));}
00069 static T abs (T x) {return ::fabs (double(x));}
00070 static T floor (T x) {return ::floor (double(x));}
00071 static T fmod (T x, T y) {return ::fmod (double(x), double(y));}
00072 static T hypot (T x, T y) {return ::hypot (double(x), double(y));}
00073 static T signum (T x) {return ( x >0.0 ) ? 1.0 : ( ( x < 0.0 ) ? -1.0 : 0.0 ); }
00074 static T min(T x, T y) {return ( x < y ) ? x : y; }
00075 static T max(T x, T y) {return ( x > y ) ? x : y; }
00076 static T clamp(T x, T min=0, T max=1) {return ( x < min ) ? min : ( ( x > max ) ? max : x );}
00077 };
00078
00079
00080 template<>
00081 struct math<float>
00082 {
00083 static float acos (float x) {return ::acosf (x);}
00084 static float asin (float x) {return ::asinf (x);}
00085 static float atan (float x) {return ::atanf (x);}
00086 static float atan2 (float y, float x) {return ::atan2f (y, x);}
00087 static float cos (float x) {return ::cosf (x);}
00088 static float sin (float x) {return ::sinf (x);}
00089 static float tan (float x) {return ::tanf (x);}
00090 static float cosh (float x) {return ::coshf (x);}
00091 static float sinh (float x) {return ::sinhf (x);}
00092 static float tanh (float x) {return ::tanhf (x);}
00093 static float exp (float x) {return ::expf (x);}
00094 static float log (float x) {return ::logf (x);}
00095 static float log10 (float x) {return ::log10f (x);}
00096 static float modf (float x, float *y) {return ::modff (x, y);}
00097 static float pow (float x, float y) {return ::powf (x, y);}
00098 static float sqrt (float x) {return ::sqrtf (x);}
00099 #if defined( _MSC_VER )
00100 static float cbrt( float x ) { return ( x > 0 ) ? (::powf( x, 1.0f / 3.0f )) : (- ::powf( -x, 1.0f / 3.0f ) ); }
00101 #else
00102 static float cbrt (float x) { return ::cbrtf( x ); }
00103 #endif
00104 static float ceil (float x) {return ::ceilf (x);}
00105 static float abs (float x) {return ::fabsf (x);}
00106 static float floor (float x) {return ::floorf (x);}
00107 static float fmod (float x, float y) {return ::fmodf (x, y);}
00108 #if !defined(_MSC_VER)
00109 static float hypot (float x, float y) {return ::hypotf (x, y);}
00110 #else
00111 static float hypot (float x, float y) {return ::sqrtf(x*x + y*y);}
00112 #endif
00113 static float signum (float x) {return ( x > 0.0f ) ? 1.0f : ( ( x < 0.0f ) ? -1.0f : 0.0f ); }
00114 static float min(float x, float y) {return ( x < y ) ? x : y; }
00115 static float max(float x, float y) {return ( x > y ) ? x : y; }
00116 static float clamp(float x, float min=0, float max=1) {return ( x < min ) ? min : ( ( x > max ) ? max : x );}
00117 };
00118
00119 #ifndef M_PI
00120 #define M_PI 3.14159265358979323846
00121 #endif
00122
00123 const double EPSILON_VALUE = 4.37114e-05;
00124 #define EPSILON EPSILON_VALUE
00125
00126 inline float toRadians( float x )
00127 {
00128 return x * 0.017453292519943295769f;
00129 }
00130
00131 inline double toRadians( double x )
00132 {
00133 return x * 0.017453292519943295769;
00134 }
00135
00136 inline float toDegrees( float x )
00137 {
00138 return x * 57.295779513082321f;
00139 }
00140
00141 inline double toDegrees( double x )
00142 {
00143 return x * 57.295779513082321;
00144 }
00145
00146 template<typename T, typename L>
00147 T lerp( const T &a, const T &b, L factor )
00148 {
00149 return a + ( b - a ) * factor;
00150 }
00151
00152 template<typename T>
00153 T lmap(T val, T inMin, T inMax, T outMin, T outMax)
00154 {
00155 return outMin + (outMax - outMin) * ((val - inMin) / (inMax - inMin));
00156 }
00157
00158 template<typename T, typename L>
00159 T bezierInterp( T a, T b, T c, T d, L t)
00160 {
00161 L t1 = static_cast<L>(1.0) - t;
00162 return a*(t1*t1*t1) + b*(3*t*t1*t1) + c*(3*t*t*t1) + d*(t*t*t);
00163 }
00164
00165 template<typename T, typename L>
00166 T bezierInterpRef( const T &a, const T &b, const T &c, const T &d, L t)
00167 {
00168 L t1 = static_cast<L>(1.0) - t;
00169 return a*(t1*t1*t1) + b*(3*t*t1*t1) + c*(3*t*t*t1) + d*(t*t*t);
00170 }
00171
00172 template<typename T>
00173 T constrain( T val, T minVal, T maxVal )
00174 {
00175 if( val < minVal ) return minVal;
00176 else if( val > maxVal ) return maxVal;
00177 else return val;
00178 }
00179
00180
00181
00182 template <class T>
00183 T sinx_over_x( T x )
00184 {
00185 if( x * x < 1.19209290E-07F )
00186 return T( 1 );
00187 else
00188 return math<T>::sin( x ) / x;
00189 }
00190
00191
00192 inline uint32_t log2floor( uint32_t x )
00193 {
00194 uint32_t result = 0;
00195 while( x >>= 1 )
00196 ++result;
00197
00198 return result;
00199 }
00200
00201 inline uint32_t log2ceil( uint32_t x )
00202 {
00203 uint32_t isNotPowerOf2 = (x & (x - 1));
00204 return ( isNotPowerOf2 ) ? (log2floor( x ) + 1) : log2floor( x );
00205 }
00206
00207 inline uint32_t nextPowerOf2( uint32_t x )
00208 {
00209 x |= (x >> 1);
00210 x |= (x >> 2);
00211 x |= (x >> 4);
00212 x |= (x >> 8);
00213 x |= (x >> 16);
00214 return(x+1);
00215 }
00216
00217 template<typename T>
00218 inline int solveLinear( T a, T b, T result[1] )
00219 {
00220 if( a == 0 ) return (b == 0 ? -1 : 0 );
00221 result[0] = -b / a;
00222 return 1;
00223 }
00224
00225 template<typename T>
00226 inline int solveQuadratic( T a, T b, T c, T result[2] )
00227 {
00228 if( a == 0 ) return solveLinear( b, c, result );
00229
00230 T radical = b * b - 4 * a * c;
00231 if( radical < 0 ) return 0;
00232
00233 if( radical == 0 ) {
00234 result[0] = -b / (2 * a);
00235 return 1;
00236 }
00237
00238 T srad = math<T>::sqrt( radical );
00239 result[0] = ( -b - srad ) / (2 * a);
00240 result[1] = ( -b + srad ) / (2 * a);
00241 if( a < 0 ) std::swap( result[0], result[1] );
00242 return 2;
00243 }
00244
00245 template<typename T>
00246 int solveCubic( T a, T b, T c, T d, T result[3] );
00247
00248 }
00249
00250 #if defined( _MSC_VER )
00251 namespace std {
00252 inline bool isfinite( float arg ) { return _finite( arg ) != 0; }
00253 inline bool isfinite( double arg ) { return _finite( arg ) != 0; }
00254 }
00255 #endif