Open Inventor Release 2024.2.1
 
Loading...
Searching...
No Matches
SbMathHelper.h
1#ifndef SB_MATH_HELPER_H
2#define SB_MATH_HELPER_H
3
4/*=======================================================================
5 *** THE CONTENT OF THIS WORK IS PROPRIETARY TO FEI S.A.S, (FEI S.A.S.), ***
6 *** AND IS DISTRIBUTED UNDER A LICENSE AGREEMENT. ***
7 *** ***
8 *** REPRODUCTION, DISCLOSURE, OR USE, IN WHOLE OR IN PART, OTHER THAN AS ***
9 *** SPECIFIED IN THE LICENSE ARE NOT TO BE UNDERTAKEN EXCEPT WITH PRIOR ***
10 *** WRITTEN AUTHORIZATION OF FEI S.A.S. ***
11 *** ***
12 *** RESTRICTED RIGHTS LEGEND ***
13 *** USE, DUPLICATION, OR DISCLOSURE BY THE GOVERNMENT OF THE CONTENT OF THIS ***
14 *** WORK OR RELATED DOCUMENTATION IS SUBJECT TO RESTRICTIONS AS SET FORTH IN ***
15 *** SUBPARAGRAPH (C)(1) OF THE COMMERCIAL COMPUTER SOFTWARE RESTRICTED RIGHT ***
16 *** CLAUSE AT FAR 52.227-19 OR SUBPARAGRAPH (C)(1)(II) OF THE RIGHTS IN ***
17 *** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 52.227-7013. ***
18 *** ***
19 *** COPYRIGHT (C) 1996-2017 BY FEI S.A.S, ***
20 *** BORDEAUX, FRANCE ***
21 *** ALL RIGHTS RESERVED ***
22**=======================================================================*/
23/*=======================================================================
24** Author : VSG (MMM YYYY)
25**=======================================================================*/
26
27
28#include <Inventor/SbBase.h>
29#include <cfloat>
30#include <cmath>
31#include <Inventor/STL/limits>
32#include <Inventor/STL/complex>
33
34namespace SbMathHelper
35{
39 static const int OIV_RAND_MAX = 32767;
43 static const float OIV_DEF_MATH_HELPER_EPS = 1.e-6f;
44
51 SbBool floatIsEqual(float A, float B, unsigned int numFloat);
52 template <typename T> inline T Max(T a, T b) { return (a>b)?a:b; }
53 template <typename T> inline T Min(T a, T b) { return (a<b)?a:b; }
54
61 template <typename T> T shiftValue(T v, int offset) { return v + offset; }
62 template <> float shiftValue(float v, int offset);
63 template<> double shiftValue(double v, int offset);
64
68 template <typename T> inline T Clamp(T a, T minV, T maxV) { return Min(Max(minV, a), maxV); }
69
73 template <typename T> inline T alignToNextPowerOf2(T n, size_t shift)
74 {
75 if ( n & ((T(1)<<shift)-1) )
76 n = (n + (T(1)<<shift)) & ~((T(1)<<shift)-1);
77 return n;
78 }
79
83 template <typename T> inline T getNextPow2(T a)
84 {
85 T pow = 1;
86 while ( pow < a )
87 pow *= 2;
88 return pow;
89 }
90
94 template <int N, typename T>
96 {
97 if ( v%N == 0 )
98 return v;
99 else
100 return v + (N - (v%N));
101 }
102
106 template <int N, typename T>
108 {
109 return v - (v%N);
110 }
111
115 int getNextLog2(int num);
116
120 inline float deg2Rad(float a)
121 {
122 return (a*float(M_PI))/180.f;
123 }
124
128 inline float rad2Deg(float a)
129 {
130 return (a*180.f)/float(M_PI);
131 }
132
144 inline double roundToNearestInt(double x)
145 {
146 return floor(x + 0.5);
147 }
148
152 inline bool isNaN(double a)
153 {
154#ifdef _WIN32
155 return _isnan(a) != 0;
156#else
157 return std::isnan(a);
158#endif
159 }
160
166 inline bool isFinite( double value )
167 {
168 // Alternative to support all compilers
169#if defined(_MSC_VER) && (_MSC_VER < 1800)
170 return value == value &&
171 value != std::numeric_limits<double>::infinity() &&
172 value != -std::numeric_limits<double>::infinity();
173#else
174 return std::isfinite( value );
175#endif // #if defined(_MSC_VER) && (_MSC_VER < 1800)
176 }
177
178 inline bool isFinite( float value )
179 {
180#if defined(_MSC_VER) && (_MSC_VER < 1800)
181 return value == value &&
182 value != std::numeric_limits<float>::infinity() &&
183 value != -std::numeric_limits<float>::infinity();
184#else
185 return std::isfinite( value );
186#endif // #if defined(_MSC_VER) && (_MSC_VER < 1800)
187 }
196 int rand();
197
201 void srand(unsigned seed);
202
206 template< typename T >
207 inline bool isCoinc( const T& x, const T& y, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
208 {
209 return ( fabs( x - y ) <= tol );
210 }
211
213 template<typename T> inline T abs( const T& v ) { return ::abs(v); }
214 template<> inline long int abs( const long int& v ) { return ::labs(v); }
215 template<> inline float abs( const float& v ) { return std::abs(v); }
216 template<> inline double abs( const double& v ) { return std::abs(v); }
217
221 template<typename T>
222 inline bool isLessThan( const T& x, const T& y, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
223 {
224 return ( x < y ) && !isCoinc( x, y, tol );
225 }
226
230 template<typename T>
231 inline bool isGreaterThan( const T& x, const T& y, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
232 {
233 return ( x > y ) && !isCoinc( x, y, tol );
234 }
235
239 template<typename T>
240 inline bool isLessOrEqualThan( const T& x, const T& y, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
241 {
242 return ( x < y ) || isCoinc( x, y, tol );
243 }
244
248 template<typename T>
249 inline bool isGreaterOrEqualThan( const T& x, const T& y, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
250 {
251 return ( x > y ) || isCoinc( x, y, tol );
252 }
253
257 template<typename T>
258 inline bool checkRangeI( const T& x, const T& min, T max, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
259 {
260 return ( isLessOrEqualThan( x, max, tol ) &&
261 isGreaterOrEqualThan( x, min, tol ) );
262 }
263
267 template<typename T>
268 inline bool checkRangeE( const T& x, const T& min, T max, T tol = (T)OIV_DEF_MATH_HELPER_EPS )
269 {
270 return ( isLessThan( x, max, tol ) &&
271 isGreaterThan( x, min, tol ) ) ;
272 }
273
277 template <typename T>
278 bool isCoincRelativeOrAbsolute( const T& A, const T& B, T maxRelativeError, T maxAbsoluteError )
279 {
280 long double ABfabs(std::fabs((long double)(A - B)));
281 if ( ABfabs < maxAbsoluteError )
282 return true;
283 long double Afabs( std::fabs((long double) A) );
284 long double Bfabs( std::fabs((long double) B) );
285 T relativeError = T( ABfabs / ( ( Bfabs > Afabs ) ? Bfabs : Afabs ) );
286 return ( relativeError <= maxRelativeError ) ;
287 }
288
293 template <typename T>
294 int sgn( const T& val )
295 {
296 return (T(0) < val) - (val < T(0));
297 }
298
300 template <typename T> inline T rangeMax() { return std::numeric_limits<T>::max(); }
301
304 template <typename T> inline T rangeMin() { return std::numeric_limits<T>::min(); }
305 template <> inline float rangeMin<float>() { return -rangeMax<float>(); }
306 template <> inline double rangeMin<double>() { return -rangeMax<double>(); }
307
310 template <typename T> inline T fract(const T& /*value*/)
311 {
312 // default implementation is for integer type. Floating type are managed by specific template implementation.
313 return 0;
314 }
315 template <> inline float fract(const float& value)
316 {
317 float intpart;
318 return modff(value, &intpart);
319 }
320 template <> inline double fract(const double& value)
321 {
322 double intpart;
323 return modf(value, &intpart);
324 }
325 template <> inline long double fract(const long double& value)
326 {
327 long double intpart;
328 return modfl(value, &intpart);
329 }
330
331}
332
333#endif
334
335
int SbBool
Boolean type.
Definition SbBase.h:87
SbBool floatIsEqual(float A, float B, unsigned int numFloat)
Return true if A and B are equal.
static const int OIV_RAND_MAX
Maximum value returned by SbMathHelper::rand()
T nearestUpperMultipleOf(T v)
Return the nearest upper multiple of some value.
int sgn(const T &val)
Implements signum return value in { -1, 0, +1 }.
bool isGreaterThan(const T &x, const T &y, T tol=(T) OIV_DEF_MATH_HELPER_EPS)
Greater than test (x > y) using given tolerance.
T Clamp(T a, T minV, T maxV)
Clamps value to given range [minV, maxV].
bool isNaN(double a)
Returns true if the specified value is NaN.
bool isGreaterOrEqualThan(const T &x, const T &y, T tol=(T) OIV_DEF_MATH_HELPER_EPS)
Greater or equal than test (x >= y) using given tolerance.
bool checkRangeI(const T &x, const T &min, T max, T tol=(T) OIV_DEF_MATH_HELPER_EPS)
Inside closed interval (including endpoints) using given tolerance test.
T Max(T a, T b)
bool isCoincRelativeOrAbsolute(const T &A, const T &B, T maxRelativeError, T maxAbsoluteError)
Relative or absolute error without sign comparison.
float rad2Deg(float a)
Convert radians to degrees.
void srand(unsigned seed)
Set seed for a new sequence of pseudo-random integers to be returned by rand()
static const float OIV_DEF_MATH_HELPER_EPS
Default epsilon value for coincidence and interval checking.
T alignToNextPowerOf2(T n, size_t shift)
Return an integer multiple of 2^shift greater or equals to n.
T rangeMax()
Returns the maximum finite value representable by the numeric type T.
int rand()
Returns a pseudo-random integer between 0 and OIV_RAND_MAX.
bool isFinite(double value)
Returns true if the value is a finite value (i.e.
T Min(T a, T b)
T abs(const T &v)
Return absolute value of v.
bool isLessOrEqualThan(const T &x, const T &y, T tol=(T) OIV_DEF_MATH_HELPER_EPS)
Less or equal than test (x <= y) using given tolerance.
double rangeMin< double >()
int getNextLog2(int num)
Return the next log of 2 greater or equal to a.
double roundToNearestInt(double x)
Round the double value to the nearest integer value.
T nearestLowerMultipleOf(T v)
Return the nearest lower multiple of some value.
T fract(const T &)
Return fractional part of given value.
bool isLessThan(const T &x, const T &y, T tol=(T) OIV_DEF_MATH_HELPER_EPS)
Less than test (x < y) using given tolerance.
float rangeMin< float >()
T rangeMin()
Returns the lowest finite value representable by the numeric type T, that is, a finite value x such t...
T getNextPow2(T a)
Return the next power of 2 greater or equal to a.
bool isCoinc(const T &x, const T &y, T tol=(T) OIV_DEF_MATH_HELPER_EPS)
Coincidence test using given tolerance.
float deg2Rad(float a)
Convert degrees to radians.
bool checkRangeE(const T &x, const T &min, T max, T tol=(T) OIV_DEF_MATH_HELPER_EPS)
Inside open interval (excluding endpoints) using given tolerance test.
T shiftValue(T v, int offset)
shift the value of offset representable values considering value type.