00001 /* 00002 Copyright (c) 2010, The Barbarian Group 00003 All rights reserved. 00004 00005 Portions Copyright (c) 2004, Laminar Research. 00006 00007 Redistribution and use in source and binary forms, with or without modification, are permitted provided that 00008 the following conditions are met: 00009 00010 * Redistributions of source code must retain the above copyright notice, this list of conditions and 00011 the following disclaimer. 00012 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 00013 the following disclaimer in the documentation and/or other materials provided with the distribution. 00014 00015 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 00016 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00017 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00018 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00019 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00020 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00021 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00022 POSSIBILITY OF SUCH DAMAGE. 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; // ( x * PI / 180 ) 00128 } 00129 00130 inline double toRadians( double x ) 00131 { 00132 return x * 0.017453292519943295769; // ( x * PI / 180 ) 00133 } 00134 00135 inline float toDegrees( float x ) 00136 { 00137 return x * 57.295779513082321f; // ( x * 180 / PI ) 00138 } 00139 00140 inline double toDegrees( double x ) 00141 { 00142 return x * 57.295779513082321; // ( x * 180 / PI ) 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 // Don Hatch's version of sin(x)/x, which is accurate for very small x. 00180 // Returns 1 for x == 0. 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 // There are faster techniques for this, but this is portable 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 } // namespace cinder