Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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  constexpr Matrix3x3T operator*(const Matrix3x3T &rhs) const {
99  return Matrix3x3T {{
100  (*this)(0, 0) * rhs(0, 0) + (*this)(0, 1) * rhs(1, 0) + (*this)(0, 2) * rhs(2, 0),
101  (*this)(0, 0) * rhs(0, 1) + (*this)(0, 1) * rhs(1, 1) + (*this)(0, 2) * rhs(2, 1),
102  (*this)(0, 0) * rhs(0, 2) + (*this)(0, 1) * rhs(1, 2) + (*this)(0, 2) * rhs(2, 2),
103 
104  (*this)(1, 0) * rhs(0, 0) + (*this)(1, 1) * rhs(1, 0) + (*this)(1, 2) * rhs(2, 0),
105  (*this)(1, 0) * rhs(0, 1) + (*this)(1, 1) * rhs(1, 1) + (*this)(1, 2) * rhs(2, 1),
106  (*this)(1, 0) * rhs(0, 2) + (*this)(1, 1) * rhs(1, 2) + (*this)(1, 2) * rhs(2, 2),
107 
108  (*this)(2, 0) * rhs(0, 0) + (*this)(2, 1) * rhs(1, 0) + (*this)(2, 2) * rhs(2, 0),
109  (*this)(2, 0) * rhs(0, 1) + (*this)(2, 1) * rhs(1, 1) + (*this)(2, 2) * rhs(2, 1),
110  (*this)(2, 0) * rhs(0, 2) + (*this)(2, 1) * rhs(1, 2) + (*this)(2, 2) * rhs(2, 2),
111  }};
112  }
113 
114  constexpr Vec3 operator*(const Vec3 &rhs) const {
115  return Vec3(
116  (*this)(0, 0) * rhs[0] + (*this)(0, 1) * rhs[1] + (*this)(0, 2) * rhs[2],
117  (*this)(1, 0) * rhs[0] + (*this)(1, 1) * rhs[1] + (*this)(1, 2) * rhs[2],
118  (*this)(2, 0) * rhs[0] + (*this)(2, 1) * rhs[1] + (*this)(2, 2) * rhs[2]
119  );
120  }
121 
122  constexpr friend Vec3 operator*(Vec3 v, const Matrix3x3T &rhs) {
123  return Vec3(
124  rhs(0, 0) * v[0] + rhs(0, 1) * v[1] + rhs(0, 2) * v[2],
125  rhs(1, 0) * v[0] + rhs(1, 1) * v[1] + rhs(1, 2) * v[2],
126  rhs(2, 0) * v[0] + rhs(2, 1) * v[1] + rhs(2, 2) * v[2]
127  );
128  }
129 
130  constexpr Matrix3x3T operator*(Scalar c) const {
131  return Matrix3x3T {{
132  (*this)[0] * c, (*this)[1] * c, (*this)[2] * c,
133  (*this)[3] * c, (*this)[4] * c, (*this)[5] * c,
134  (*this)[6] * c, (*this)[7] * c, (*this)[8] * c,
135  }};
136  }
137 
138  constexpr friend Matrix3x3T operator*(Scalar c, const Matrix3x3T &rhs) {
139  return Matrix3x3T {{
140  rhs[0] * c, rhs[1] * c, rhs[2] * c,
141  rhs[3] * c, rhs[4] * c, rhs[5] * c,
142  rhs[6] * c, rhs[7] * c, rhs[8] * c,
143  }};
144  }
145 
146  constexpr Matrix3x3T operator+ (const Matrix3x3T &rhs) const {
147  return Matrix3x3T {{
148  (*this)[0] + rhs[0], (*this)[1] + rhs[1], (*this)[2] + rhs[2],
149  (*this)[3] + rhs[3], (*this)[4] + rhs[4], (*this)[5] + rhs[5],
150  (*this)[6] + rhs[6], (*this)[7] + rhs[7], (*this)[8] + rhs[8],
151  }};
152  }
153 
154  constexpr Matrix3x3T operator- (const Matrix3x3T &rhs) const {
155  return Matrix3x3T {{
156  (*this)[0] - rhs[0], (*this)[1] - rhs[1], (*this)[2] - rhs[2],
157  (*this)[3] - rhs[3], (*this)[4] - rhs[4], (*this)[5] - rhs[5],
158  (*this)[6] - rhs[6], (*this)[7] - rhs[7], (*this)[8] - rhs[8],
159  }};
160  }
161 
162  constexpr Matrix3x3T operator- () const {
163  return Matrix3x3T {{
164  -values_[0], -values_[1], -values_[2],
165  -values_[3], -values_[4], -values_[5],
166  -values_[6], -values_[7], -values_[8]
167  }};
168  }
169 
170  const Matrix3x3T &operator*=(const Matrix3x3T &rhs) {
171  (*this) = operator*(rhs);
172  return *this;
173  }
174 
175  constexpr Scalar det() const {
176  return (*this)(0, 0) * ((*this)(1, 1) * (*this)(2, 2) - (*this)(2, 1) * (*this)(1, 2)) -
177  (*this)(0, 1) * ((*this)(1, 0) * (*this)(2, 2) - (*this)(1, 2) * (*this)(2, 0)) +
178  (*this)(0, 2) * ((*this)(1, 0) * (*this)(2, 1) - (*this)(1, 1) * (*this)(2, 0));
179 
180  /*
181  return (*this)(0, 0) * (*this)(1, 1) * (*this)(2, 2) +
182  (*this)(1, 0) * (*this)(2, 1) * (*this)(0, 2) +
183  (*this)(2, 0) * (*this)(0, 1) * (*this)(1, 2) -
184  (*this)(0, 0) * (*this)(2, 1) * (*this)(1, 2) -
185  (*this)(2, 0) * (*this)(1, 1) * (*this)(0, 2) -
186  (*this)(1, 0) * (*this)(0, 1) * (*this)(2, 2)
187  */
188  }
189 
190  constexpr Scalar trace() const {
191  return (*this)[0] + (*this)[4] + (*this)[8];
192  }
193 
194  void transpose() {
195  std::swap(values_[1], values_[3]);
196  std::swap(values_[2], values_[6]);
197  std::swap(values_[5], values_[7]);
198  }
199 
200  constexpr Matrix3x3T transposed() const {
201  return Matrix3x3T {{
202  values_[0], values_[3], values_[6],
203  values_[1], values_[4], values_[7],
204  values_[2], values_[5], values_[8],
205  }};
206  }
207 
208  void invert() {
209  *this = inverse();
210  }
211 
212  Matrix3x3T inverse() const {
213  const Scalar invdet = 1.0 / det();
214  return Matrix3x3T {{
215  ((*this)(1, 1) * (*this)(2, 2) - (*this)(2, 1) * (*this)(1, 2)) * invdet,
216  ((*this)(0, 2) * (*this)(2, 1) - (*this)(0, 1) * (*this)(2, 2)) * invdet,
217  ((*this)(0, 1) * (*this)(1, 2) - (*this)(0, 2) * (*this)(1, 1)) * invdet,
218  ((*this)(1, 2) * (*this)(2, 0) - (*this)(1, 0) * (*this)(2, 2)) * invdet,
219  ((*this)(0, 0) * (*this)(2, 2) - (*this)(0, 2) * (*this)(2, 0)) * invdet,
220  ((*this)(1, 0) * (*this)(0, 2) - (*this)(0, 0) * (*this)(1, 2)) * invdet,
221  ((*this)(1, 0) * (*this)(2, 1) - (*this)(2, 0) * (*this)(1, 1)) * invdet,
222  ((*this)(2, 0) * (*this)(0, 1) - (*this)(0, 0) * (*this)(2, 1)) * invdet,
223  ((*this)(0, 0) * (*this)(1, 1) - (*this)(1, 0) * (*this)(0, 1)) * invdet,
224  }};
225  }
226 
227  constexpr Scalar frobeniusSquared() const {
228  return std::inner_product(
229  values_.begin(), values_.end(), values_.begin(), Scalar(0.0));
230  }
231 
232  constexpr double frobenius() const {
233  return std::sqrt(frobeniusSquared());
234  }
235 
236 
237  friend
238  std::ostream &operator<< (std::ostream &os, const Matrix3x3T &m) {
239  os << "[[" << m[0] << ", " << m[1] << ", " << m[2] << "], "
240  "[" << m[3] << ", " << m[4] << ", " << m[5] << "], "
241  "[" << m[6] << ", " << m[7] << ", " << m[8] << "]]";
242  return os;
243  }
244 
245  private:
246  std::array<Scalar, 9> values_;
247 };
248 
249 typedef Matrix3x3T<float> Matrix3x3f;
250 typedef Matrix3x3T<double> Matrix3x3d;
251 
252 } /* namespace ACG */
253 
254 #if defined(_MSC_VER) && _MSC_VER < 1900
255 #undef constexpr
256 #endif
257 
258 #endif /* ACG_MATH_MATRIX3X3T_HH_ */
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
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
constexpr Matrix3x3T(std::array< Scalar, 9 > row_major)
Definition: Matrix3x3T.hh:63
STL namespace.