35 #ifndef OPENVDB_MATH_HAS_BEEN_INCLUDED
36 #define OPENVDB_MATH_HAS_BEEN_INCLUDED
45 #include <boost/numeric/conversion/conversion_traits.hpp>
46 #include <openvdb/Platform.h>
47 #include <openvdb/version.h>
54 #if defined(__INTEL_COMPILER)
55 #define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN \
56 _Pragma("warning (push)") \
57 _Pragma("warning (disable:1572)")
58 #define OPENVDB_NO_FP_EQUALITY_WARNING_END \
59 _Pragma("warning (pop)")
68 #define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN
69 #define OPENVDB_NO_FP_EQUALITY_WARNING_END
80 template<
typename T>
inline T
zeroVal() {
return T(0); }
82 template<>
inline std::string zeroVal<std::string>() {
return ""; }
92 template<>
struct tolerance<float> {
static float value() {
return 1e-8f; } };
93 template<>
struct tolerance<double> {
static double value() {
return 1e-15; } };
99 inline std::string
operator+(
const std::string& s,
bool) {
return s; }
102 inline std::string
operator+(
const std::string& s,
int) {
return s; }
103 inline std::string
operator+(
const std::string& s,
float) {
return s; }
104 inline std::string
operator+(
const std::string& s,
double) {
return s; }
109 template<
typename T>
inline T
negative(
const T& val) {
return T(-val); }
113 template<>
inline bool negative(
const bool& val) {
return !val; }
115 template<>
inline std::string
negative(
const std::string& val) {
return val; }
124 inline void randSeed(
unsigned int seed) { srand(seed); }
128 inline double randUniform() {
return (
double)(rand() / (RAND_MAX + 1.0)); }
138 assert(min<max &&
"RandomInt: invalid arguments");
142 int operator()()
const {
return rand() % my_range + my_min; }
150 template<
typename Type>
155 return x > min ? x < max ? x : max :
min;
160 template<
typename Type>
162 Clamp01(Type x) {
return x > Type(0) ? x < Type(1) ? x : Type(1) : Type(0); }
166 template<
typename Type>
170 if (x >= Type(0) && x <= Type(1))
return false;
171 x = x < Type(0) ? Type(0) : Type(1);
178 template<
typename Type>
183 const Type t = (x-
min)/(max-min);
184 return t > 0 ? t < 1 ? (3-2*t)*t*t : Type(1) : Type(0);
192 inline int32_t
Abs(int32_t i) {
return abs(i); }
194 inline int64_t
Abs(int64_t i)
197 return (i < int64_t(0) ? -i : i);
202 inline float Abs(
float x) {
return fabs(x); }
203 inline double Abs(
double x) {
return fabs(x); }
204 inline long double Abs(
long double x) {
return fabs(x); }
205 inline uint32_t
Abs(uint32_t i) {
return i; }
206 inline uint64_t
Abs(uint64_t i) {
return i; }
217 template<
typename Type>
222 return x == zeroVal<Type>();
229 template<
typename Type>
233 const Type
tolerance = Type(zeroVal<Type>() + toleranceValue<Type>());
234 return x < tolerance && x > -tolerance;
238 template<
typename Type>
242 return x < tolerance && x > -tolerance;
246 template<
typename Type>
251 template<
typename Type>
255 const Type
tolerance = Type(zeroVal<Type>() + toleranceValue<Type>());
256 return !(
Abs(a - b) > tolerance);
259 template<
typename Type>
263 return !(
Abs(a - b) > tolerance);
266 #define OPENVDB_EXACT_IS_APPROX_EQUAL(T) \
267 template<> inline bool isApproxEqual<T>(const T& a, const T& b) { return a == b; } \
268 template<> inline bool isApproxEqual<T>(const T& a, const T& b, const T&) { return a == b; } \
275 template<typename T0, typename T1>
285 template<
typename Type>
291 if (!(
Abs(a - b) > absTol))
return true;
298 relError =
Abs((a - b) / b);
300 relError =
Abs((a - b) / a);
302 return (relError <= relTol);
319 union FloatOrInt32 {
float floatValue; int32_t int32Value; };
320 const FloatOrInt32* foi =
reinterpret_cast<const FloatOrInt32*
>(&aFloatValue);
321 return foi->int32Value;
328 union DoubleOrInt64 {
double doubleValue; int64_t int64Value; };
329 const DoubleOrInt64* dol =
reinterpret_cast<const DoubleOrInt64*
>(&aDoubleValue);
330 return dol->int64Value;
339 isUlpsEqual(
const double aLeft,
const double aRight,
const int64_t aUnitsInLastPlace)
344 longLeft = INT64_C(0x8000000000000000) - longLeft;
350 longRight = INT64_C(0x8000000000000000) - longRight;
353 int64_t difference = labs(longLeft - longRight);
354 return (difference <= aUnitsInLastPlace);
358 isUlpsEqual(
const float aLeft,
const float aRight,
const int32_t aUnitsInLastPlace)
363 intLeft = 0x80000000 - intLeft;
369 intRight = 0x80000000 - intRight;
372 int32_t difference = abs(intLeft - intRight);
373 return (difference <= aUnitsInLastPlace);
383 template<
typename Type>
384 inline Type
Pow2(Type x) {
return x*x; }
387 template<
typename Type>
388 inline Type
Pow3(Type x) {
return x*x*x; }
391 template<
typename Type>
395 template<
typename Type>
404 while (n--) ans *= x;
413 assert( b >= 0.0f &&
"Pow(float,float): base is negative" );
420 assert( b >= 0.0 &&
"Pow(double,double): base is negative" );
429 template<
typename Type>
431 Max(
const Type& a,
const Type& b)
437 template<
typename Type>
439 Max(
const Type& a,
const Type& b,
const Type& c)
445 template<
typename Type>
447 Max(
const Type& a,
const Type& b,
const Type& c,
const Type& d)
453 template<
typename Type>
455 Max(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
const Type& e)
461 template<
typename Type>
463 Max(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
const Type& e,
const Type& f)
469 template<
typename Type>
471 Max(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
472 const Type& e,
const Type& f,
const Type& g)
478 template<
typename Type>
480 Max(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
481 const Type& e,
const Type& f,
const Type& g,
const Type& h)
490 template<
typename Type>
495 template<
typename Type>
500 template<
typename Type>
502 Min(
const Type& a,
const Type& b,
const Type& c,
const Type& d)
508 template<
typename Type>
510 Min(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
const Type& e)
516 template<
typename Type>
518 Min(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
const Type& e,
const Type& f)
524 template<
typename Type>
526 Min(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
527 const Type& e,
const Type& f,
const Type& g)
533 template<
typename Type>
535 Min(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
536 const Type& e,
const Type& f,
const Type& g,
const Type& h)
546 template <
typename Type>
547 inline int Sign(
const Type &x) {
return (zeroVal<Type>() < x) - (x < zeroVal<Type>()); }
552 template <
typename Type>
556 return ( (a<zeroVal<Type>()) ^ (b<zeroVal<Type>()) );
562 template <
typename Type>
566 return a * b <= zeroVal<Type>();
571 inline float Sqrt(
float x) {
return sqrtf(x); }
573 inline double Sqrt(
double x) {
return sqrt(x); }
574 inline long double Sqrt(
long double x) {
return sqrtl(x); }
579 inline float Cbrt(
float x) {
return cbrtf(x); }
581 inline double Cbrt(
double x) {
return cbrtf(x); }
582 inline long double Cbrt(
long double x) {
return cbrtl(x); }
587 inline int Mod(
int x,
int y) {
return (x % y); };
589 inline float Mod(
float x,
float y) {
return fmodf(x,y); }
590 inline double Mod(
double x,
double y) {
return fmod(x,y); }
591 inline long double Mod(
long double x,
long double y) {
return fmodl(x,y); }
592 template<
typename Type>
inline Type
Remainder(Type x, Type y) {
return Mod(x,y); }
597 inline float RoundUp(
float x) {
return ceilf(x); }
599 inline double RoundUp(
double x) {
return ceil(x); }
600 inline long double RoundUp(
long double x) {
return ceill(x); }
602 template<
typename Type>
608 return remainder ? x-remainder+base : x;
613 inline float RoundDown(
float x) {
return floorf(x); }
616 inline long double RoundDown(
long double x) {
return floorl(x); }
619 template<
typename Type>
625 return remainder ? x-remainder : x;
630 template<
typename Type>
638 template<
typename Type>
651 inline int Ceil(
float x) {
return (
int)
RoundUp(x); }
659 template<
typename Type>
660 inline Type
Chop(Type x, Type delta) {
return (
Abs(x) < delta ? zeroVal<Type>() : x); }
664 template<
typename Type>
668 Type tenth =
Pow(10,digits);
677 template<
typename Type>
705 template <
typename S,
typename T>
707 typedef typename boost::numeric::conversion_traits<S, T>::supertype
type;
713 template<
typename Vec3T>
717 static const size_t hashTable[8] = { 2, 1, 9, 1, 2, 9, 0, 0 };
718 const size_t hashKey =
719 ((v[0] < v[1]) << 2) + ((v[0] < v[2]) << 1) + (v[1] < v[2]);
720 return hashTable[hashKey];
726 template<
typename Vec3T>
730 static const size_t hashTable[8] = { 2, 1, 9, 1, 2, 9, 0, 0 };
731 const size_t hashKey =
732 ((v[0] > v[1]) << 2) + ((v[0] > v[2]) << 1) + (v[1] > v[2]);
733 return hashTable[hashKey];
740 #endif // OPENVDB_MATH_MATH_HAS_BEEN_INCLUDED