00001 #ifndef SB_MATH_HELPER_H
00002 #define SB_MATH_HELPER_H
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 #include <Inventor/SbBase.h>
00029 #include <cfloat>
00030 #include <cmath>
00031 #include <Inventor/STL/limits>
00032 #include <Inventor/STL/complex>
00033
00034 namespace SbMathHelper
00035 {
00039 static const int OIV_RAND_MAX = 32767;
00043 static const float OIV_DEF_MATH_HELPER_EPS = 1.e-6f;
00044
00051 SbBool floatIsEqual(float A, float B, unsigned int numFloat);
00052 template <typename T> inline T Max(T a, T b) { return (a>b)?a:b; }
00053 template <typename T> inline T Min(T a, T b) { return (a<b)?a:b; }
00054
00061 template <typename T> T shiftValue(T v, int offset) { return v + offset; }
00062 template <> float shiftValue(float v, int offset);
00063 template<> double shiftValue(double v, int offset);
00064
00068 template <typename T> inline T Clamp(T a, T minV, T maxV) { return Min(Max(minV, a), maxV); }
00069
00073 template <typename T> inline T alignToNextPowerOf2(T n, size_t shift)
00074 {
00075 if ( n & ((T(1)<<shift)-1) )
00076 n = (n + (T(1)<<shift)) & ~((T(1)<<shift)-1);
00077 return n;
00078 }
00079
00083 template <typename T> inline T getNextPow2(T a)
00084 {
00085 T pow = 1;
00086 while ( pow < a )
00087 pow *= 2;
00088 return pow;
00089 }
00090
00094 template <int N, typename T>
00095 inline T nearestUpperMultipleOf(T v)
00096 {
00097 if ( v%N == 0 )
00098 return v;
00099 else
00100 return v + (N - (v%N));
00101 }
00102
00106 template <int N, typename T>
00107 inline T nearestLowerMultipleOf(T v)
00108 {
00109 return v - (v%N);
00110 }
00111
00115 int getNextLog2(int num);
00116
00120 inline float deg2Rad(float a)
00121 {
00122 return (a*float(M_PI))/180.f;
00123 }
00124
00128 inline float rad2Deg(float a)
00129 {
00130 return (a*180.f)/float(M_PI);
00131 }
00132
00136 inline bool isNaN(double a)
00137 {
00138 #ifdef _WIN32
00139 return _isnan(a) != 0;
00140 #else
00141 return std::isnan(a);
00142 #endif
00143 }
00144
00150 inline bool isFinite( double value )
00151 {
00152
00153 #if defined(_MSC_VER) && (_MSC_VER < 1800)
00154 return value == value &&
00155 value != std::numeric_limits<double>::infinity() &&
00156 value != -std::numeric_limits<double>::infinity();
00157 #else
00158 return std::isfinite( value );
00159 #endif // #if defined(_MSC_VER) && (_MSC_VER < 1800)
00160 }
00161
00162 inline bool isFinite( float value )
00163 {
00164 #if defined(_MSC_VER) && (_MSC_VER < 1800)
00165 return value == value &&
00166 value != std::numeric_limits<float>::infinity() &&
00167 value != -std::numeric_limits<float>::infinity();
00168 #else
00169 return std::isfinite( value );
00170 #endif // #if defined(_MSC_VER) && (_MSC_VER < 1800)
00171 }
00180 int rand();
00181
00185 void srand(unsigned seed);
00186
00190 template<typename T>
00191 inline bool isCoinc( const T& x, const T& y, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
00192 {
00193 return ( fabs( x - y ) <= tol );
00194 }
00195
00197 template<typename T> inline T abs( const T& v ) { return ::abs(v); }
00198 template<> inline long int abs( const long int& v ) { return ::labs(v); }
00199 template<> inline float abs( const float& v ) { return std::abs(v); }
00200 template<> inline double abs( const double& v ) { return std::abs(v); }
00201
00205 template<typename T>
00206 inline bool isLessThan( const T& x, const T& y, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
00207 {
00208 return ( x < y ) && !isCoinc( x, y, tol );
00209 }
00210
00214 template<typename T>
00215 inline bool isGreaterThan( const T& x, const T& y, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
00216 {
00217 return ( x > y ) && !isCoinc( x, y, tol );
00218 }
00219
00223 template<typename T>
00224 inline bool isLessOrEqualThan( const T& x, const T& y, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
00225 {
00226 return ( x < y ) || isCoinc( x, y, tol );
00227 }
00228
00232 template<typename T>
00233 inline bool isGreaterOrEqualThan( const T& x, const T& y, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
00234 {
00235 return ( x > y ) || isCoinc( x, y, tol );
00236 }
00237
00241 template<typename T>
00242 inline bool checkRangeI( const T& x, const T& min, T max, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
00243 {
00244 return ( isLessOrEqualThan( x, max, tol ) &&
00245 isGreaterOrEqualThan( x, min, tol ) );
00246 }
00247
00251 template<typename T>
00252 inline bool checkRangeE( const T& x, const T& min, T max, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
00253 {
00254 return ( isLessThan( x, max, tol ) &&
00255 isGreaterThan( x, min, tol ) ) ;
00256 }
00257
00261 template <typename T>
00262 bool isCoincRelativeOrAbsolute( const T& A, const T& B, T maxRelativeError, T maxAbsoluteError )
00263 {
00264 long double fAmB(std::fabs((long double)(A - B)));
00265 if ( fAmB < maxAbsoluteError )
00266 return true;
00267 T relativeError;
00268 long double fA( std::fabs((long double) A) );
00269 long double fB( std::fabs((long double) B) );
00270 if ( fB > fA )
00271 relativeError = (T)(fAmB / fB);
00272 else
00273 relativeError = (T)(fAmB / fA);
00274 if ( relativeError <= maxRelativeError )
00275 return true;
00276 return false;
00277 }
00278
00283 template <typename T>
00284 int sgn( const T& val )
00285 {
00286 return (T(0) < val) - (val < T(0));
00287 }
00288
00290 template <typename T> inline T rangeMax() { return std::numeric_limits<T>::max(); }
00291
00294 template <typename T> inline T rangeMin() { return std::numeric_limits<T>::min(); }
00295 template <> inline float rangeMin<float>() { return -rangeMax<float>(); }
00296 template <> inline double rangeMin<double>() { return -rangeMax<double>(); }
00297
00300 template <typename T> inline T fract(const T& value)
00301 {
00302
00303 return 0;
00304 }
00305 template <> inline float fract(const float& value)
00306 {
00307 float intpart;
00308 return modff(value, &intpart);
00309 }
00310 template <> inline double fract(const double& value)
00311 {
00312 double intpart;
00313 return modf(value, &intpart);
00314 }
00315 template <> inline long double fract(const long double& value)
00316 {
00317 long double intpart;
00318 return modfl(value, &intpart);
00319 }
00320
00321 }
00322
00323 #endif
00324
00325
00326