mirror of
https://github.com/BlackMATov/vmath.hpp.git
synced 2025-12-13 04:06:52 +07:00
@@ -339,13 +339,22 @@ namespace vmath_hpp
|
||||
template < typename T >
|
||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
|
||||
constexpr distance(T x, T y) noexcept {
|
||||
return length(y - x);
|
||||
if constexpr ( std::is_unsigned_v<T> ) {
|
||||
return x < y ? (y - x) : (x - y);
|
||||
} else {
|
||||
return length(x - y);
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
|
||||
constexpr distance2(T x, T y) noexcept {
|
||||
return length2(y - x);
|
||||
if constexpr ( std::is_unsigned_v<T> ) {
|
||||
const T d = x < y ? (y - x) : (x - y);
|
||||
return d * d;
|
||||
} else {
|
||||
return length2(x - y);
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
@@ -393,6 +402,12 @@ namespace vmath_hpp
|
||||
return !!x;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
|
||||
constexpr approx(T x, T y, T epsilon) noexcept {
|
||||
return distance(x, y) <= epsilon;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
|
||||
constexpr approx(T x, T y) noexcept {
|
||||
@@ -400,24 +415,12 @@ namespace vmath_hpp
|
||||
/// REFERENCE:
|
||||
/// http://www.realtimecollisiondetection.net/pubs/Tolerances
|
||||
const T epsilon = std::numeric_limits<T>::epsilon();
|
||||
return abs(x - y) <= epsilon * max(max(T{1}, abs(x)), abs(y));
|
||||
return approx(x, y, epsilon * max(T{1}, max(abs(x), abs(y))));
|
||||
} else {
|
||||
return x == y;
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
|
||||
constexpr approx(T x, T y, T epsilon) noexcept {
|
||||
if constexpr ( std::is_floating_point_v<T> ) {
|
||||
/// REFERENCE:
|
||||
/// http://www.realtimecollisiondetection.net/pubs/Tolerances
|
||||
return abs(x - y) <= epsilon * max(max(T{1}, abs(x)), abs(y));
|
||||
} else {
|
||||
return abs(x - y) <= epsilon;
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
|
||||
constexpr less(T x, T y) noexcept {
|
||||
|
||||
@@ -954,12 +954,12 @@ namespace vmath_hpp
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr T distance(const vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
return length(ys - xs);
|
||||
return length(xs - ys);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr T distance2(const vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
return length2(ys - xs);
|
||||
return length2(xs - ys);
|
||||
}
|
||||
|
||||
template < typename T, typename U
|
||||
|
||||
@@ -446,13 +446,22 @@ namespace vmath_hpp
|
||||
template < typename T >
|
||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
|
||||
constexpr distance(T x, T y) noexcept {
|
||||
return length(y - x);
|
||||
if constexpr ( std::is_unsigned_v<T> ) {
|
||||
return x < y ? (y - x) : (x - y);
|
||||
} else {
|
||||
return length(x - y);
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
|
||||
constexpr distance2(T x, T y) noexcept {
|
||||
return length2(y - x);
|
||||
if constexpr ( std::is_unsigned_v<T> ) {
|
||||
const T d = x < y ? (y - x) : (x - y);
|
||||
return d * d;
|
||||
} else {
|
||||
return length2(x - y);
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
@@ -500,6 +509,12 @@ namespace vmath_hpp
|
||||
return !!x;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
|
||||
constexpr approx(T x, T y, T epsilon) noexcept {
|
||||
return distance(x, y) <= epsilon;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
|
||||
constexpr approx(T x, T y) noexcept {
|
||||
@@ -507,24 +522,12 @@ namespace vmath_hpp
|
||||
/// REFERENCE:
|
||||
/// http://www.realtimecollisiondetection.net/pubs/Tolerances
|
||||
const T epsilon = std::numeric_limits<T>::epsilon();
|
||||
return abs(x - y) <= epsilon * max(max(T{1}, abs(x)), abs(y));
|
||||
return approx(x, y, epsilon * max(T{1}, max(abs(x), abs(y))));
|
||||
} else {
|
||||
return x == y;
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
|
||||
constexpr approx(T x, T y, T epsilon) noexcept {
|
||||
if constexpr ( std::is_floating_point_v<T> ) {
|
||||
/// REFERENCE:
|
||||
/// http://www.realtimecollisiondetection.net/pubs/Tolerances
|
||||
return abs(x - y) <= epsilon * max(max(T{1}, abs(x)), abs(y));
|
||||
} else {
|
||||
return abs(x - y) <= epsilon;
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
|
||||
constexpr less(T x, T y) noexcept {
|
||||
@@ -1767,12 +1770,12 @@ namespace vmath_hpp
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr T distance(const vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
return length(ys - xs);
|
||||
return length(xs - ys);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr T distance2(const vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
return length2(ys - xs);
|
||||
return length2(xs - ys);
|
||||
}
|
||||
|
||||
template < typename T, typename U
|
||||
|
||||
@@ -120,9 +120,17 @@ TEST_CASE("vmath/fun") {
|
||||
STATIC_CHECK(rlength2(10.f) == uapprox(0.01f));
|
||||
STATIC_CHECK(rlength2(-10.f) == uapprox(0.01f));
|
||||
|
||||
STATIC_CHECK(distance(5, 10) == 5);
|
||||
STATIC_CHECK(distance(10, 5) == 5);
|
||||
STATIC_CHECK(distance(5u, 10u) == 5);
|
||||
STATIC_CHECK(distance(10u, 5u) == 5);
|
||||
STATIC_CHECK(distance(5.f, 10.f) == uapprox(5.f));
|
||||
STATIC_CHECK(distance(-5.f, -10.f) == uapprox(5.f));
|
||||
|
||||
STATIC_CHECK(distance2(5, 10) == 25);
|
||||
STATIC_CHECK(distance2(10, 5) == 25);
|
||||
STATIC_CHECK(distance2(5u, 10u) == 25);
|
||||
STATIC_CHECK(distance2(10u, 5u) == 25);
|
||||
STATIC_CHECK(distance2(5.f, 10.f) == uapprox(25.f));
|
||||
STATIC_CHECK(distance2(-5.f, -10.f) == uapprox(25.f));
|
||||
|
||||
@@ -151,6 +159,22 @@ TEST_CASE("vmath/fun") {
|
||||
STATIC_CHECK_FALSE(approx(0, 1));
|
||||
STATIC_CHECK_FALSE(approx(0, 1, 0));
|
||||
STATIC_CHECK(approx(0, 1, 1));
|
||||
STATIC_CHECK_FALSE(approx(1, 3, 1));
|
||||
STATIC_CHECK(approx(1, 3, 2));
|
||||
|
||||
STATIC_CHECK(approx(1u, 1u));
|
||||
STATIC_CHECK_FALSE(approx(0u, 1u));
|
||||
STATIC_CHECK_FALSE(approx(0u, 1u, 0u));
|
||||
STATIC_CHECK(approx(0u, 1u, 1u));
|
||||
STATIC_CHECK_FALSE(approx(1u, 3u, 1u));
|
||||
STATIC_CHECK(approx(1u, 3u, 2u));
|
||||
|
||||
STATIC_CHECK(approx(1.f, 1.f));
|
||||
STATIC_CHECK_FALSE(approx(0.f, 1.f));
|
||||
STATIC_CHECK_FALSE(approx(0.f, 1.f, 0.f));
|
||||
STATIC_CHECK(approx(0.f, 1.f, 1.f));
|
||||
STATIC_CHECK_FALSE(approx(1.f, 3.f, 1.f));
|
||||
STATIC_CHECK(approx(1.f, 3.f, 2.f));
|
||||
|
||||
STATIC_CHECK(approx(1.f, 1.f + std::numeric_limits<float>::epsilon() * 0.5f));
|
||||
STATIC_CHECK_FALSE(approx(1.f, 1.f + std::numeric_limits<float>::epsilon() * 1.5f));
|
||||
|
||||
Reference in New Issue
Block a user