Mathter
A configurable 3D math library for game developers.
Approx.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 
4 // Specialization for floats.
5 #include "../IoStream.hpp"
6 #include "../Matrix.hpp"
7 #include "../Vector.hpp"
8 
9 #include <type_traits>
10 
11 namespace mathter {
12 
13 
14 template <class T>
15 bool AlmostEqual(T d1, T d2, std::true_type) {
16  if (std::abs(d1) < 1e-38 && std::abs(d2) < 1e-38) {
17  return true;
18  }
19  if ((d1 == 0 && d2 < 1e-4) || (d2 == 0 && d1 < 1e-4)) {
20  return true;
21  }
22  T scaler = pow(T(10), floor(std::log10(std::abs(d1))));
23  d1 /= scaler;
24  d2 /= scaler;
25  d1 *= T(1000.0);
26  d2 *= T(1000.0);
27  return round(d1) == round(d2);
28 }
29 
30 // Specialization for int, complex and custom types: simple equality.
31 template <class T>
32 bool AlmostEqual(T d1, T d2, std::false_type) {
33  return d1 == d2;
34 }
35 
36 // Check equivalence with tolerance.
37 template <class T, class = std::enable_if_t<traits::NotVector<T>::value && traits::NotMatrix<T>::value && traits::NotQuaternion<T>::value>>
38 bool AlmostEqual(T d1, T d2) {
39  return AlmostEqual(d1, d2, std::integral_constant<bool, std::is_floating_point<T>::value>());
40 }
41 
42 template <class T, int Dim, bool Packed1, bool Packed2>
44  bool eq = true;
45  for (auto i : Range(Dim)) {
46  eq = eq && AlmostEqual(lhs[i], rhs[i]);
47  }
48  return eq;
49 }
50 
51 template <class T, bool Packed1, bool Packed2>
53  bool eq = true;
54  for (auto i : Range(4)) {
55  eq = eq && AlmostEqual(lhs.vec[i], rhs.vec[i]);
56  }
57  return eq;
58 }
59 
60 template <class T,
61  int Rows,
62  int Columns,
63  eMatrixOrder Order1,
64  eMatrixLayout Layout1,
65  bool Packed1,
66  eMatrixOrder Order2,
67  eMatrixLayout Layout2,
68  bool Packed2>
70  bool eq = true;
71  for (auto i : Range(Rows)) {
72  for (auto j : Range(Columns)) {
73  eq = eq && AlmostEqual(lhs(i, j), rhs(i, j));
74  }
75  }
76  return eq;
77 }
78 
79 
80 // Floating point comparison helper class, works like Catch2 units testing framework's float Approx.
81 template <class LinalgClass>
82 struct ApproxHelper {
84  explicit ApproxHelper(LinalgClass object) {
85  this->object = object;
86  }
87  LinalgClass object;
88 };
89 
90 
91 template <class LinalgClass1, class LinalgClass2>
92 bool operator==(const ApproxHelper<LinalgClass1>& lhs, const LinalgClass2& rhs) {
93  return AlmostEqual(lhs.object, rhs);
94 }
95 
96 template <class LinalgClass1, class LinalgClass2>
97 bool operator==(const LinalgClass1& lhs, const ApproxHelper<LinalgClass2>& rhs) {
98  return AlmostEqual(rhs.object, lhs);
99 }
100 
101 template <class LinalgClass1, class LinalgClass2>
103  return AlmostEqual(lhs.object, rhs.object);
104 }
105 
106 template <class LinalgClass>
107 std::ostream& operator<<(std::ostream& os, const ApproxHelper<LinalgClass>& arg) {
108  os << arg.object;
109  return os;
110 }
111 
112 template <class LinalgClass>
113 ApproxHelper<LinalgClass> ApproxVec(const LinalgClass& arg) {
114  return ApproxHelper<LinalgClass>{ arg };
115 }
116 
117 
118 
119 } // namespace mathter
ApproxHelper()
Definition: Approx.hpp:83
Allows you to do quaternion math and represent rotation in a compact way.
Definition: Definitions.hpp:69
ApproxHelper(LinalgClass object)
Definition: Approx.hpp:84
ApproxHelper< LinalgClass > ApproxVec(const LinalgClass &arg)
Definition: Approx.hpp:113
bool operator==(const ApproxHelper< LinalgClass1 > &lhs, const LinalgClass2 &rhs)
Definition: Approx.hpp:92
Represents a vector in N-dimensional space.
Definition: Definitions.hpp:57
LinalgClass object
Definition: Approx.hpp:87
Definition: Approx.hpp:11
Definition: Approx.hpp:82
Definition: Traits.hpp:152
Definition: Definitions.hpp:63
Definition: Traits.hpp:178
RangeHelper< T > Range(T first, T last, T step)
Definition: Range.hpp:54
bool AlmostEqual(T d1, T d2, std::true_type)
Definition: Approx.hpp:15
Vector< T, 4, Packed > vec
Definition: QuaternionImpl.hpp:41
eMatrixOrder
Determines if you want to left- or right-multiply your matrices with vectors.
Definition: Definitions.hpp:22
eMatrixLayout
Determines the memory layout of matrices.
Definition: Definitions.hpp:36