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