rename equal_to to approximately, remove not_equal_to, add relational functions for matrix

This commit is contained in:
BlackMATov
2020-12-07 17:22:52 +07:00
parent 030c17dc9a
commit b77472e89b
8 changed files with 228 additions and 215 deletions

100
README.md
View File

@@ -1254,69 +1254,73 @@ vec<T, Size> refract(const vec<T, Size>& i, const vec<T, Size>& n, T eta);
#### Scalar #### Scalar
```cpp ```cpp
template < arithmetic T >
constexpr bool equal_to(T x, T y) noexcept;
template < arithmetic T >
constexpr bool equal_to(T x, T y, T epsilon) noexcept;
template < arithmetic T >
constexpr bool not_equal_to(T x, T y) noexcept;
template < arithmetic T >
constexpr bool not_equal_to(T x, T y, T epsilon) noexcept;
template < arithmetic T > template < arithmetic T >
constexpr bool any(T x) noexcept; constexpr bool any(T x) noexcept;
template < arithmetic T > template < arithmetic T >
constexpr bool all(T x) noexcept; constexpr bool all(T x) noexcept;
template < arithmetic T >
constexpr bool approximately(T x, T y) noexcept;
template < arithmetic T >
constexpr bool approximately(T x, T y, T epsilon) noexcept;
``` ```
#### Vector #### Vector
```cpp ```cpp
template < typename T, size_t Size >
constexpr vec<bool, Size> equal_to(const vec<T, Size>& xs, T y);
template < typename T, size_t Size >
constexpr vec<bool, Size> equal_to(T x, const vec<T, Size>& ys);
template < typename T, size_t Size >
constexpr vec<bool, Size> equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys);
template < typename T, size_t Size >
constexpr vec<bool, Size> equal_to(const vec<T, Size>& xs, T y, T epsilon);
template < typename T, size_t Size >
constexpr vec<bool, Size> equal_to(T x, const vec<T, Size>& ys, T epsilon);
template < typename T, size_t Size >
constexpr vec<bool, Size> equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys, T epsilon);
template < typename T, size_t Size >
constexpr vec<bool, Size> not_equal_to(const vec<T, Size>& xs, T y);
template < typename T, size_t Size >
constexpr vec<bool, Size> not_equal_to(T x, const vec<T, Size>& ys);
template < typename T, size_t Size >
constexpr vec<bool, Size> not_equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys);
template < typename T, size_t Size >
constexpr vec<bool, Size> not_equal_to(const vec<T, Size>& xs, T y, T epsilon);
template < typename T, size_t Size >
constexpr vec<bool, Size> not_equal_to(T x, const vec<T, Size>& ys, T epsilon);
template < typename T, size_t Size >
constexpr vec<bool, Size> not_equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys, T epsilon);
template < typename T, size_t Size > template < typename T, size_t Size >
constexpr bool any(const vec<T, Size>& xs); constexpr bool any(const vec<T, Size>& xs);
template < typename T, size_t Size > template < typename T, size_t Size >
constexpr bool all(const vec<T, Size>& xs); constexpr bool all(const vec<T, Size>& xs);
template < typename T, size_t Size >
constexpr vec<bool, Size> approximately(const vec<T, Size>& xs, T y);
template < typename T, size_t Size >
constexpr vec<bool, Size> approximately(T x, const vec<T, Size>& ys);
template < typename T, size_t Size >
constexpr vec<bool, Size> approximately(const vec<T, Size>& xs, const vec<T, Size>& ys);
template < typename T, size_t Size >
constexpr vec<bool, Size> approximately(const vec<T, Size>& xs, T y, T epsilon);
template < typename T, size_t Size >
constexpr vec<bool, Size> approximately(T x, const vec<T, Size>& ys, T epsilon);
template < typename T, size_t Size >
constexpr vec<bool, Size> approximately(const vec<T, Size>& xs, const vec<T, Size>& ys, T epsilon);
```
#### Matrix
```cpp
template < typename T, size_t Size >
constexpr bool any(const mat<T, Size>& xs);
template < typename T, size_t Size >
constexpr bool all(const mat<T, Size>& xs);
template < typename T, size_t Size >
constexpr mat<bool, Size> approximately(const mat<T, Size>& xs, T y);
template < typename T, size_t Size >
constexpr mat<bool, Size> approximately(T x, const mat<T, Size>& ys);
template < typename T, size_t Size >
constexpr mat<bool, Size> approximately(const mat<T, Size>& xs, const mat<T, Size>& ys);
template < typename T, size_t Size >
constexpr mat<bool, Size> approximately(const mat<T, Size>& xs, T y, T epsilon);
template < typename T, size_t Size >
constexpr mat<bool, Size> approximately(T x, const mat<T, Size>& ys, T epsilon);
template < typename T, size_t Size >
constexpr mat<bool, Size> approximately(const mat<T, Size>& xs, const mat<T, Size>& ys, T epsilon);
``` ```
### Matrix Functions ### Matrix Functions

