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