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
00026
00027
00028
00029
00030
00031 #ifndef SYNMATH
00032 #define SYNMATH
00033 #include <assert.h>
00034 #include <math.h>
00035 namespace syn
00036 {
00037 namespace Math
00038 {
00040 struct ADDEQUAL { inline static void oper( float& i, const float o ) { i += o; } };
00041
00043 struct EQUAL { inline static void oper( float& i, const float o ) { i = o; } };
00044
00046 struct MULTEQUAL { inline static void oper( float& i, const float o ) { i *= o; } };
00047
00048 const float PI = 3.14159265358979323846f;
00049 const float PI_OVER_2 = 1.57079632679489661923f;
00050 const float PI_OVER_4 = 0.78539816339744830962f;
00051
00052
00054 template <class T>
00055 inline T Min( const T& x, const T& y )
00056 {
00057 return ( x > y ) ? y : x;
00058 }
00060 template <class T>
00061 inline T Min( const T& x, const T& y, const T& z )
00062 {
00063 return Math::Min( Math::Min( x, y ), z );
00064 }
00066 template <class T>
00067 inline T Min( const T& w, const T& x, const T& y, const T& z )
00068 {
00069 return Math::Min( Math::Min( w, x ), Math::Min( y, z ) );
00070 }
00071
00073 template <class T>
00074 inline T Max( const T& x, const T& y )
00075 {
00076 return ( x > y ) ? x : y;
00077 }
00079 template <class T>
00080 inline T Max( const T& x, const T& y, const T& z )
00081 {
00082 return Math::Max( Math::Max( x, y ), z );
00083 }
00085 template <class T>
00086 inline T Max( const T& w, const T& x, const T& y, const T& z )
00087 {
00088 return Math::Max( Math::Max( w, x ), Math::Max( y, z ) );
00089 }
00093 template <class T, typename U>
00094 inline void lerp( T& result, const U& lerp, const T& a, const T& b )
00095 {
00096 T size = b - a;
00097 result = ((U)a) + (((U)size) * lerp);
00098 }
00099
00101 template <class T>
00102 inline T trunc( T val )
00103 {
00104 return T( (val < ((T)0)) ? Math::ceil( val ) : Math::floor( val ) );
00105 }
00107 template <class T>
00108 inline T round( T p )
00109 {
00110 return T( Math::floor( p + (T)0.5 ) );
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 template <typename T>
00139 inline T aCos( T fValue );
00140 inline float aCos( float fValue )
00141 {
00142 if ( -1.0f < fValue )
00143 {
00144 if ( fValue < 1.0f )
00145 return float( ::acosf( fValue ) );
00146 else
00147 return 0.0f;
00148 }
00149 else
00150 {
00151 return (float)Math::PI;
00152 }
00153 }
00154 inline double aCos( double fValue )
00155 {
00156 if ( -1.0 < fValue )
00157 {
00158 if ( fValue < 1.0 )
00159 return double( ::acos( fValue ) );
00160 else
00161 return 0.0;
00162 }
00163 else
00164 {
00165 return (double)PI;
00166 }
00167 }
00168
00169 template <typename T>
00170 inline T aSin( T fValue );
00171 inline float aSin( float fValue )
00172 {
00173 if ( -1.0f < fValue )
00174 {
00175 if ( fValue < 1.0f )
00176 return float( ::asinf( fValue ) );
00177 else
00178 return (float)-PI_OVER_2;
00179 }
00180 else
00181 {
00182 return (float)PI_OVER_2;
00183 }
00184 }
00185 inline double aSin( double fValue )
00186 {
00187 if ( -1.0 < fValue )
00188 {
00189 if ( fValue < 1.0 )
00190 return double( ::asin( fValue ) );
00191 else
00192 return (double)-PI_OVER_2;
00193 }
00194 else
00195 {
00196 return (double)PI_OVER_2;
00197 }
00198 }
00199 template <typename T>
00200 inline T aTan( T fValue );
00201 inline float aTan( float fValue )
00202 {
00203 return float( ::atanf( fValue ) );
00204 }
00205 inline double aTan( double fValue )
00206 {
00207 return ::atan( fValue );
00208 }
00209
00210 template <typename T>
00211 inline T atan2( T fY, T fX );
00212 inline float aTan2( float fY, float fX )
00213 {
00214 return float( ::atan2f( fY, fX ) );
00215 }
00216 inline double aTan2( double fY, double fX )
00217 {
00218 return double( ::atan2( fY, fX ) );
00219 }
00220
00221 template <typename T>
00222 inline T cos( T fValue );
00223 inline float cos( float fValue )
00224 {
00225 return float( ::cosf( fValue ) );
00226 }
00227 inline double cos( double fValue )
00228 {
00229 return double( ::cos( fValue ) );
00230 }
00231
00232 template <typename T>
00233 inline T exp( T fValue );
00234 inline float exp( float fValue )
00235 {
00236 return float( ::expf( fValue ) );
00237 }
00238 inline double exp( double fValue )
00239 {
00240 return double( ::exp( fValue ) );
00241 }
00242
00243 template <typename T>
00244 inline T log( T fValue );
00245 inline double log( double fValue )
00246 {
00247 return double( ::log( fValue ) );
00248 }
00249 inline float log( float fValue )
00250 {
00251 return float( ::logf( fValue ) );
00252 }
00253
00254 inline double pow( double fBase, double fExponent)
00255 {
00256 return double( ::pow( fBase, fExponent ) );
00257 }
00258 inline float pow( float fBase, float fExponent)
00259 {
00260 return float( ::powf( fBase, fExponent ) );
00261 }
00262 template <typename T>
00263 inline T sin( T fValue );
00264 inline double sin( double fValue )
00265 {
00266 return double( ::sin( fValue ) );
00267 }
00268 inline float sin( float fValue )
00269 {
00270 return float( ::sinf( fValue ) );
00271 }
00272 template <typename T>
00273 inline T tan( T fValue );
00274 inline double tan( double fValue )
00275 {
00276 return double( ::tan( fValue ) );
00277 }
00278 inline float tan( float fValue )
00279 {
00280 return float( ::tanf( fValue ) );
00281 }
00282 template <typename T>
00283 inline T sqr( T fValue )
00284 {
00285 return T( fValue * fValue );
00286 }
00287 template <typename T>
00288 inline T sqrt( T fValue )
00289 {
00290 return T( ::sqrtf( ((float)fValue) ) );
00291 }
00292 inline double sqrt( double fValue )
00293 {
00294 return double( ::sqrt( fValue ) );
00295 }
00296
00297 template <typename T>
00298 inline T abs( T iValue )
00299 {
00300 return T( iValue >= ((T)0) ? iValue : -iValue );
00301 }
00302
00308 inline double fast_exp2( const double val )
00309 {
00310
00311 union
00312 {
00313 short val;
00314 char ch[sizeof( short )];
00315 } un;
00316 un.val = 256;
00317
00318
00319
00320 int e;
00321 double ret;
00322
00323 if (val >= 0)
00324 {
00325 e = int (val);
00326 ret = val - (e - 1);
00327
00328 if (un.ch[1] == 1)
00329 ((*(1 + (int *) &ret)) &= ~(2047 << 20)) += (e + 1023) << 20;
00330 else
00331 ((*((int *) &ret)) &= ~(2047 << 20)) += (e + 1023) << 20;
00332 }
00333 else
00334 {
00335 e = int (val + 1023);
00336 ret = val - (e - 1024);
00337
00338 if (un.ch[1] == 1)
00339 ((*(1 + (int *) &ret)) &= ~(2047 << 20)) += e << 20;
00340 else
00341 ((*((int *) &ret)) &= ~(2047 << 20)) += e << 20;
00342 }
00343
00344 return ret;
00345 }
00346
00354 inline float fast_log2( const float f )
00355 {
00356 assert( f > 0. );
00357
00358
00359 int i = (*(int *)&f);
00360 return (((i&0x7f800000)>>23)-0x7f)+(i&0x007fffff)/(float)0x800000;
00361 }
00362
00365 template <typename T>
00366 inline T log2( const T f )
00367 {
00368 static const double conversion = ::log10( 2.0f );
00369 return (T)log10( (double)f ) / conversion;
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 inline float volumeToDB( float vol )
00396 {
00397 float db;
00398
00399 vol = 100.0f - vol;
00400
00401 if (vol <= 0.0f) {
00402 db = 10.0f;
00403 } else if (vol < 48.0f) {
00404 db = 10.0f - 5.0f/12.0f * vol;
00405 } else if (vol < 84.0f) {
00406 db = -10.0f - 10.0f/12.0f * (vol - 48.0f);
00407 } else if (vol < 96.0f) {
00408 db = -40.0f - 20.0f/12.0f * (vol - 84.0f);
00409 } else if (vol < 100.0f) {
00410 db = -60.0f - 35.0f * (vol - 96.0f);
00411 } else db = -200.0f;
00412 return db;
00413 }
00414
00415 inline float DBtoVolume( float db )
00416 {
00417 float vol;
00418 if (db >= 10.0f) {
00419 vol = 0.0f;
00420 } else if (db > -10.0f) {
00421 vol = -12.0f/5.0f * (db - 10.0f);
00422 } else if (db > -40.0f) {
00423 vol = 48.0f - 12.0f/10.0f * (db + 10.0f);
00424 } else if (db > -60.0f) {
00425 vol = 84.0f - 12.0f/20.0f * (db + 40.0f);
00426 } else if (db > -200.0f) {
00427 vol = 96.0f - 1.0f/35.0f * (db + 60.0f);
00428 } else vol = 100.0f;
00429
00430 vol = 100.0f - vol;
00431
00432 return vol;
00433 }
00434 }
00435 }
00436
00437 #endif