Developer Documentation
Matrix3x3T.hh
1 #ifndef ACG_MATH_MATRIX3X3T_HH_
2 #define ACG_MATH_MATRIX3X3T_HH_
3 
4 #include <array>
5 #include <ostream>
6 #include <ACG/Math/VectorT.hh>
7 #include <algorithm>
8 #include <cmath>
9 
10 #if defined(_MSC_VER) && _MSC_VER < 1900
11 #define constexpr
12 typedef unsigned char uint_fast8_t;
13 #endif
14 
15 namespace ACG {
16 
20 template<typename Scalar>
21 class Matrix3x3T {
22  public:
23  typedef typename OpenMesh::VectorT<Scalar, 3> Vec3;
24 
25  static Matrix3x3T<Scalar> fromColumns(Vec3 c1, Vec3 c2, Vec3 c3) {
26  return Matrix3x3T<Scalar> {{
27  c1[0], c2[0], c3[0],
28  c1[1], c2[1], c3[1],
29  c1[2], c2[2], c3[2],
30  }};
31  }
32 
33  static Matrix3x3T<Scalar> fromRows(Vec3 r1, Vec3 r2, Vec3 r3) {
34  return Matrix3x3T<Scalar> {{
35  r1[0], r1[1], r1[2],
36  r2[0], r2[1], r2[2],
37  r3[0], r3[1], r3[2]
38  }};
39  }
40 
41  static constexpr Matrix3x3T<Scalar> identity() {
42  return {{
43  1, 0, 0,
44  0, 1, 0,
45  0, 0, 1
46  }};
47  }
48 
49  static constexpr Matrix3x3T<Scalar> zero() {
50  return {{
51  0, 0, 0,
52  0, 0, 0,
53  0, 0, 0
54  }};
55  }
56 
57  public:
58  Matrix3x3T() = default;
59 
63  constexpr Matrix3x3T(std::array<Scalar, 9> row_major) :
64  values_(std::move(row_major)) {}
65 
66  constexpr bool operator==(const Matrix3x3T &rhs) const {
67  return values_ == rhs.values_;
68  }
69 
70  //Matrix3x3T(std::initializer_list<Scalar> row_major) {
71  // static_assert(row_major.size() == 9, "Need exactly 9 values.");
72  // std::copy(row_major.begin(), row_major.end(), this->begin());
73  //}
74 
76  constexpr static uint_fast8_t indexof(uint_fast8_t r, uint_fast8_t c) {
77  return r*3+c;
78  }
79 
80  constexpr const Scalar &operator() (uint_fast8_t r, uint_fast8_t c) const {
81  return values_[indexof(r, c)];
82  }
83 
84  Scalar &operator() (uint_fast8_t r, uint_fast8_t c) {
85  return values_[indexof(r, c)];
86  }
87 
89  constexpr const Scalar &operator[] (uint_fast8_t i) const {
90  return values_[i];
91  }
92 
94  Scalar &operator[] (uint_fast8_t i) {
95  return values_[i];
96  }
97 
98  Vec3 getRow(uint_fast8_t r) const {
99  return Vec3((*this)(r,0), (*this)(r,1), (*this)(r,2));
100  }
101  Vec3 getCol(uint_fast8_t c) const {
102  return Vec3((*this)(0,c), (*this)(1,c), (*this)(2,c));
103  }
104 
105  constexpr Matrix3x3T operator*(const Matrix3x3T &rhs) const {
106  return Matrix3x3T {{
107  (*this)(0, 0) * rhs(0, 0) + (*this)(0, 1) * rhs(1, 0) + (*this)(0, 2) * rhs(2, 0),
108  (*this)(0, 0) * rhs(0, 1) + (*this)(0, 1) * rhs(1, 1) + (*this)(0, 2) * rhs(2, 1),
109  (*this)(0, 0) * rhs(0, 2) + (*this)(0, 1) * rhs(1, 2) + (*this)(0, 2) * rhs(2, 2),
110 
111  (*this)(1, 0) * rhs(0, 0) + (*this)(1, 1) * rhs(1, 0) + (*this)(1, 2) * rhs(2, 0),
112  (*this)(1, 0) * rhs(0, 1) + (*this)(1, 1) * rhs(1, 1) + (*this)(1, 2) * rhs(2, 1),
113  (*this)(1, 0) * rhs(0, 2) + (*this)(1, 1) * rhs(1, 2) + (*this)(1, 2) * rhs(2, 2),
114 
115  (*this)(2, 0) * rhs(0, 0) + (*this)(2, 1) * rhs(1, 0) + (*this)(2, 2) * rhs(2, 0),
116  (*this)(2, 0) * rhs(0, 1) + (*this)(2, 1) * rhs(1, 1) + (*this)(2, 2) * rhs(2, 1),
117  (*this)(2, 0) * rhs(0, 2) + (*this)(2, 1) * rhs(1, 2) + (*this)(2, 2) * rhs(2, 2),
118  }};
119  }
120 
121  constexpr Vec3 operator*(const Vec3 &rhs) const {
122  return Vec3(
123  (*this)(0, 0) * rhs[0] + (*this)(0, 1) * rhs[1] + (*this)(0, 2) * rhs[2],
124  (*this)(1, 0) * rhs[0] + (*this)(1, 1) * rhs[1] + (*this)(1, 2) * rhs[2],
125  (*this)(2, 0) * rhs[0] + (*this)(2, 1) * rhs[1] + (*this)(2, 2) * rhs[2]
126  );
127  }
128 
129  constexpr friend Vec3 operator*(Vec3 v, const Matrix3x3T &rhs) {
130  return Vec3(
131  rhs(0, 0) * v[0] + rhs(0, 1) * v[1] + rhs(0, 2) * v[2],
132  rhs(1, 0) * v[0] + rhs(1, 1) * v[1] + rhs(1, 2) * v[2],
133  rhs(2, 0) * v[0] + rhs(2, 1) * v[1] + rhs(2, 2) * v[2]
134  );
135  }
136 
137  constexpr Matrix3x3T operator*(Scalar c) const {
138  return Matrix3x3T {{
139  (*this)[0] * c, (*this)[1] * c, (*this)[2] * c,
140  (*this)[3] * c, (*this)[4] * c, (*this)[5] * c,
141  (*this)[6] * c, (*this)[7] * c, (*this)[8] * c,
142  }};
143  }
144 
145  constexpr friend Matrix3x3T operator*(Scalar c, const Matrix3x3T &rhs) {
146  return Matrix3x3T {{
147  rhs[0] * c, rhs[1] * c, rhs[2] * c,
148  rhs[3] * c, rhs[4] * c, rhs[5] * c,
149  rhs[6] * c, rhs[7] * c, rhs[8] * c,
150  }};
151  }
152 
153  constexpr Matrix3x3T operator+ (const Matrix3x3T &rhs) const {
154  return Matrix3x3T {{
155  (*this)[0] + rhs[0], (*this)[1] + rhs[1], (*this)[2] + rhs[2],
156  (*this)[3] + rhs[3], (*this)[4] + rhs[4], (*this)[5] + rhs[5],
157  (*this)[6] + rhs[6], (*this)[7] + rhs[7], (*this)[8] + rhs[8],
158  }};
159  }
160 
161  constexpr Matrix3x3T operator- (const Matrix3x3T &rhs) const {
162  return Matrix3x3T {{
163  (*this)[0] - rhs[0], (*this)[1] - rhs[1], (*this)[2] - rhs[2],
164  (*this)[3] - rhs[3], (*this)[4] - rhs[4], (*this)[5] - rhs[5],
165  (*this)[6] - rhs[6], (*this)[7] - rhs[7], (*this)[8] - rhs[8],
166  }};
167  }
168 
169  constexpr Matrix3x3T operator- () const {
170  return Matrix3x3T {{
171  -values_[0], -values_[1], -values_[2],
172  -values_[3], -values_[4], -values_[5],
173  -values_[6], -values_[7], -values_[8]
174  }};
175  }
176 
177  const Matrix3x3T &operator*=(const Matrix3x3T &rhs) {
178  (*this) = operator*(rhs);
179  return *this;
180  }
181 
182  constexpr Scalar det() const {
183  return (*this)(0, 0) * ((*this)(1, 1) * (*this)(2, 2) - (*this)(2, 1) * (*this)(1, 2)) -
184  (*this)(0, 1) * ((*this)(1, 0) * (*this)(2, 2) - (*this)(1, 2) * (*this)(2, 0)) +
185  (*this)(0, 2) * ((*this)(1, 0) * (*this)(2, 1) - (*this)(1, 1) * (*this)(2, 0));
186 
187  /*
188  return (*this)(0, 0) * (*this)(1, 1) * (*this)(2, 2) +
189  (*this)(1, 0) * (*this)(2, 1) * (*this)(0, 2) +
190  (*this)(2, 0) * (*this)(0, 1) * (*this)(1, 2) -
191  (*this)(0, 0) * (*this)(2, 1) * (*this)(1, 2) -
192  (*this)(2, 0) * (*this)(1, 1) * (*this)(0, 2) -
193  (*this)(1, 0) * (*this)(0, 1) * (*this)(2, 2)
194  */
195  }
196 
197  constexpr Scalar trace() const {
198  return (*this)[0] + (*this)[4] + (*this)[8];
199  }
200 
201  void transpose() {
202  std::swap(values_[1], values_[3]);
203  std::swap(values_[2], values_[6]);
204  std::swap(values_[5], values_[7]);
205  }
206 
207  constexpr Matrix3x3T transposed() const {
208  return Matrix3x3T {{
209  values_[0], values_[3], values_[6],
210  values_[1], values_[4], values_[7],
211  values_[2], values_[5], values_[8],
212  }};
213  }
214 
215  void invert() {
216  *this = inverse();
217  }
218 
219  Matrix3x3T inverse() const {
220  const Scalar invdet = 1.0 / det();
221  return Matrix3x3T {{
222  ((*this)(1, 1) * (*this)(2, 2) - (*this)(2, 1) * (*this)(1, 2)) * invdet,
223  ((*this)(0, 2) * (*this)(2, 1) - (*this)(0, 1) * (*this)(2, 2)) * invdet,
224  ((*this)(0, 1) * (*this)(1, 2) - (*this)(0, 2) * (*this)(1, 1)) * invdet,
225  ((*this)(1, 2) * (*this)(2, 0) - (*this)(1, 0) * (*this)(2, 2)) * invdet,
226  ((*this)(0, 0) * (*this)(2, 2) - (*this)(0, 2) * (*this)(2, 0)) * invdet,
227  ((*this)(1, 0) * (*this)(0, 2) - (*this)(0, 0) * (*this)(1, 2)) * invdet,
228  ((*this)(1, 0) * (*this)(2, 1) - (*this)(2, 0) * (*this)(1, 1)) * invdet,
229  ((*this)(2, 0) * (*this)(0, 1) - (*this)(0, 0) * (*this)(2, 1)) * invdet,
230  ((*this)(0, 0) * (*this)(1, 1) - (*this)(1, 0) * (*this)(0, 1)) * invdet,
231  }};
232  }
233 
234  constexpr Scalar frobeniusSquared() const {
235  return std::inner_product(
236  values_.begin(), values_.end(), values_.begin(), Scalar(0.0));
237  }
238 
239  constexpr double frobenius() const {
240  return std::sqrt(frobeniusSquared());
241  }
242 
243 
244  friend
245  std::ostream &operator<< (std::ostream &os, const Matrix3x3T &m) {
246  os << "[[" << m[0] << ", " << m[1] << ", " << m[2] << "], "
247  "[" << m[3] << ", " << m[4] << ", " << m[5] << "], "
248  "[" << m[6] << ", " << m[7] << ", " << m[8] << "]]";
249  return os;
250  }
251 
252  private:
253  std::array<Scalar, 9> values_;
254 };
255 
258 
259 } /* namespace ACG */
260 
261 #if defined(_MSC_VER) && _MSC_VER < 1900
262 #undef constexpr
263 #endif
264 
265 #endif /* ACG_MATH_MATRIX3X3T_HH_ */
Namespace providing different geometric functions concerning angles.
STL namespace.
constexpr Matrix3x3T(std::array< Scalar, 9 > row_major)
Definition: Matrix3x3T.hh:63
static constexpr uint_fast8_t indexof(uint_fast8_t r, uint_fast8_t c)
Map row/column index to linearized index.
Definition: Matrix3x3T.hh:76
constexpr const Scalar & operator[](uint_fast8_t i) const
Linearized row major access.
Definition: Matrix3x3T.hh:89