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
00144 inline double roundToNearestInt(double x)
00145 {
00146 return floor(x + 0.5);
00147 }
00148
00152 inline bool isNaN(double a)
00153 {
00154 #ifdef _WIN32
00155 return _isnan(a) != 0;
00156 #else
00157 return std::isnan(a);
00158 #endif
00159 }
00160
00166 inline bool isFinite( double value )
00167 {
00168
00169 #if defined(_MSC_VER) && (_MSC_VER < 1800)
00170 return value == value &&
00171 value != std::numeric_limits<double>::infinity() &&
00172 value != -std::numeric_limits<double>::infinity();
00173 #else
00174 return std::isfinite( value );
00175 #endif // #if defined(_MSC_VER) && (_MSC_VER < 1800)
00176 }
00177
00178 inline bool isFinite( float value )
00179 {
00180 #if defined(_MSC_VER) && (_MSC_VER < 1800)
00181 return value == value &&
00182 value != std::numeric_limits<float>::infinity() &&
00183 value != -std::numeric_limits<float>::infinity();
00184 #else
00185 return std::isfinite( value );
00186 #endif // #if defined(_MSC_VER) && (_MSC_VER < 1800)
00187 }
00196 int rand();
00197
00201 void srand(unsigned seed);
00202
00206 template< typename T >
00207 inline bool isCoinc( const T& x, const T& y, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
00208 {
00209 return ( fabs( x - y ) <= tol );
00210 }
00211
00213 template<typename T> inline T abs( const T& v ) { return ::abs(v); }
00214 template<> inline long int abs( const long int& v ) { return ::labs(v); }
00215 template<> inline float abs( const float& v ) { return std::abs(v); }
00216 template<> inline double abs( const double& v ) { return std::abs(v); }
00217
00221 template<typename T>
00222 inline bool isLessThan( const T& x, const T& y, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
00223 {
00224 return ( x < y ) && !isCoinc( x, y, tol );
00225 }
00226
00230 template<typename T>
00231 inline bool isGreaterThan( const T& x, const T& y, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
00232 {
00233 return ( x > y ) && !isCoinc( x, y, tol );
00234 }
00235
00239 template<typename T>
00240 inline bool isLessOrEqualThan( const T& x, const T& y, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
00241 {
00242 return ( x < y ) || isCoinc( x, y, tol );
00243 }
00244
00248 template<typename T>
00249 inline bool isGreaterOrEqualThan( const T& x, const T& y, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
00250 {
00251 return ( x > y ) || isCoinc( x, y, tol );
00252 }
00253
00257 template<typename T>
00258 inline bool checkRangeI( const T& x, const T& min, T max, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
00259 {
00260 return ( isLessOrEqualThan( x, max, tol ) &&
00261 isGreaterOrEqualThan( x, min, tol ) );
00262 }
00263
00267 template<typename T>
00268 inline bool checkRangeE( const T& x, const T& min, T max, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
00269 {
00270 return ( isLessThan( x, max, tol ) &&
00271 isGreaterThan( x, min, tol ) ) ;
00272 }
00273
00277 template <typename T>
00278 bool isCoincRelativeOrAbsolute( const T& A, const T& B, T maxRelativeError, T maxAbsoluteError )
00279 {
00280 long double ABfabs(std::fabs((long double)(A - B)));
00281 if ( ABfabs < maxAbsoluteError )
00282 return true;
00283 long double Afabs( std::fabs((long double) A) );
00284 long double Bfabs( std::fabs((long double) B) );
00285 T relativeError = T( ABfabs / ( ( Bfabs > Afabs ) ? Bfabs : Afabs ) );
00286 return ( relativeError <= maxRelativeError ) ;
00287 }
00288
00293 template <typename T>
00294 int sgn( const T& val )
00295 {
00296 return (T(0) < val) - (val < T(0));
00297 }
00298
00300 template <typename T> inline T rangeMax() { return std::numeric_limits<T>::max(); }
00301
00304 template <typename T> inline T rangeMin() { return std::numeric_limits<T>::min(); }
00305 template <> inline float rangeMin<float>() { return -rangeMax<float>(); }
00306 template <> inline double rangeMin<double>() { return -rangeMax<double>(); }
00307
00310 template <typename T> inline T fract(const T& )
00311 {
00312
00313 return 0;
00314 }
00315 template <> inline float fract(const float& value)
00316 {
00317 float intpart;
00318 return modff(value, &intpart);
00319 }
00320 template <> inline double fract(const double& value)
00321 {
00322 double intpart;
00323 return modf(value, &intpart);
00324 }
00325 template <> inline long double fract(const long double& value)
00326 {
00327 long double intpart;
00328 return modfl(value, &intpart);
00329 }
00330
00331 }
00332
00333 #endif
00334
00335
00336