View File

@@ -399,46 +399,11 @@ namespace vmath_hpp
} }
// //
// Scalar Relational Functions // Relational Functions
// //
namespace vmath_hpp namespace vmath_hpp
{ {
template < typename T >
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
constexpr equal_to(T x, T y) noexcept {
if constexpr ( std::is_floating_point_v<T> ) {
// http://www.realtimecollisiondetection.net/pubs/Tolerances
const T epsilon = std::numeric_limits<T>::epsilon();
return abs(x - y) <= epsilon * max(T(1), abs(x), abs(y));
} else {
return x == y;
}
}
template < typename T >
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
constexpr equal_to(T x, T y, T epsilon) noexcept {
if constexpr ( std::is_floating_point_v<T> ) {
// http://www.realtimecollisiondetection.net/pubs/Tolerances
return abs(x - y) <= epsilon * 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 not_equal_to(T x, T y) noexcept {
return !equal_to(x, y);
}
template < typename T >
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
constexpr not_equal_to(T x, T y, T epsilon) noexcept {
return !equal_to(x, y, epsilon);
}
template < typename T > template < typename T >
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool> [[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
constexpr any(T x) noexcept { constexpr any(T x) noexcept {
@@ -450,4 +415,27 @@ namespace vmath_hpp
constexpr all(T x) noexcept { constexpr all(T x) noexcept {
return !!x; return !!x;
} }
template < typename T >
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
constexpr approximately(T x, T y) noexcept {
if constexpr ( std::is_floating_point_v<T> ) {
// http://www.realtimecollisiondetection.net/pubs/Tolerances
const T epsilon = std::numeric_limits<T>::epsilon();
return abs(x - y) <= epsilon * max(T(1), abs(x), abs(y));
} else {
return x == y;
}
}
template < typename T >
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
constexpr approximately(T x, T y, T epsilon) noexcept {
if constexpr ( std::is_floating_point_v<T> ) {
// http://www.realtimecollisiondetection.net/pubs/Tolerances
return abs(x - y) <= epsilon * max(T(1), abs(x), abs(y));
} else {
return abs(x - y) <= epsilon;
}
}
} }

View File

@@ -544,6 +544,53 @@ namespace vmath_hpp
} }
} }
//
// Relational Functions
//
namespace vmath_hpp
{
template < typename T, std::size_t Size >
[[nodiscard]] constexpr bool any(const mat<T, Size>& xs) {
return fold_join([](bool acc, const vec<T, Size>& x){ return acc || any(x); }, false, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr bool all(const mat<T, Size>& xs) {
return fold_join([](bool acc, const vec<T, Size>& x){ return acc && all(x); }, true, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<bool, Size> approximately(const mat<T, Size>& xs, T y) {
return map_join([y](const vec<T, Size>& x){ return approximately(x, y); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<bool, Size> approximately(T x, const mat<T, Size>& ys) {
return map_join([x](const vec<T, Size>& y){ return approximately(x, y); }, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<bool, Size> approximately(const mat<T, Size>& xs, const mat<T, Size>& ys) {
return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return approximately(x, y); }, xs, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<bool, Size> approximately(const mat<T, Size>& xs, T y, T epsilon) {
return map_join([y, epsilon](const vec<T, Size>& x){ return approximately(x, y, epsilon); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<bool, Size> approximately(T x, const mat<T, Size>& ys, T epsilon) {
return map_join([x, epsilon](const vec<T, Size>& y){ return approximately(x, y, epsilon); }, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr mat<bool, Size> approximately(const mat<T, Size>& xs, const mat<T, Size>& ys, T epsilon) {
return map_join([epsilon](const vec<T, Size>& x, const vec<T, Size>& y){ return approximately(x, y, epsilon); }, xs, ys);
}
}
// //
// Matrix Functions // Matrix Functions
// //

View File

@@ -898,77 +898,11 @@ namespace vmath_hpp
} }
// //
// Vector Relational Functions // Relational Functions
// //
namespace vmath_hpp namespace vmath_hpp
{ {
// equal_to
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> equal_to(const vec<T, Size>& xs, T y) {
return map_join([y](T x){ return equal_to(x, y); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> equal_to(T x, const vec<T, Size>& ys) {
return map_join([x](T y){ return equal_to(x, y); }, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return map_join([](T x, T y){ return equal_to(x, y); }, xs, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> equal_to(const vec<T, Size>& xs, T y, T epsilon) {
return map_join([y, epsilon](T x){ return equal_to(x, y, epsilon); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> equal_to(T x, const vec<T, Size>& ys, T epsilon) {
return map_join([x, epsilon](T y){ return equal_to(x, y, epsilon); }, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys, T epsilon) {
return map_join([epsilon](T x, T y){ return equal_to(x, y, epsilon); }, xs, ys);
}
// not_equal_to
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> not_equal_to(const vec<T, Size>& xs, T y) {
return map_join([y](T x){ return not_equal_to(x, y); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> not_equal_to(T x, const vec<T, Size>& ys) {
return map_join([x](T y){ return not_equal_to(x, y); }, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> not_equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return map_join([](T x, T y){ return not_equal_to(x, y); }, xs, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> not_equal_to(const vec<T, Size>& xs, T y, T epsilon) {
return map_join([y, epsilon](T x){ return not_equal_to(x, y, epsilon); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> not_equal_to(T x, const vec<T, Size>& ys, T epsilon) {
return map_join([x, epsilon](T y){ return not_equal_to(x, y, epsilon); }, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> not_equal_to(const vec<T, Size>& xs, const vec<T, Size>& ys, T epsilon) {
return map_join([epsilon](T x, T y){ return not_equal_to(x, y, epsilon); }, xs, ys);
}
// any/all
template < typename T, std::size_t Size > template < typename T, std::size_t Size >
[[nodiscard]] constexpr bool any(const vec<T, Size>& xs) { [[nodiscard]] constexpr bool any(const vec<T, Size>& xs) {
return fold_join([](bool acc, T x){ return acc || any(x); }, false, xs); return fold_join([](bool acc, T x){ return acc || any(x); }, false, xs);
@@ -978,4 +912,34 @@ namespace vmath_hpp
[[nodiscard]] constexpr bool all(const vec<T, Size>& xs) { [[nodiscard]] constexpr bool all(const vec<T, Size>& xs) {
return fold_join([](bool acc, T x){ return acc && all(x); }, true, xs); return fold_join([](bool acc, T x){ return acc && all(x); }, true, xs);
} }
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> approximately(const vec<T, Size>& xs, T y) {
return map_join([y](T x){ return approximately(x, y); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> approximately(T x, const vec<T, Size>& ys) {
return map_join([x](T y){ return approximately(x, y); }, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> approximately(const vec<T, Size>& xs, const vec<T, Size>& ys) {
return map_join([](T x, T y){ return approximately(x, y); }, xs, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> approximately(const vec<T, Size>& xs, T y, T epsilon) {
return map_join([y, epsilon](T x){ return approximately(x, y, epsilon); }, xs);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> approximately(T x, const vec<T, Size>& ys, T epsilon) {
return map_join([x, epsilon](T y){ return approximately(x, y, epsilon); }, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<bool, Size> approximately(const vec<T, Size>& xs, const vec<T, Size>& ys, T epsilon) {
return map_join([epsilon](T x, T y){ return approximately(x, y, epsilon); }, xs, ys);
}
} }

View File

@@ -142,29 +142,7 @@ TEST_CASE("vmath/fun") {
REQUIRE(refract(1.f, 2.f, 1.f) == approx(-7.f)); REQUIRE(refract(1.f, 2.f, 1.f) == approx(-7.f));
} }
SUBCASE("Scalar Relational Functions") { SUBCASE("Relational Functions") {
STATIC_REQUIRE(equal_to(1, 1));
STATIC_REQUIRE_FALSE(equal_to(0, 1));
STATIC_REQUIRE_FALSE(equal_to(0, 1, 0));
STATIC_REQUIRE(equal_to(0, 1, 1));
STATIC_REQUIRE(not_equal_to(0, 1));
STATIC_REQUIRE(not_equal_to(0, 1, 0));
STATIC_REQUIRE_FALSE(not_equal_to(0, 1, 1));
STATIC_REQUIRE_FALSE(not_equal_to(1, 1));
STATIC_REQUIRE_FALSE(not_equal_to(1, 1, 0));
STATIC_REQUIRE_FALSE(not_equal_to(1, 1, 1));
STATIC_REQUIRE(equal_to(1.f, 1.f + std::numeric_limits<float>::epsilon() * 0.5f));
STATIC_REQUIRE_FALSE(equal_to(1.f, 1.f + std::numeric_limits<float>::epsilon() * 1.5f));
STATIC_REQUIRE(equal_to(100.f, 100.f + std::numeric_limits<float>::epsilon() * 90.f));
STATIC_REQUIRE_FALSE(equal_to(100.f, 100.f + std::numeric_limits<float>::epsilon() * 110.f));
STATIC_REQUIRE_FALSE(not_equal_to(1.f, 1.f + std::numeric_limits<float>::epsilon() * 0.5f));
STATIC_REQUIRE(not_equal_to(1.f, 1.f + std::numeric_limits<float>::epsilon() * 1.5f));
STATIC_REQUIRE_FALSE(not_equal_to(100.f, 100.f + std::numeric_limits<float>::epsilon() * 90.f));
STATIC_REQUIRE(not_equal_to(100.f, 100.f + std::numeric_limits<float>::epsilon() * 110.f));
STATIC_REQUIRE_FALSE(any(false)); STATIC_REQUIRE_FALSE(any(false));
STATIC_REQUIRE_FALSE(any(0)); STATIC_REQUIRE_FALSE(any(0));
STATIC_REQUIRE(any(true)); STATIC_REQUIRE(any(true));
@@ -174,5 +152,15 @@ TEST_CASE("vmath/fun") {
STATIC_REQUIRE_FALSE(all(0)); STATIC_REQUIRE_FALSE(all(0));
STATIC_REQUIRE(all(true)); STATIC_REQUIRE(all(true));
STATIC_REQUIRE(all(1)); STATIC_REQUIRE(all(1));
STATIC_REQUIRE(approximately(1, 1));
STATIC_REQUIRE_FALSE(approximately(0, 1));
STATIC_REQUIRE_FALSE(approximately(0, 1, 0));
STATIC_REQUIRE(approximately(0, 1, 1));
STATIC_REQUIRE(approximately(1.f, 1.f + std::numeric_limits<float>::epsilon() * 0.5f));
STATIC_REQUIRE_FALSE(approximately(1.f, 1.f + std::numeric_limits<float>::epsilon() * 1.5f));
STATIC_REQUIRE(approximately(100.f, 100.f + std::numeric_limits<float>::epsilon() * 90.f));
STATIC_REQUIRE_FALSE(approximately(100.f, 100.f + std::numeric_limits<float>::epsilon() * 110.f));
} }
} }

View File

@@ -181,6 +181,44 @@ TEST_CASE("vmath/mat_fun") {
STATIC_REQUIRE((1 >= int2x2(0,1,2,3)) == bool2x2(true, true, false, false)); STATIC_REQUIRE((1 >= int2x2(0,1,2,3)) == bool2x2(true, true, false, false));
} }
SUBCASE("relational functions") {
STATIC_REQUIRE_FALSE(any(bool2x2(false, false, false, false)));
STATIC_REQUIRE(any(bool2x2(true, false, true, false)));
STATIC_REQUIRE(any(bool2x2(false, true, false, true)));
STATIC_REQUIRE(any(bool2x2(true, true, true, true)));
STATIC_REQUIRE_FALSE(any(int2x2(0, 0, 0, 0)));
STATIC_REQUIRE(any(int2x2(1, 0, 1, 0)));
STATIC_REQUIRE(any(int2x2(0, 1, 0, 1)));
STATIC_REQUIRE(any(int2x2(1, 1, 1, 1)));
STATIC_REQUIRE_FALSE(all(bool2x2(false, false, false, false)));
STATIC_REQUIRE_FALSE(all(bool2x2(true, false, true, false)));
STATIC_REQUIRE_FALSE(all(bool2x2(false, true, false, true)));
STATIC_REQUIRE(all(bool2x2(true, true, true, true)));
STATIC_REQUIRE_FALSE(all(int2x2(0, 0, 0, 0)));
STATIC_REQUIRE_FALSE(all(int2x2(1, 0, 1, 0)));
STATIC_REQUIRE_FALSE(all(int2x2(0, 1, 0, 1)));
STATIC_REQUIRE(all(int2x2(1, 1, 1, 1)));
STATIC_REQUIRE(approximately(int2x2(1,1,1,1), int2x2(0,1,2,3)) == bool2x2(false, true, false, false));
STATIC_REQUIRE(approximately(int2x2(0,1,2,3),1) == bool2x2(false, true, false, false));
STATIC_REQUIRE(approximately(1,int2x2(0,1,2,3)) == bool2x2(false, true, false, false));
STATIC_REQUIRE(approximately(int2x2(1,1,1,1), int2x2(0,1,2,3), 0) == bool2x2(false, true, false, false));
STATIC_REQUIRE(approximately(int2x2(0,1,2,3), 1, 0) == bool2x2(false, true, false, false));
STATIC_REQUIRE(approximately(1, int2x2(0,1,2,3), 0) == bool2x2(false, true, false, false));
STATIC_REQUIRE(approximately(int2x2(1,1,1,1), int2x2(0,1,2,3), 1) == bool2x2(true, true, true, false));
STATIC_REQUIRE(approximately(int2x2(0,1,2,3), 1, 1) == bool2x2(true, true, true, false));
STATIC_REQUIRE(approximately(1, int2x2(0,1,2,3), 1) == bool2x2(true, true, true, false));
STATIC_REQUIRE(approximately(int2x2(1,1,1,1), int2x2(0,1,2,3), 2) == bool2x2(true, true, true, true));
STATIC_REQUIRE(approximately(int2x2(0,1,2,3), 1, 2) == bool2x2(true, true, true, true));
STATIC_REQUIRE(approximately(1, int2x2(0,1,2,3), 2) == bool2x2(true, true, true, true));
}
SUBCASE("transpose") { SUBCASE("transpose") {
STATIC_REQUIRE(transpose(int2x2( STATIC_REQUIRE(transpose(int2x2(
1, 2, 1, 2,
@@ -242,7 +280,7 @@ TEST_CASE("vmath/mat_fun") {
{ {
constexpr float4x4 m1 = translate(float3(1.f, 2.f, 3.f)); constexpr float4x4 m1 = translate(float3(1.f, 2.f, 3.f));
constexpr float4x4 rm1 = inverse(m1); constexpr float4x4 rm1 = inverse(m1);
STATIC_REQUIRE(all(equal_to( STATIC_REQUIRE(all(approximately(
unit4_z<float> * m1 * rm1, unit4_z<float> * m1 * rm1,
unit4_z<float>, unit4_z<float>,
approx_epsilon_v<float>))); approx_epsilon_v<float>)));
@@ -252,7 +290,7 @@ TEST_CASE("vmath/mat_fun") {
const float3 axis2 = normalize(float3(1.f, 2.f, 3.f)); const float3 axis2 = normalize(float3(1.f, 2.f, 3.f));
const float4x4 m2 = rotate(0.5f,axis2); const float4x4 m2 = rotate(0.5f,axis2);
const float4x4 rm2 = inverse(m2); const float4x4 rm2 = inverse(m2);
REQUIRE(all(equal_to( REQUIRE(all(approximately(
unit4_z<float> * m2 * rm2, unit4_z<float> * m2 * rm2,
unit4_z<float>, unit4_z<float>,
approx_epsilon_v<float>))); approx_epsilon_v<float>)));
@@ -262,7 +300,7 @@ TEST_CASE("vmath/mat_fun") {
const float3 axis3 = normalize(float3(1.f, 2.f, 3.f)); const float3 axis3 = normalize(float3(1.f, 2.f, 3.f));
const float3x3 m3 = float3x3(rotate(0.5f,axis3)); const float3x3 m3 = float3x3(rotate(0.5f,axis3));
const float3x3 rm3 = inverse(m3); const float3x3 rm3 = inverse(m3);
REQUIRE(all(equal_to( REQUIRE(all(approximately(
unit3_z<float> * m3 * rm3, unit3_z<float> * m3 * rm3,
unit3_z<float>, unit3_z<float>,
approx_epsilon_v<float>))); approx_epsilon_v<float>)));
@@ -272,7 +310,7 @@ TEST_CASE("vmath/mat_fun") {
const float3 axis4 = normalize(float3(0.f, 0.f, 3.f)); const float3 axis4 = normalize(float3(0.f, 0.f, 3.f));
const float2x2 m4 = float2x2(rotate(0.5f,axis4)); const float2x2 m4 = float2x2(rotate(0.5f,axis4));
const float2x2 rm4 = inverse(m4); const float2x2 rm4 = inverse(m4);
REQUIRE(all(equal_to( REQUIRE(all(approximately(
unit2_y<float> * m4 * rm4, unit2_y<float> * m4 * rm4,
unit2_y<float>, unit2_y<float>,
approx_epsilon_v<float>))); approx_epsilon_v<float>)));

View File

@@ -73,21 +73,21 @@ namespace vmath_tests
template < typename T > template < typename T >
constexpr bool operator==(const T& l, const approx<T>& r) { constexpr bool operator==(const T& l, const approx<T>& r) {
return equal_to(l, r.value, approx_epsilon_v<T>); return approximately(l, r.value, approx_epsilon_v<T>);
} }
template < typename T > template < typename T >
constexpr bool operator==(const vec<T, 2>& l, const approx2<T>& r) { constexpr bool operator==(const vec<T, 2>& l, const approx2<T>& r) {
return all(equal_to(l, r.value, approx_epsilon_v<T>)); return all(approximately(l, r.value, approx_epsilon_v<T>));
} }
template < typename T > template < typename T >
constexpr bool operator==(const vec<T, 3>& l, const approx3<T>& r) { constexpr bool operator==(const vec<T, 3>& l, const approx3<T>& r) {
return all(equal_to(l, r.value, approx_epsilon_v<T>)); return all(approximately(l, r.value, approx_epsilon_v<T>));
} }
template < typename T > template < typename T >
constexpr bool operator==(const vec<T, 4>& l, const approx4<T>& r) { constexpr bool operator==(const vec<T, 4>& l, const approx4<T>& r) {
return all(equal_to(l, r.value, approx_epsilon_v<T>)); return all(approximately(l, r.value, approx_epsilon_v<T>));
} }
} }

View File

@@ -268,39 +268,7 @@ TEST_CASE("vmath/vec_fun") {
REQUIRE(refract(float2(1.f), float2(2.f), 1.f).x == approx(-15.f)); REQUIRE(refract(float2(1.f), float2(2.f), 1.f).x == approx(-15.f));
} }
SUBCASE("Vector Relational Functions") { SUBCASE("Relational Functions") {
STATIC_REQUIRE(equal_to(int3(1,1,1), int3(0,1,2)) == bool3(false, true, false));
STATIC_REQUIRE(equal_to(int3(0,1,2),1) == bool3(false, true, false));
STATIC_REQUIRE(equal_to(1,int3(0,1,2)) == bool3(false, true, false));
STATIC_REQUIRE(equal_to(int4(1,1,1,1), int4(0,1,2,3), 0) == bool4(false, true, false, false));
STATIC_REQUIRE(equal_to(int4(0,1,2,3), 1, 0) == bool4(false, true, false, false));
STATIC_REQUIRE(equal_to(1, int4(0,1,2,3), 0) == bool4(false, true, false, false));
STATIC_REQUIRE(equal_to(int4(1,1,1,1), int4(0,1,2,3), 1) == bool4(true, true, true, false));
STATIC_REQUIRE(equal_to(int4(0,1,2,3), 1, 1) == bool4(true, true, true, false));
STATIC_REQUIRE(equal_to(1, int4(0,1,2,3), 1) == bool4(true, true, true, false));
STATIC_REQUIRE(equal_to(int4(1,1,1,1), int4(0,1,2,3), 2) == bool4(true, true, true, true));
STATIC_REQUIRE(equal_to(int4(0,1,2,3), 1, 2) == bool4(true, true, true, true));
STATIC_REQUIRE(equal_to(1, int4(0,1,2,3), 2) == bool4(true, true, true, true));
STATIC_REQUIRE(not_equal_to(int3(1,1,1), int3(0,1,2)) == bool3(true, false, true));
STATIC_REQUIRE(not_equal_to(int3(0,1,2),1) == bool3(true, false, true));
STATIC_REQUIRE(not_equal_to(1,int3(0,1,2)) == bool3(true, false, true));
STATIC_REQUIRE(not_equal_to(int4(1,1,1,1), int4(0,1,2,3), 0) == bool4(true, false, true, true));
STATIC_REQUIRE(not_equal_to(int4(0,1,2,3), 1, 0) == bool4(true, false, true, true));
STATIC_REQUIRE(not_equal_to(1, int4(0,1,2,3), 0) == bool4(true, false, true, true));
STATIC_REQUIRE(not_equal_to(int4(1,1,1,1), int4(0,1,2,3), 1) == bool4(false, false, false, true));
STATIC_REQUIRE(not_equal_to(int4(0,1,2,3), 1, 1) == bool4(false, false, false, true));
STATIC_REQUIRE(not_equal_to(1, int4(0,1,2,3), 1) == bool4(false, false, false, true));
STATIC_REQUIRE(not_equal_to(int4(1,1,1,1), int4(0,1,2,3), 2) == bool4(false, false, false, false));
STATIC_REQUIRE(not_equal_to(int4(0,1,2,3), 1, 2) == bool4(false, false, false, false));
STATIC_REQUIRE(not_equal_to(1, int4(0,1,2,3), 2) == bool4(false, false, false, false));
STATIC_REQUIRE_FALSE(any(bool2(false, false))); STATIC_REQUIRE_FALSE(any(bool2(false, false)));
STATIC_REQUIRE(any(bool2(true, false))); STATIC_REQUIRE(any(bool2(true, false)));
STATIC_REQUIRE(any(bool2(false, true))); STATIC_REQUIRE(any(bool2(false, true)));
@@ -320,5 +288,21 @@ TEST_CASE("vmath/vec_fun") {
STATIC_REQUIRE_FALSE(all(int2(1, 0))); STATIC_REQUIRE_FALSE(all(int2(1, 0)));
STATIC_REQUIRE_FALSE(all(int2(0, 1))); STATIC_REQUIRE_FALSE(all(int2(0, 1)));
STATIC_REQUIRE(all(int2(1, 1))); STATIC_REQUIRE(all(int2(1, 1)));
STATIC_REQUIRE(approximately(int3(1,1,1), int3(0,1,2)) == bool3(false, true, false));
STATIC_REQUIRE(approximately(int3(0,1,2),1) == bool3(false, true, false));
STATIC_REQUIRE(approximately(1,int3(0,1,2)) == bool3(false, true, false));
STATIC_REQUIRE(approximately(int4(1,1,1,1), int4(0,1,2,3), 0) == bool4(false, true, false, false));
STATIC_REQUIRE(approximately(int4(0,1,2,3), 1, 0) == bool4(false, true, false, false));
STATIC_REQUIRE(approximately(1, int4(0,1,2,3), 0) == bool4(false, true, false, false));
STATIC_REQUIRE(approximately(int4(1,1,1,1), int4(0,1,2,3), 1) == bool4(true, true, true, false));
STATIC_REQUIRE(approximately(int4(0,1,2,3), 1, 1) == bool4(true, true, true, false));
STATIC_REQUIRE(approximately(1, int4(0,1,2,3), 1) == bool4(true, true, true, false));
STATIC_REQUIRE(approximately(int4(1,1,1,1), int4(0,1,2,3), 2) == bool4(true, true, true, true));
STATIC_REQUIRE(approximately(int4(0,1,2,3), 1, 2) == bool4(true, true, true, true));
STATIC_REQUIRE(approximately(1, int4(0,1,2,3), 2) == bool4(true, true, true, true));
} }
} }