19 #ifndef UTIL_MATH_MATRIX3X3_INL_H__ 20 #define UTIL_MATH_MATRIX3X3_INL_H__ 27 #include "util/math/mathutil.h" 28 #include "util/math/vector3-inl.h" 29 #include "util/math/matrix3x3.h" 30 #include "base/integral_types.h" 31 #include "base/logging.h" 33 template <
class VType>
42 m_[0][2] = m_[0][1] = m_[0][0] = VType();
43 m_[1][2] = m_[1][1] = m_[1][0] = VType();
44 m_[2][2] = m_[2][1] = m_[2][0] = VType();
49 Matrix3x3(
const VType &m00,
const VType &m01,
const VType &m02,
50 const VType &m10,
const VType &m11,
const VType &m12,
51 const VType &m20,
const VType &m21,
const VType &m22) {
67 m_[0][0] = mb.m_[0][0];
68 m_[0][1] = mb.m_[0][1];
69 m_[0][2] = mb.m_[0][2];
71 m_[1][0] = mb.m_[1][0];
72 m_[1][1] = mb.m_[1][1];
73 m_[1][2] = mb.m_[1][2];
75 m_[2][0] = mb.m_[2][0];
76 m_[2][1] = mb.m_[2][1];
77 m_[2][2] = mb.m_[2][2];
81 template <
class VType2>
83 return Self(static_cast<VType>(mb(0, 0)),
84 static_cast<VType>(mb(0, 1)),
85 static_cast<VType>(mb(0, 2)),
86 static_cast<VType>(mb(1, 0)),
87 static_cast<VType>(mb(1, 1)),
88 static_cast<VType>(mb(1, 2)),
89 static_cast<VType>(mb(2, 0)),
90 static_cast<VType>(mb(2, 1)),
91 static_cast<VType>(mb(2, 2)));
96 Set(
const VType &m00,
const VType &m01,
const VType &m02,
97 const VType &m10,
const VType &m11,
const VType &m12,
98 const VType &m20,
const VType &m21,
const VType &m22) {
114 inline Self& operator=(
const Self &mb) {
115 m_[0][0] = mb.m_[0][0];
116 m_[0][1] = mb.m_[0][1];
117 m_[0][2] = mb.m_[0][2];
119 m_[1][0] = mb.m_[1][0];
120 m_[1][1] = mb.m_[1][1];
121 m_[1][2] = mb.m_[1][2];
123 m_[2][0] = mb.m_[2][0];
124 m_[2][1] = mb.m_[2][1];
125 m_[2][2] = mb.m_[2][2];
130 inline bool operator==(
const Self &mb)
const {
131 return (m_[0][0] == mb.m_[0][0]) &&
132 (m_[0][1] == mb.m_[0][1]) &&
133 (m_[0][2] == mb.m_[0][2]) &&
134 (m_[1][0] == mb.m_[1][0]) &&
135 (m_[1][1] == mb.m_[1][1]) &&
136 (m_[1][2] == mb.m_[1][2]) &&
137 (m_[2][0] == mb.m_[2][0]) &&
138 (m_[2][1] == mb.m_[2][1]) &&
139 (m_[2][2] == mb.m_[2][2]);
143 inline Self& operator+=(
const Self &mb) {
144 m_[0][0] += mb.m_[0][0];
145 m_[0][1] += mb.m_[0][1];
146 m_[0][2] += mb.m_[0][2];
148 m_[1][0] += mb.m_[1][0];
149 m_[1][1] += mb.m_[1][1];
150 m_[1][2] += mb.m_[1][2];
152 m_[2][0] += mb.m_[2][0];
153 m_[2][1] += mb.m_[2][1];
154 m_[2][2] += mb.m_[2][2];
159 inline Self& operator-=(
const Self &mb) {
160 m_[0][0] -= mb.m_[0][0];
161 m_[0][1] -= mb.m_[0][1];
162 m_[0][2] -= mb.m_[0][2];
164 m_[1][0] -= mb.m_[1][0];
165 m_[1][1] -= mb.m_[1][1];
166 m_[1][2] -= mb.m_[1][2];
168 m_[2][0] -= mb.m_[2][0];
169 m_[2][1] -= mb.m_[2][1];
170 m_[2][2] -= mb.m_[2][2];
175 inline Self& operator*=(
const VType &k) {
191 inline Self operator+(
const Self &mb)
const {
192 return Self(*
this) += mb;
196 inline Self operator-(
const Self &mb)
const {
197 return Self(*
this) -= mb;
201 friend inline Self operator-(
const Self &vb) {
202 return Self(-vb.m_[0][0], -vb.m_[0][1], -vb.m_[0][2],
203 -vb.m_[1][0], -vb.m_[1][1], -vb.m_[1][2],
204 -vb.m_[2][0], -vb.m_[2][1], -vb.m_[2][2]);
208 inline Self operator*(
const VType &k)
const {
209 return Self(*
this) *= k;
212 friend inline Self operator*(
const VType &k,
const Self &mb) {
217 inline Self operator*(
const Self &mb)
const {
219 m_[0][0] * mb.m_[0][0] + m_[0][1] * mb.m_[1][0] + m_[0][2] * mb.m_[2][0],
220 m_[0][0] * mb.m_[0][1] + m_[0][1] * mb.m_[1][1] + m_[0][2] * mb.m_[2][1],
221 m_[0][0] * mb.m_[0][2] + m_[0][1] * mb.m_[1][2] + m_[0][2] * mb.m_[2][2],
223 m_[1][0] * mb.m_[0][0] + m_[1][1] * mb.m_[1][0] + m_[1][2] * mb.m_[2][0],
224 m_[1][0] * mb.m_[0][1] + m_[1][1] * mb.m_[1][1] + m_[1][2] * mb.m_[2][1],
225 m_[1][0] * mb.m_[0][2] + m_[1][1] * mb.m_[1][2] + m_[1][2] * mb.m_[2][2],
227 m_[2][0] * mb.m_[0][0] + m_[2][1] * mb.m_[1][0] + m_[2][2] * mb.m_[2][0],
228 m_[2][0] * mb.m_[0][1] + m_[2][1] * mb.m_[1][1] + m_[2][2] * mb.m_[2][1],
229 m_[2][0] * mb.m_[0][2] + m_[2][1] * mb.m_[1][2] + m_[2][2] * mb.m_[2][2]);
235 m_[0][0] * v[0] + m_[0][1] * v[1] + m_[0][2] * v[2],
236 m_[1][0] * v[0] + m_[1][1] * v[1] + m_[1][2] * v[2],
237 m_[2][0] * v[0] + m_[2][1] * v[1] + m_[2][2] * v[2]);
241 inline VType Det(
void)
const {
242 return m_[0][0] * m_[1][1] * m_[2][2]
243 + m_[0][1] * m_[1][2] * m_[2][0]
244 + m_[0][2] * m_[1][0] * m_[2][1]
245 - m_[2][0] * m_[1][1] * m_[0][2]
246 - m_[2][1] * m_[1][2] * m_[0][0]
247 - m_[2][2] * m_[1][0] * m_[0][1];
251 inline VType Trace(
void)
const {
252 return m_[0][0] + m_[1][1] + m_[2][2];
258 return reinterpret_cast<VType*>(m_);
260 const VType* Data()
const {
261 return reinterpret_cast<const VType*>(m_);
265 inline VType &operator()(
const int i,
const int j) {
272 inline VType operator()(
const int i,
const int j)
const {
281 inline VType &operator[](
const int i) {
284 return reinterpret_cast<VType*>(m_)[i];
286 inline VType operator[](
const int i)
const {
289 return reinterpret_cast<const VType*>(m_)[i];
293 inline Self Transpose(
void)
const {
294 return Self(m_[0][0], m_[1][0], m_[2][0],
295 m_[0][1], m_[1][1], m_[2][1],
296 m_[0][2], m_[1][2], m_[2][2]);
301 inline Self ComatrixTransposed(
void)
const {
303 m_[1][1] * m_[2][2] - m_[2][1] * m_[1][2],
304 m_[2][1] * m_[0][2] - m_[0][1] * m_[2][2],
305 m_[0][1] * m_[1][2] - m_[1][1] * m_[0][2],
307 m_[1][2] * m_[2][0] - m_[2][2] * m_[1][0],
308 m_[2][2] * m_[0][0] - m_[0][2] * m_[2][0],
309 m_[0][2] * m_[1][0] - m_[1][2] * m_[0][0],
311 m_[1][0] * m_[2][1] - m_[2][0] * m_[1][1],
312 m_[2][0] * m_[0][1] - m_[0][0] * m_[2][1],
313 m_[0][0] * m_[1][1] - m_[1][0] * m_[0][1]);
316 inline Self Inverse(
void)
const {
318 CHECK(det != 0) <<
" Can't inverse. Determinant = 0.";
319 return (1/det) * ComatrixTransposed();
323 inline MVector Row(
const int i)
const {
326 return MVector(m_[i][0], m_[i][1], m_[i][2]);
330 inline MVector Col(
const int i)
const {
333 return MVector(m_[0][i], m_[1][i], m_[2][i]);
341 temp.Set(v1[0], v1[1], v1[2],
343 v3[0], v3[1], v3[2]);
352 temp.Set(v1[0], v2[0], v3[0],
354 v1[2], v2[2], v3[2]);
359 void SetRow(
int i,
const MVector &v1) {
368 void SetCol(
int i,
const MVector &v1) {
378 Self Orthogonalize()
const {
380 r1 = Row(0).Normalize();
381 r2 = (Row(2).CrossProd(r1)).Normalize();
382 r3 = (r1.CrossProd(r2)).Normalize();
383 return FromRows(r1, r2, r3);
387 static inline Self Identity(
void) {
396 static inline Self Zero(
void) {
402 return Self(v[0], VType(), VType(),
403 VType(), v[1], VType(),
404 VType(), VType(), v[2]);
410 v[0]*v[0], v[0]*v[1], v[0]*v[2],
411 v[1]*v[0], v[1]*v[1], v[1]*v[2],
412 v[2]*v[0], v[2]*v[1], v[2]*v[2]);
417 return Self(VType(), -v[2], v[1],
418 v[2], VType(), -v[0],
419 -v[1], v[0], VType());
424 VType theta = rot.Norm();
426 Self Wv = Self::AntiSym3(w);
427 Self I = Self::Identity();
428 Self A = Self::Sym3(w);
429 R = (1 - cos(theta)) * A + sin(theta) * Wv + cos(theta) * I;
435 return ((*
this) * u).DotProd(v);
445 VType FrobeniusNorm()
const {
447 for (
int i = 0; i < 3; i++) {
448 for (
int j = 0; j < 3; j++) {
449 sum += m_[i][j] * m_[i][j];
464 void SymmetricEigenSolver(
MVector *eig_val,
467 double c2 = -(m_[0][0] + m_[1][1] + m_[2][2]);
468 double c1 = -(m_[1][0] * m_[1][0] - m_[0][0] * m_[1][1]
469 - m_[0][0] * m_[2][2] - m_[1][1] * m_[2][2]
470 + m_[2][0] * m_[2][0] + m_[2][1] * m_[2][1]);
471 double c0 = -(m_[0][0] * m_[1][1] * m_[2][2] - m_[2][0]
472 * m_[2][0] * m_[1][1] - m_[1][0] * m_[1][0]
473 * m_[2][2] - m_[0][0] * m_[2][1] * m_[2][1]
474 + 2 * m_[1][0] * m_[2][0] * m_[2][1]);
477 double q = (c2*c2-3*c1)/9.0;
478 double r = (2*c2*c2*c2-9*c2*c1+27*c0)/54.0;
481 double sqrt_q = -2.0 * sqrt(q);
482 double theta = acos(r / sqrt(q * q * q));
483 double c2_3 = c2 / 3;
484 (*eig_val)[0] = sqrt_q * cos(theta / 3.0) - c2_3;
485 (*eig_val)[1] = sqrt_q * cos((theta + 2.0 * M_PI)/3.0) - c2_3;
486 (*eig_val)[2] = sqrt_q * cos((theta - 2.0 * M_PI)/3.0) - c2_3;
490 (*eig_val) =
MVector((*eig_val)[d_order[2]],
491 (*eig_val)[d_order[1]],
492 (*eig_val)[d_order[0]]);
494 for (
int i = 0; i < 3; ++i) {
495 MVector r1 , r2 , r3 , e1 , e2 , e3;
496 r1[0] = m_[0][0] - (*eig_val)[i];
500 r2[1] = m_[1][1] - (*eig_val)[i];
504 r3[2] = m_[2][2] - (*eig_val)[i];
506 e1 = r1.CrossProd(r2);
507 e2 = r2.CrossProd(r3);
508 e3 = r3.CrossProd(r1);
511 if (e2.DotProd(e1) < 0) e2 = -e2;
512 if (e3.DotProd(e1) < 0) e3 = -e3;
513 MVector e = (e1 + e2 + e3).Normalize();
514 eig_vec->SetCol(i,e);
520 for (
int i = 0; i < 3; ++i ) {
521 for (
int j = 0; j < 3; ++j ) {
522 if ( isnan(m_[i][j]) ) {
530 friend std::ostream &operator <<(std::ostream &out,
const Self &mb) {
532 for (i = 0; i < 3; i++) {
538 for (j = 0; j < 3; j++) {
539 out << mb(i, j) <<
" ";
554 PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT(
Matrix3x3);
556 #endif // UTIL_MATH_MATRIX3X3_INL_H__