diff --git a/include/irrMath.h b/include/irrMath.h index e3b75e02e..0219bd487 100644 --- a/include/irrMath.h +++ b/include/irrMath.h @@ -9,6 +9,7 @@ #include #include // for abs() etc. #include // For INT_MAX / UINT_MAX +#include namespace irr { @@ -17,9 +18,6 @@ namespace core //! Rounding error constant often used when comparing f32 values. - const s32 ROUNDING_ERROR_S32 = 0; - - const s64 ROUNDING_ERROR_S64 = 0; const f32 ROUNDING_ERROR_f32 = 0.000001f; const f64 ROUNDING_ERROR_f64 = 0.00000001; @@ -170,30 +168,6 @@ namespace core return ROUNDING_ERROR_f64; } - template <> - inline s32 roundingError() - { - return ROUNDING_ERROR_S32; - } - - template <> - inline u32 roundingError() - { - return ROUNDING_ERROR_S32; - } - - template <> - inline s64 roundingError() - { - return ROUNDING_ERROR_S64; - } - - template <> - inline u64 roundingError() - { - return ROUNDING_ERROR_S64; - } - template inline T relativeErrorFactor() { @@ -212,14 +186,20 @@ namespace core return 8; } + //! returns if a equals b, for types without rounding errors + template ::value, bool> = true> + inline bool equals(const T a, const T b) + { + return a == b; + } + //! returns if a equals b, taking possible rounding errors into account - template + template ::value, bool> = true> inline bool equals(const T a, const T b, const T tolerance = roundingError()) { - return (a + tolerance >= b) && (a - tolerance <= b); + return abs(a - b) <= tolerance; } - //! returns if a equals b, taking relative error in form of factor //! this particular function does not involve any division. template diff --git a/include/vector2d.h b/include/vector2d.h index 75ca08b70..139ee7a57 100644 --- a/include/vector2d.h +++ b/include/vector2d.h @@ -75,47 +75,47 @@ class vector2d return *(&X+index); } - //! sort in order X, Y. Equality with rounding tolerance. + //! sort in order X, Y. bool operator<=(const vector2d&other) const { - return (X other); } - //! sort in order X, Y. Equality with rounding tolerance. + //! sort in order X, Y. bool operator>=(const vector2d&other) const { - return (X>other.X || core::equals(X, other.X)) || - (core::equals(X, other.X) && (Y>other.Y || core::equals(Y, other.Y))); + return !(*this < other); } - //! sort in order X, Y. Difference must be above rounding tolerance. + //! sort in order X, Y. bool operator<(const vector2d&other) const { - return (X(const vector2d&other) const { - return (X>other.X && !core::equals(X, other.X)) || - (core::equals(X, other.X) && Y>other.Y && !core::equals(Y, other.Y)); + return X > other.X || (X == other.X && Y > other.Y); } - bool operator==(const vector2d& other) const { return equals(other); } - bool operator!=(const vector2d& other) const { return !equals(other); } + bool operator==(const vector2d& other) const { + return X == other.X && Y == other.Y; + } + + bool operator!=(const vector2d& other) const { + return !(*this == other); + } // functions //! Checks if this vector equals the other one. /** Takes floating point rounding errors into account. \param other Vector to compare with. - \param tolerance Epsilon value for both - comparing X and Y. \return True if the two vector are (almost) equal, else false. */ - bool equals(const vector2d& other, const T tolerance = (T)ROUNDING_ERROR_f32 ) const + bool equals(const vector2d& other) const { - return core::equals(X, other.X, tolerance) && core::equals(Y, other.Y, tolerance); + return core::equals(X, other.X) && core::equals(Y, other.Y); } vector2d& set(T nx, T ny) {X=nx; Y=ny; return *this; } diff --git a/include/vector3d.h b/include/vector3d.h index b89bfbcb5..2817287fe 100644 --- a/include/vector3d.h +++ b/include/vector3d.h @@ -68,57 +68,51 @@ namespace core return *(&X+index); } - //! sort in order X, Y, Z. Equality with rounding tolerance. + //! sort in order X, Y, Z. bool operator<=(const vector3d&other) const { - return (X other); } - //! sort in order X, Y, Z. Equality with rounding tolerance. + //! sort in order X, Y, Z. bool operator>=(const vector3d&other) const { - return (X>other.X || core::equals(X, other.X)) || - (core::equals(X, other.X) && (Y>other.Y || core::equals(Y, other.Y))) || - (core::equals(X, other.X) && core::equals(Y, other.Y) && (Z>other.Z || core::equals(Z, other.Z))); + return !(*this < other); } - //! sort in order X, Y, Z. Difference must be above rounding tolerance. + //! sort in order X, Y, Z. bool operator<(const vector3d&other) const { - return (X(const vector3d&other) const { - return (X>other.X && !core::equals(X, other.X)) || - (core::equals(X, other.X) && Y>other.Y && !core::equals(Y, other.Y)) || - (core::equals(X, other.X) && core::equals(Y, other.Y) && Z>other.Z && !core::equals(Z, other.Z)); + return X > other.X || (X == other.X && Y > other.Y) || + (X == other.X && Y == other.Y && Z > other.Z); } - //! use weak float compare bool operator==(const vector3d& other) const { - return this->equals(other); + return X == other.X && Y == other.Y && Z == other.Z; } bool operator!=(const vector3d& other) const { - return !this->equals(other); + return !(*this == other); } // functions - //! returns if this vector equals the other one, taking floating point rounding errors into account - bool equals(const vector3d& other, const T tolerance = (T)ROUNDING_ERROR_f32 ) const + //! Checks if this vector equals the other one. + /** Takes floating point rounding errors into account. + \param other Vector to compare with. + \return True if the two vector are (almost) equal, else false. */ + bool equals(const vector3d& other) const { - return core::equals(X, other.X, tolerance) && - core::equals(Y, other.Y, tolerance) && - core::equals(Z, other.Z, tolerance); + return core::equals(X, other.X) && core::equals(Y, other.Y) && core::equals(Z, other.Z); } vector3d& set(const T nx, const T ny, const T nz) {X=nx; Y=ny; Z=nz; return *this;}