Cinder  0.8.6
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CinderMath.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2010, The Barbarian Group
3  All rights reserved.
4 
5  Portions Copyright (c) 2004, Laminar Research.
6 
7  Redistribution and use in source and binary forms, with or without modification, are permitted provided that
8  the following conditions are met:
9 
10  * Redistributions of source code must retain the above copyright notice, this list of conditions and
11  the following disclaimer.
12  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
13  the following disclaimer in the documentation and/or other materials provided with the distribution.
14 
15  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
16  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
17  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
18  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
19  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
22  POSSIBILITY OF SUCH DAMAGE.
23 */
24 
25 #pragma once
26 
27 #include "cinder/Cinder.h"
28 #include <cmath>
29 #include <climits>
30 #include <cfloat>
31 #include <functional>
32 #if defined( CINDER_MSW ) || defined( CINDER_WINRT )
33  #undef min
34  #undef max
35 #endif
36 
37 namespace cinder {
38 
39 template<typename T>
40 struct math
41 {
42  static T acos (T x) {return ::acos (double(x));}
43  static T asin (T x) {return ::asin (double(x));}
44  static T atan (T x) {return ::atan (double(x));}
45  static T atan2 (T y, T x) {return ::atan2 (double(y), double(x));}
46  static T cos (T x) {return ::cos (double(x));}
47  static T sin (T x) {return ::sin (double(x));}
48  static T tan (T x) {return ::tan (double(x));}
49  static T cosh (T x) {return ::cosh (double(x));}
50  static T sinh (T x) {return ::sinh (double(x));}
51  static T tanh (T x) {return ::tanh (double(x));}
52  static T exp (T x) {return ::exp (double(x));}
53  static T log (T x) {return ::log (double(x));}
54  static T log10 (T x) {return ::log10 (double(x));}
55  static T modf (T x, T *iptr)
56  {
57  double ival;
58  T rval( ::modf (double(x),&ival));
59  *iptr = ival;
60  return rval;
61  }
62  static T pow (T x, T y) {return ::pow (double(x), double(y));}
63  static T sqrt (T x) {return ::sqrt (double(x));}
64 #if defined( _MSC_VER )
65  static T cbrt( T x ) { return ( x > 0 ) ? (::pow( x, 1.0 / 3.0 )) : (- ::pow( -x, 1.0 / 3.0 ) ); }
66 #else
67  static T cbrt( T x ) { return ::cbrt( x ); }
68 #endif
69  static T ceil (T x) {return ::ceil (double(x));}
70  static T abs (T x) {return ::fabs (double(x));}
71  static T floor (T x) {return ::floor (double(x));}
72  static T fmod (T x, T y) {return ::fmod (double(x), double(y));}
73  static T hypot (T x, T y) {return ::hypot (double(x), double(y));}
74  static T signum (T x) {return ( x >0.0 ) ? 1.0 : ( ( x < 0.0 ) ? -1.0 : 0.0 ); }
75  static T min(T x, T y) {return ( x < y ) ? x : y; }
76  static T max(T x, T y) {return ( x > y ) ? x : y; }
77  static T clamp(T x, T min=0, T max=1) {return ( x < min ) ? min : ( ( x > max ) ? max : x );}
78 };
79 
80 
81 template<>
82 struct math<float>
83 {
84  static float acos (float x) {return ::acosf (x);}
85  static float asin (float x) {return ::asinf (x);}
86  static float atan (float x) {return ::atanf (x);}
87  static float atan2 (float y, float x) {return ::atan2f (y, x);}
88  static float cos (float x) {return ::cosf (x);}
89  static float sin (float x) {return ::sinf (x);}
90  static float tan (float x) {return ::tanf (x);}
91  static float cosh (float x) {return ::coshf (x);}
92  static float sinh (float x) {return ::sinhf (x);}
93  static float tanh (float x) {return ::tanhf (x);}
94  static float exp (float x) {return ::expf (x);}
95  static float log (float x) {return ::logf (x);}
96  static float log10 (float x) {return ::log10f (x);}
97  static float modf (float x, float *y) {return ::modff (x, y);}
98  static float pow (float x, float y) {return ::powf (x, y);}
99  static float sqrt (float x) {return ::sqrtf (x);}
100 #if defined( _MSC_VER )
101  static float cbrt( float x ) { return ( x > 0 ) ? (::powf( x, 1.0f / 3.0f )) : (- ::powf( -x, 1.0f / 3.0f ) ); }
102 #else
103  static float cbrt (float x) { return ::cbrtf( x ); }
104 #endif
105  static float ceil (float x) {return ::ceilf (x);}
106  static float abs (float x) {return ::fabsf (x);}
107  static float floor (float x) {return ::floorf (x);}
108  static float fmod (float x, float y) {return ::fmodf (x, y);}
109  #if !defined(_MSC_VER)
110  static float hypot (float x, float y) {return ::hypotf (x, y);}
111  #else
112  static float hypot (float x, float y) {return ::sqrtf(x*x + y*y);}
113  #endif
114  static float signum (float x) {return ( x > 0.0f ) ? 1.0f : ( ( x < 0.0f ) ? -1.0f : 0.0f ); }
115  static float min(float x, float y) {return ( x < y ) ? x : y; }
116  static float max(float x, float y) {return ( x > y ) ? x : y; }
117  static float clamp(float x, float min=0, float max=1) {return ( x < min ) ? min : ( ( x > max ) ? max : x );}
118 };
119 
120 #ifndef M_PI
121 #define M_PI 3.14159265358979323846
122 #endif
123 
124 const double EPSILON_VALUE = 4.37114e-05;
125 #define EPSILON EPSILON_VALUE
126 
127 inline float toRadians( float x )
128 {
129  return x * 0.017453292519943295769f; // ( x * PI / 180 )
130 }
131 
132 inline double toRadians( double x )
133 {
134  return x * 0.017453292519943295769; // ( x * PI / 180 )
135 }
136 
137 inline float toDegrees( float x )
138 {
139  return x * 57.295779513082321f; // ( x * 180 / PI )
140 }
141 
142 inline double toDegrees( double x )
143 {
144  return x * 57.295779513082321; // ( x * 180 / PI )
145 }
146 
147 template<typename T, typename L>
148 T lerp( const T &a, const T &b, L factor )
149 {
150  return a + ( b - a ) * factor;
151 }
152 
153 template<typename T>
154 T lmap(T val, T inMin, T inMax, T outMin, T outMax)
155 {
156  return outMin + (outMax - outMin) * ((val - inMin) / (inMax - inMin));
157 }
158 
159 template<typename T, typename L>
160 T bezierInterp( T a, T b, T c, T d, L t)
161 {
162  L t1 = static_cast<L>(1.0) - t;
163  return a*(t1*t1*t1) + b*(3*t*t1*t1) + c*(3*t*t*t1) + d*(t*t*t);
164 }
165 
166 template<typename T, typename L>
167 T bezierInterpRef( const T &a, const T &b, const T &c, const T &d, L t)
168 {
169  L t1 = static_cast<L>(1.0) - t;
170  return a*(t1*t1*t1) + b*(3*t*t1*t1) + c*(3*t*t*t1) + d*(t*t*t);
171 }
172 
173 template<typename T>
174 T constrain( T val, T minVal, T maxVal )
175 {
176  if( val < minVal ) return minVal;
177  else if( val > maxVal ) return maxVal;
178  else return val;
179 }
180 
182 template<typename T>
183 T fract( T x )
184 {
185  return x - math<T>::floor( x );
186 }
187 
188 // Don Hatch's version of sin(x)/x, which is accurate for very small x.
189 // Returns 1 for x == 0.
190 template <class T>
191 T sinx_over_x( T x )
192 {
193  if( x * x < 1.19209290E-07F )
194  return T( 1 );
195  else
196  return math<T>::sin( x ) / x;
197 }
198 
199 // There are faster techniques for this, but this is portable
200 inline uint32_t log2floor( uint32_t x )
201 {
202  uint32_t result = 0;
203  while( x >>= 1 )
204  ++result;
205 
206  return result;
207 }
208 
209 inline uint32_t log2ceil( uint32_t x )
210 {
211  uint32_t isNotPowerOf2 = (x & (x - 1));
212  return ( isNotPowerOf2 ) ? (log2floor( x ) + 1) : log2floor( x );
213 }
214 
215 inline uint32_t nextPowerOf2( uint32_t x )
216 {
217  x |= (x >> 1);
218  x |= (x >> 2);
219  x |= (x >> 4);
220  x |= (x >> 8);
221  x |= (x >> 16);
222  return(x+1);
223 }
224 
226 inline bool isPowerOf2( size_t x )
227 {
228  return ( x & ( x - 1 ) ) == 0;
229 }
230 
231 template<typename T>
232 inline int solveLinear( T a, T b, T result[1] )
233 {
234  if( a == 0 ) return (b == 0 ? -1 : 0 );
235  result[0] = -b / a;
236  return 1;
237 }
238 
239 template<typename T>
240 inline int solveQuadratic( T a, T b, T c, T result[2] )
241 {
242  if( a == 0 ) return solveLinear( b, c, result );
243 
244  T radical = b * b - 4 * a * c;
245  if( radical < 0 ) return 0;
246 
247  if( radical == 0 ) {
248  result[0] = -b / (2 * a);
249  return 1;
250  }
251 
252  T srad = math<T>::sqrt( radical );
253  result[0] = ( -b - srad ) / (2 * a);
254  result[1] = ( -b + srad ) / (2 * a);
255  if( a < 0 ) std::swap( result[0], result[1] );
256  return 2;
257 }
258 
259 template<typename T,int ORDER>
260 T rombergIntegral( T a, T b, const std::function<T(T)> &SPEEDFN )
261 {
262  static_assert(ORDER > 2, "ORDER must be greater than 2" );
263  T rom[2][ORDER];
264  T half = b - a;
265 
266  rom[0][0] = ((T)0.5) * half * ( SPEEDFN(a)+SPEEDFN(b) );
267  for( int i0=2, iP0=1; i0 <= ORDER; i0++, iP0 *= 2, half *= (T)0.5) {
268  // approximations via the trapezoid rule
269  T sum = 0;
270  for( int i1 = 1; i1 <= iP0; i1++ )
271  sum += SPEEDFN(a + half*(i1-((T)0.5)));
272 
273  // Richardson extrapolation
274  rom[1][0] = ((T)0.5)*(rom[0][0] + half*sum);
275  for( int i2 = 1, iP2 = 4; i2 < i0; i2++, iP2 *= 4 )
276  rom[1][i2] = (iP2*rom[1][i2-1] - rom[0][i2-1])/(iP2-1);
277  for( int i1 = 0; i1 < i0; i1++ )
278  rom[0][i1] = rom[1][i1];
279  }
280 
281  return rom[0][ORDER-1];
282 }
283 
284 template<typename T>
285 int solveCubic( T a, T b, T c, T d, T result[3] );
286 
287 } // namespace cinder
288 
289 #if defined( _MSC_VER ) && ( _MSC_VER < 1800 )
290 // define math.h functions that aren't defined until vc120
291 namespace std {
292 
293 inline bool isfinite( float arg ) { return _finite( arg ) != 0; }
294 inline bool isfinite( double arg ) { return _finite( arg ) != 0; }
295 inline bool isnan( float arg ) { return _isnan( arg ) != 0; }
296 inline bool isnan( double arg ) { return _isnan( arg ) != 0; }
297 
298 // note that while these round* variants follow the basic premise of c99 implementations (numbers with fractional parts of 0.5 should be
299 // rounded away from zero), they are not 100% compliable implementations since they do not cover all edge cases like NaN's, inifinite numbers, etc.
300 inline double round( double x ) { return floor( x < 0 ? x - 0.5 : x + 0.5 ); }
301 inline float roundf( float x ) { return floorf( x < 0 ? x - 0.5f : x + 0.5f ); }
302 inline long int lround( double x ) { return (long int)( x < 0 ? x - 0.5 : x + 0.5 ); }
303 inline long int lroundf( float x ) { return (long int)( x < 0 ? x - 0.5f : x + 0.5f ); }
304 
305 } // namespace std
306 #endif // defined( _MSC_VER ) && ( _MSC_VER < 1800 )
static T sqrt(T x)
Definition: CinderMath.h:63
static T ceil(T x)
Definition: CinderMath.h:69
static float ceil(float x)
Definition: CinderMath.h:105
static float pow(float x, float y)
Definition: CinderMath.h:98
GLenum GLint GLint y
Definition: GLee.h:987
static float abs(float x)
Definition: CinderMath.h:106
Definition: CinderMath.h:40
static T cos(T x)
Definition: CinderMath.h:46
static T log(T x)
Definition: CinderMath.h:53
float toDegrees(float x)
Definition: CinderMath.h:137
static float tanh(float x)
Definition: CinderMath.h:93
static float max(float x, float y)
Definition: CinderMath.h:116
T rombergIntegral(T a, T b, const std::function< T(T)> &SPEEDFN)
Definition: CinderMath.h:260
static float atan2(float y, float x)
Definition: CinderMath.h:87
T sinx_over_x(T x)
Definition: CinderMath.h:191
int int * max
Definition: GLee.h:17208
static T tanh(T x)
Definition: CinderMath.h:51
static T asin(T x)
Definition: CinderMath.h:43
static T modf(T x, T *iptr)
Definition: CinderMath.h:55
static T sin(T x)
Definition: CinderMath.h:47
static float sin(float x)
Definition: CinderMath.h:89
uint32_t nextPowerOf2(uint32_t x)
Definition: CinderMath.h:215
static float sqrt(float x)
Definition: CinderMath.h:99
uint32_t log2floor(uint32_t x)
Definition: CinderMath.h:200
T lerp(const T &a, const T &b, L factor)
Definition: CinderMath.h:148
static T pow(T x, T y)
Definition: CinderMath.h:62
static float floor(float x)
Definition: CinderMath.h:107
static T floor(T x)
Definition: CinderMath.h:71
static T fmod(T x, T y)
Definition: CinderMath.h:72
static T cosh(T x)
Definition: CinderMath.h:49
const double EPSILON_VALUE
Definition: CinderMath.h:124
static float sinh(float x)
Definition: CinderMath.h:92
static T sinh(T x)
Definition: CinderMath.h:50
static float acos(float x)
Definition: CinderMath.h:84
T lmap(T val, T inMin, T inMax, T outMin, T outMax)
Definition: CinderMath.h:154
GLuint GLfloat * val
Definition: GLee.h:14636
int solveCubic(T a, T b, T c, T d, T result[3])
Definition: CinderMath.cpp:33
static T max(T x, T y)
Definition: CinderMath.h:76
static T atan2(T y, T x)
Definition: CinderMath.h:45
float sum(const float *array, size_t length)
returns the sum of array
Definition: Dsp.cpp:175
static T acos(T x)
Definition: CinderMath.h:42
static float min(float x, float y)
Definition: CinderMath.h:115
static T abs(T x)
Definition: CinderMath.h:70
static float cos(float x)
Definition: CinderMath.h:88
static T clamp(T x, T min=0, T max=1)
Definition: CinderMath.h:77
static T hypot(T x, T y)
Definition: CinderMath.h:73
static float clamp(float x, float min=0, float max=1)
Definition: CinderMath.h:117
GLenum GLint x
Definition: GLee.h:987
int solveQuadratic(T a, T b, T c, T result[2])
Definition: CinderMath.h:240
static float atan(float x)
Definition: CinderMath.h:86
static T log10(T x)
Definition: CinderMath.h:54
static float log10(float x)
Definition: CinderMath.h:96
static float hypot(float x, float y)
Definition: CinderMath.h:110
static T tan(T x)
Definition: CinderMath.h:48
static T exp(T x)
Definition: CinderMath.h:52
GLboolean GLboolean GLboolean b
Definition: GLee.h:2964
static float log(float x)
Definition: CinderMath.h:95
static float cosh(float x)
Definition: CinderMath.h:91
static float cbrt(float x)
Definition: CinderMath.h:103
const GLubyte * c
Definition: GLee.h:8491
static T cbrt(T x)
Definition: CinderMath.h:67
float toRadians(float x)
Definition: CinderMath.h:127
static float modf(float x, float *y)
Definition: CinderMath.h:97
GLboolean GLboolean GLboolean GLboolean a
Definition: GLee.h:2964
static T atan(T x)
Definition: CinderMath.h:44
static float asin(float x)
Definition: CinderMath.h:85
static T min(T x, T y)
Definition: CinderMath.h:75
static float exp(float x)
Definition: CinderMath.h:94
T bezierInterp(T a, T b, T c, T d, L t)
Definition: CinderMath.h:160
T constrain(T val, T minVal, T maxVal)
Definition: CinderMath.h:174
T bezierInterpRef(const T &a, const T &b, const T &c, const T &d, L t)
Definition: CinderMath.h:167
GLdouble GLdouble t
Definition: GLee.h:1426
bool isPowerOf2(size_t x)
Returns true if x is a power of two, false otherwise.
Definition: CinderMath.h:226
static T signum(T x)
Definition: CinderMath.h:74
GLclampf f
Definition: GLee.h:15307
static float tan(float x)
Definition: CinderMath.h:90
static float signum(float x)
Definition: CinderMath.h:114
uint32_t log2ceil(uint32_t x)
Definition: CinderMath.h:209
T fract(T x)
Returns the fractional part of x, calculated as x - floor( x )
Definition: CinderMath.h:183
static float fmod(float x, float y)
Definition: CinderMath.h:108
int solveLinear(T a, T b, T result[1])
Definition: CinderMath.h:232