8#ifndef OPENVDB_MATH_HAS_BEEN_INCLUDED
9#define OPENVDB_MATH_HAS_BEEN_INCLUDED
12#include <openvdb/version.h>
13#include <boost/numeric/conversion/conversion_traits.hpp>
27#if defined(__INTEL_COMPILER)
28 #define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN \
29 _Pragma("warning (push)") \
30 _Pragma("warning (disable:1572)")
31 #define OPENVDB_NO_FP_EQUALITY_WARNING_END \
32 _Pragma("warning (pop)")
33#elif defined(__clang__)
34 #define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN \
35 PRAGMA(clang diagnostic push) \
36 PRAGMA(clang diagnostic ignored "-Wfloat-equal")
37 #define OPENVDB_NO_FP_EQUALITY_WARNING_END \
38 PRAGMA(clang diagnostic pop)
47 #define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN
48 #define OPENVDB_NO_FP_EQUALITY_WARNING_END
55#define OPENVDB_IS_POD(Type) \
56static_assert(std::is_standard_layout<Type>::value, \
57 #Type" must be a POD type (satisfy StandardLayoutType.)"); \
58static_assert(std::is_trivial<Type>::value, \
59 #Type" must be a POD type (satisfy TrivialType.)");
69template<
typename T>
inline T
zeroVal() {
return T(0); }
71template<>
inline std::string zeroVal<std::string>() {
return ""; }
73template<>
inline bool zeroVal<bool>() {
return false; }
81inline std::string
operator+(
const std::string& s,
bool) {
return s; }
82inline std::string
operator+(
const std::string& s,
int) {
return s; }
83inline std::string
operator+(
const std::string& s,
float) {
return s; }
84inline std::string
operator+(
const std::string& s,
double) {
return s; }
88template<
typename Type1,
typename Type2>
89inline auto cwiseAdd(
const Type1& v,
const Type2 s)
97template<
typename Type1,
typename Type2>
106template<
typename Type1,
typename Type2>
118template <
typename T>
inline constexpr T
pi() {
return 3.141592653589793238462643383279502884e+00; }
119template <>
inline constexpr float pi() {
return 3.141592653589793238462643383279502884e+00F; }
120template <>
inline constexpr double pi() {
return 3.141592653589793238462643383279502884e+00; }
121template <>
inline constexpr long double pi() {
return 3.141592653589793238462643383279502884e+00L; }
127template<
typename T>
inline T
negative(
const T& val)
132#pragma warning(disable:4146)
140template<>
inline bool negative(
const bool& val) {
return !val; }
142template<>
inline std::string
negative(
const std::string& val) {
return val; }
147template<
typename T>
struct Tolerance {
static T
value() {
return zeroVal<T>(); } };
154template<
typename T>
struct Delta {
static T
value() {
return zeroVal<T>(); } };
155template<>
struct Delta<float> {
static float value() {
return 1e-5f; } };
156template<>
struct Delta<double> {
static double value() {
return 1e-9; } };
164template<
typename FloatType =
double,
typename EngineType = std::mt19937>
169 std::uniform_real_distribution<FloatType> mRand;
176 Rand01(
const EngineType& engine): mEngine(engine) {}
180 Rand01(
unsigned int seed): mEngine(static_cast<typename EngineType::result_type>(seed)) {}
185 mEngine.seed(
static_cast<typename EngineType::result_type
>(seed));
189 const EngineType&
engine()
const {
return mEngine; }
200template<
typename IntType =
int,
typename EngineType = std::mt19937>
204 using Distr = std::uniform_int_distribution<IntType>;
212 RandInt(
const EngineType& engine, IntType imin, IntType imax):
214 mRand(
std::min(imin, imax),
std::max(imin, imax))
220 RandInt(
unsigned int seed, IntType imin, IntType imax):
221 mEngine(static_cast<typename EngineType::result_type>(seed)),
222 mRand(
std::min(imin, imax),
std::max(imin, imax))
228 mRand = Distr(std::min(imin, imax), std::max(imin, imax));
234 mEngine.seed(
static_cast<typename EngineType::result_type
>(seed));
238 const EngineType&
engine()
const {
return mEngine; }
247 const IntType lo = std::min(imin, imax), hi = std::max(imin, imax);
248 return mRand(mEngine,
typename Distr::param_type(lo, hi));
258template<
typename Type>
262 assert( !(min>max) );
263 return x > min ? x < max ? x : max : min;
268template<
typename Type>
270Clamp01(Type x) {
return x > Type(0) ? x < Type(1) ? x : Type(1) : Type(0); }
274template<
typename Type>
278 if (x >= Type(0) && x <= Type(1))
return false;
279 x = x < Type(0) ? Type(0) : Type(1);
284template<
typename Type>
288 return x > 0 ? x < 1 ? (3-2*x)*x*x : Type(1) : Type(0);
293template<
typename Type>
307inline int32_t
Abs(int32_t i) {
return abs(i); }
308inline int64_t
Abs(int64_t i)
311 return (i < int64_t(0) ? -i : i);
316inline float Abs(
float x) {
return std::fabs(x); }
317inline double Abs(
double x) {
return std::fabs(x); }
318inline long double Abs(
long double x) {
return std::fabs(x); }
319inline uint32_t
Abs(uint32_t i) {
return i; }
320inline uint64_t
Abs(uint64_t i) {
return i; }
321inline bool Abs(
bool b) {
return b; }
324inline typename std::enable_if<std::is_same<T, size_t>::value, T>::type
336template<
typename Type>
341 return x == zeroVal<Type>();
348template<
typename Type>
353 return !(x > tolerance) && !(x < -tolerance);
357template<
typename Type>
361 return !(x > tolerance) && !(x < -tolerance);
366template<
typename Type>
371template<>
inline bool isNegative<bool>(
const bool&) {
return false; }
376isFinite(
const float x) {
return std::isfinite(x); }
379template<typename Type, typename std::enable_if<std::is_arithmetic<Type>::value,
int>::type = 0>
381isFinite(
const Type& x) {
return std::isfinite(
static_cast<double>(x)); }
389template<typename Type, typename std::enable_if<std::is_arithmetic<Type>::value,
int>::type = 0>
391isInfinite(
const Type& x) {
return std::isinf(
static_cast<double>(x)); }
396isNan(
const float x) {
return std::isnan(x); }
399template<typename Type, typename std::enable_if<std::is_arithmetic<Type>::value,
int>::type = 0>
401isNan(
const Type& x) {
return std::isnan(
static_cast<double>(x)); }
405template<
typename Type>
414template<
typename Type>
422#define OPENVDB_EXACT_IS_APPROX_EQUAL(T) \
423 template<> inline bool isApproxEqual<T>(const T& a, const T& b) { return a == b; } \
424 template<> inline bool isApproxEqual<T>(const T& a, const T& b, const T&) { return a == b; } \
433template<typename Type>
435isApproxLarger(const Type& a, const Type& b, const Type& tolerance)
437 return (b - a < tolerance);
442template<
typename T0,
typename T1>
452template<
typename Type>
458 if (!(
Abs(a - b) > absTol))
return true;
465 relError =
Abs((a - b) / b);
467 relError =
Abs((a - b) / a);
469 return (relError <= relTol);
486 union FloatOrInt32 {
float floatValue; int32_t int32Value; };
487 const FloatOrInt32* foi =
reinterpret_cast<const FloatOrInt32*
>(&aFloatValue);
488 return foi->int32Value;
495 union DoubleOrInt64 {
double doubleValue; int64_t int64Value; };
496 const DoubleOrInt64* dol =
reinterpret_cast<const DoubleOrInt64*
>(&aDoubleValue);
497 return dol->int64Value;
506isUlpsEqual(
const double aLeft,
const double aRight,
const int64_t aUnitsInLastPlace)
511 longLeft = INT64_C(0x8000000000000000) - longLeft;
517 longRight = INT64_C(0x8000000000000000) - longRight;
520 int64_t difference = labs(longLeft - longRight);
521 return (difference <= aUnitsInLastPlace);
525isUlpsEqual(
const float aLeft,
const float aRight,
const int32_t aUnitsInLastPlace)
530 intLeft = 0x80000000 - intLeft;
536 intRight = 0x80000000 - intRight;
539 int32_t difference = abs(intLeft - intRight);
540 return (difference <= aUnitsInLastPlace);
550template<
typename Type>
551inline Type
Pow2(Type x) {
return x*x; }
554template<
typename Type>
555inline Type
Pow3(Type x) {
return x*x*x; }
558template<
typename Type>
562template<
typename Type>
571 while (n--) ans *= x;
580 assert( b >= 0.0f &&
"Pow(float,float): base is negative" );
587 assert( b >= 0.0 &&
"Pow(double,double): base is negative" );
588 return std::pow(b,e);
596template<
typename Type>
598Max(
const Type& a,
const Type& b)
600 return std::max(a,b);
604template<
typename Type>
606Max(
const Type& a,
const Type& b,
const Type& c)
608 return std::max(std::max(a,b), c);
612template<
typename Type>
614Max(
const Type& a,
const Type& b,
const Type& c,
const Type& d)
616 return std::max(std::max(a,b), std::max(c,d));
620template<
typename Type>
622Max(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
const Type& e)
624 return std::max(std::max(a,b),
Max(c,d,e));
628template<
typename Type>
630Max(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
const Type& e,
const Type& f)
632 return std::max(
Max(a,b,c),
Max(d,e,f));
636template<
typename Type>
638Max(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
639 const Type& e,
const Type& f,
const Type& g)
641 return std::max(
Max(a,b,c,d),
Max(e,f,g));
645template<
typename Type>
647Max(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
648 const Type& e,
const Type& f,
const Type& g,
const Type& h)
650 return std::max(
Max(a,b,c,d),
Max(e,f,g,h));
657template<
typename Type>
659Min(
const Type& a,
const Type& b) {
return std::min(a, b); }
662template<
typename Type>
664Min(
const Type& a,
const Type& b,
const Type& c) {
return std::min(std::min(a, b), c); }
667template<
typename Type>
669Min(
const Type& a,
const Type& b,
const Type& c,
const Type& d)
671 return std::min(std::min(a, b), std::min(c, d));
675template<
typename Type>
677Min(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
const Type& e)
679 return std::min(std::min(a,b),
Min(c,d,e));
683template<
typename Type>
685Min(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
const Type& e,
const Type& f)
687 return std::min(
Min(a,b,c),
Min(d,e,f));
691template<
typename Type>
693Min(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
694 const Type& e,
const Type& f,
const Type& g)
696 return std::min(
Min(a,b,c,d),
Min(e,f,g));
700template<
typename Type>
702Min(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
703 const Type& e,
const Type& f,
const Type& g,
const Type& h)
705 return std::min(
Min(a,b,c,d),
Min(e,f,g,h));
712template<
typename Type>
713inline Type
Exp(
const Type& x) {
return std::exp(x); }
719inline float Sin(
const float& x) {
return std::sin(x); }
721inline double Sin(
const double& x) {
return std::sin(x); }
728inline float Cos(
const float& x) {
return std::cos(x); }
730inline double Cos(
const double& x) {
return std::cos(x); }
738template <
typename Type>
739inline int Sign(
const Type &x) {
return (zeroVal<Type>() < x) - (x < zeroVal<Type>()); }
744template <
typename Type>
748 return ( (a<zeroVal<Type>()) ^ (b<zeroVal<Type>()) );
754template <
typename Type>
758 return a * b <= zeroVal<Type>();
764inline float Sqrt(
float x) {
return std::sqrt(x); }
765inline double Sqrt(
double x) {
return std::sqrt(x); }
766inline long double Sqrt(
long double x) {
return std::sqrt(x); }
772inline float Cbrt(
float x) {
return std::cbrt(x); }
773inline double Cbrt(
double x) {
return std::cbrt(x); }
774inline long double Cbrt(
long double x) {
return std::cbrt(x); }
780inline int Mod(
int x,
int y) {
return (x % y); }
781inline float Mod(
float x,
float y) {
return std::fmod(x, y); }
782inline double Mod(
double x,
double y) {
return std::fmod(x, y); }
783inline long double Mod(
long double x,
long double y) {
return std::fmod(x, y); }
784template<
typename Type>
inline Type
Remainder(Type x, Type y) {
return Mod(x, y); }
790inline float RoundUp(
float x) {
return std::ceil(x); }
791inline double RoundUp(
double x) {
return std::ceil(x); }
792inline long double RoundUp(
long double x) {
return std::ceil(x); }
795template<
typename Type>
800 return remainder ? x-remainder+base : x;
806inline float RoundDown(
float x) {
return std::floor(x); }
807inline double RoundDown(
double x) {
return std::floor(x); }
808inline long double RoundDown(
long double x) {
return std::floor(x); }
811template<
typename Type>
816 return remainder ? x-remainder : x;
830template<
typename Type>
836template<
typename Type>
844template<
typename Type>
866template<
typename Type>
867inline Type
Chop(Type x, Type delta) {
return (
Abs(x) < delta ? zeroVal<Type>() : x); }
871template<
typename Type>
875 Type tenth =
static_cast<Type
>(
Pow(
size_t(10), digits));
885inline auto PrintCast(
const T& val) ->
typename std::enable_if<!std::is_same<T, int8_t>::value
886 && !std::is_same<T, uint8_t>::value,
const T&>::type {
return val; }
887inline int32_t
PrintCast(int8_t val) {
return int32_t(val); }
888inline uint32_t
PrintCast(uint8_t val) {
return uint32_t(val); }
895template<
typename Type>
923template <
typename S,
typename T>
925 using type =
typename boost::numeric::conversion_traits<S, T>::supertype;
936template<
typename Vec3T>
940 static const size_t hashTable[8] = { 2, 1, 9, 1, 2, 9, 0, 0 };
941 const size_t hashKey =
942 ((v[0] < v[1]) << 2) + ((v[0] < v[2]) << 1) + (v[1] < v[2]);
943 return hashTable[hashKey];
954template<
typename Vec3T>
958 static const size_t hashTable[8] = { 2, 1, 9, 1, 2, 9, 0, 0 };
959 const size_t hashKey =
960 ((v[0] > v[1]) << 2) + ((v[0] > v[2]) << 1) + (v[1] > v[2]);
961 return hashTable[hashKey];
#define OPENVDB_EXACT_IS_APPROX_EQUAL(T)
Definition: Math.h:422
#define OPENVDB_NO_FP_EQUALITY_WARNING_END
Definition: Math.h:48
#define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN
Definition: Math.h:47
Simple generator of random numbers over the range [0, 1)
Definition: Math.h:166
void setSeed(unsigned int seed)
Set the seed value for the random number generator.
Definition: Math.h:183
Rand01(const EngineType &engine)
Initialize the generator.
Definition: Math.h:176
const EngineType & engine() const
Return a const reference to the random number generator.
Definition: Math.h:189
FloatType operator()()
Return a uniformly distributed random number in the range [0, 1).
Definition: Math.h:192
Rand01(unsigned int seed)
Initialize the generator.
Definition: Math.h:180
FloatType ValueType
Definition: Math.h:172
Simple random integer generator.
Definition: Math.h:202
void setSeed(unsigned int seed)
Set the seed value for the random number generator.
Definition: Math.h:232
RandInt(unsigned int seed, IntType imin, IntType imax)
Initialize the generator.
Definition: Math.h:220
void setRange(IntType imin, IntType imax)
Change the range over which integers are distributed to [imin, imax].
Definition: Math.h:226
IntType operator()()
Return a randomly-generated integer in the current range.
Definition: Math.h:241
const EngineType & engine() const
Return a const reference to the random number generator.
Definition: Math.h:238
RandInt(const EngineType &engine, IntType imin, IntType imax)
Initialize the generator.
Definition: Math.h:212
IntType operator()(IntType imin, IntType imax)
Return a randomly-generated integer in the new range [imin, imax], without changing the current range...
Definition: Math.h:245
int Sign(const Type &x)
Return the sign of the given value as an integer (either -1, 0 or 1).
Definition: Math.h:739
size_t MaxIndex(const Vec3T &v)
Return the index [0,1,2] of the largest value in a 3D vector.
Definition: Math.h:956
float RoundUp(float x)
Return x rounded up to the nearest integer.
Definition: Math.h:790
Type SmoothUnitStep(Type x)
Return 0 if x < 0, 1 if x > 1 or else (3 − 2 x) x².
Definition: Math.h:286
int Ceil(float x)
Return the ceiling of x.
Definition: Math.h:859
bool isApproxZero(const Type &x)
Return true if x is equal to zero to within the default floating-point comparison tolerance.
Definition: Math.h:350
bool isInfinite(const float x)
Return true if x is an infinity value (either positive infinity or negative infinity).
Definition: Math.h:386
Type IntegerPart(Type x)
Return the integer part of x.
Definition: Math.h:838
bool cwiseLessThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Definition: Mat.h:1037
constexpr T pi()
Pi constant taken from Boost to match old behaviour.
Definition: Math.h:118
Type Pow(Type x, int n)
Return xn.
Definition: Math.h:564
float Sqrt(float x)
Return the square root of a floating-point value.
Definition: Math.h:764
bool isApproxEqual(const Type &a, const Type &b, const Type &tolerance)
Return true if a is equal to b to within the given tolerance.
Definition: Math.h:407
bool isRelOrApproxEqual(const Type &a, const Type &b, const Type &absTol, const Type &relTol)
Definition: Math.h:454
const Type & Max(const Type &a, const Type &b)
Return the maximum of two values.
Definition: Math.h:598
size_t MinIndex(const Vec3T &v)
Return the index [0,1,2] of the smallest value in a 3D vector.
Definition: Math.h:938
Mat3< Type1 > cwiseAdd(const Mat3< Type1 > &m, const Type2 s)
Definition: Mat3.h:820
bool isFinite(const float x)
Return true if x is finite.
Definition: Math.h:376
auto PrintCast(const T &val) -> typename std::enable_if<!std::is_same< T, int8_t >::value &&!std::is_same< T, uint8_t >::value, const T & >::type
8-bit integer values print to std::ostreams as characters. Cast them so that they print as integers i...
Definition: Math.h:885
Vec3< typename promote< T, typename Coord::ValueType >::type > operator+(const Vec3< T > &v0, const Coord &v1)
Allow a Coord to be added to or subtracted from a Vec3.
Definition: Coord.h:525
Type Pow4(Type x)
Return x4.
Definition: Math.h:559
Type EuclideanRemainder(Type x)
Definition: Math.h:832
int64_t doubleToInt64(const double aDoubleValue)
Definition: Math.h:493
Type Remainder(Type x, Type y)
Definition: Math.h:784
Type Inv(Type x)
Return the inverse of x.
Definition: Math.h:897
int32_t floatToInt32(const float aFloatValue)
Definition: Math.h:484
Type Exp(const Type &x)
Return ex.
Definition: Math.h:713
bool isNegative(const Type &x)
Return true if x is less than zero.
Definition: Math.h:368
bool isNan(const float x)
Return true if x is a NaN (Not-A-Number) value.
Definition: Math.h:396
Type Clamp01(Type x)
Return x clamped to [0, 1].
Definition: Math.h:270
float Cos(const float &x)
Return cos x.
Definition: Math.h:728
bool isUlpsEqual(const double aLeft, const double aRight, const int64_t aUnitsInLastPlace)
Definition: Math.h:506
float RoundDown(float x)
Return x rounded down to the nearest integer.
Definition: Math.h:806
const Type & Min(const Type &a, const Type &b)
Return the minimum of two values.
Definition: Math.h:659
Coord Abs(const Coord &xyz)
Definition: Coord.h:515
int Mod(int x, int y)
Return the remainder of x / y.
Definition: Math.h:780
Type Truncate(Type x, unsigned int digits)
Return x truncated to the given number of decimal digits.
Definition: Math.h:873
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:127
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:444
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:822
Type Pow3(Type x)
Return x3.
Definition: Math.h:555
Type Clamp(Type x, Type min, Type max)
Return x clamped to [min, max].
Definition: Math.h:260
bool isZero(const Type &x)
Return true if x is exactly equal to zero.
Definition: Math.h:338
Type Chop(Type x, Type delta)
Return x if it is greater or equal in magnitude than delta. Otherwise, return zero.
Definition: Math.h:867
Type FractionalPart(Type x)
Return the fractional part of x.
Definition: Math.h:846
Axis
Definition: Math.h:904
@ Z_AXIS
Definition: Math.h:907
@ X_AXIS
Definition: Math.h:905
@ Y_AXIS
Definition: Math.h:906
bool cwiseGreaterThan(const Mat< SIZE, T > &m0, const Mat< SIZE, T > &m1)
Definition: Mat.h:1051
bool ClampTest01(Type &x)
Return true if x is outside [0,1].
Definition: Math.h:276
float Sin(const float &x)
Return sin x.
Definition: Math.h:719
Type Pow2(Type x)
Return x2.
Definition: Math.h:551
RotationOrder
Definition: Math.h:911
@ YXZ_ROTATION
Definition: Math.h:914
@ ZXY_ROTATION
Definition: Math.h:916
@ YZX_ROTATION
Definition: Math.h:915
@ ZXZ_ROTATION
Definition: Math.h:919
@ XZX_ROTATION
Definition: Math.h:918
@ XYZ_ROTATION
Definition: Math.h:912
@ ZYX_ROTATION
Definition: Math.h:917
@ XZY_ROTATION
Definition: Math.h:913
float Cbrt(float x)
Return the cube root of a floating-point value.
Definition: Math.h:772
int Floor(float x)
Return the floor of x.
Definition: Math.h:851
bool SignChange(const Type &a, const Type &b)
Return true if a and b have different signs.
Definition: Math.h:746
bool ZeroCrossing(const Type &a, const Type &b)
Return true if the interval [a, b] includes zero, i.e., if either a or b is zero or if they have diff...
Definition: Math.h:756
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:69
Definition: Exceptions.h:13
static double value()
Definition: Math.h:156
static float value()
Definition: Math.h:155
Delta for small floating-point offsets.
Definition: Math.h:154
static T value()
Definition: Math.h:154
static double value()
Definition: Math.h:149
static float value()
Definition: Math.h:148
Tolerance for floating-point comparison.
Definition: Math.h:147
static T value()
Definition: Math.h:147
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202