TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Matrix3.h
Go to the documentation of this file.
1 
14 #ifndef G3D_Matrix3_h
15 #define G3D_Matrix3_h
16 
17 #include "G3D/platform.h"
18 #include "G3D/Vector3.h"
19 #include "G3D/Vector4.h"
20 #include "G3D/debugAssert.h"
21 
22 #include <cstring>
23 
24 namespace G3D {
25 
26 #ifdef _MSC_VER
27 // Turn off "conditional expression is constant" warning; MSVC generates this
28 // for debug assertions in inlined methods.
29 # pragma warning (disable : 4127)
30 #endif
31 
32 class Any;
33 
37 class Matrix3 {
38 private:
39 
40  // Row, column
41  float elt[3][3];
42 
43  // Hidden operators
44  bool operator<(const Matrix3&) const;
45  bool operator>(const Matrix3&) const;
46  bool operator<=(const Matrix3&) const;
47  bool operator>=(const Matrix3&) const;
48 
49 public:
50 
57  Matrix3(const Any& any);
58 
59  static Matrix3 fromColumns(const Vector3& c0, const Vector3& c1, const Vector3& c2) {
60  Matrix3 m;
61  for (int r = 0; r < 3; ++r) {
62  m.elt[r][0] = c0[r];
63  m.elt[r][1] = c1[r];
64  m.elt[r][2] = c2[r];
65  }
66  return m;
67  }
68 
69  static Matrix3 fromRows(const Vector3& r0, const Vector3& r1, const Vector3& r2) {
70  Matrix3 m;
71  for (int c = 0; c < 3; ++c) {
72  m.elt[0][c] = r0[c];
73  m.elt[1][c] = r1[c];
74  m.elt[2][c] = r2[c];
75  }
76  return m;
77  }
78 
79  Any toAny() const;
80 
83  Matrix3() {}
84 
85  Matrix3 (class BinaryInput& b);
86  Matrix3 (const float aafEntry[3][3]);
87  Matrix3 (const Matrix3& rkMatrix);
88  Matrix3 (float fEntry00, float fEntry01, float fEntry02,
89  float fEntry10, float fEntry11, float fEntry12,
90  float fEntry20, float fEntry21, float fEntry22);
91 
92  bool fuzzyEq(const Matrix3& b) const;
93 
97  Matrix3(const class Quat& q);
98 
99  static Matrix3 diagonal(float e00, float e11, float e22) {
100  return Matrix3(e00, 0, 0,
101  0, e11, 0,
102  0, 0, e22);
103  }
104 
105  void serialize(class BinaryOutput& b) const;
106  void deserialize(class BinaryInput& b);
107 
109  bool isRightHanded() const;
110 
114  void set(float fEntry00, float fEntry01, float fEntry02,
115  float fEntry10, float fEntry11, float fEntry12,
116  float fEntry20, float fEntry21, float fEntry22);
117 
121  inline float* operator[] (int iRow) {
122  debugAssert(iRow >= 0);
123  debugAssert(iRow < 3);
124  return (float*)&elt[iRow][0];
125  }
126 
127  inline const float* operator[] (int iRow) const {
128  debugAssert(iRow >= 0);
129  debugAssert(iRow < 3);
130  return (const float*)&elt[iRow][0];
131  }
132 
133  inline operator float* () {
134  return (float*)&elt[0][0];
135  }
136 
137  inline operator const float* () const{
138  return (const float*)&elt[0][0];
139  }
140 
141  Vector3 column(int c) const;
142  const Vector3& row(int r) const;
143 
144  void setColumn(int iCol, const Vector3 &vector);
145  void setRow(int iRow, const Vector3 &vector);
146 
147  // assignment and comparison
148  inline Matrix3& operator= (const Matrix3& rkMatrix) {
149  memcpy(elt, rkMatrix.elt, 9 * sizeof(float));
150  return *this;
151  }
152 
153  bool operator== (const Matrix3& rkMatrix) const;
154  bool operator!= (const Matrix3& rkMatrix) const;
155 
156  // arithmetic operations
157  Matrix3 operator+ (const Matrix3& rkMatrix) const;
158  Matrix3 operator- (const Matrix3& rkMatrix) const;
160  Matrix3 operator* (const Matrix3& rkMatrix) const;
161  Matrix3 operator- () const;
162 
163  Matrix3& operator+= (const Matrix3& rkMatrix);
164  Matrix3& operator-= (const Matrix3& rkMatrix);
165  Matrix3& operator*= (const Matrix3& rkMatrix);
166 
170  inline Vector3 operator* (const Vector3& v) const {
171  Vector3 kProd;
172 
173  for (int r = 0; r < 3; ++r) {
174  kProd[r] =
175  elt[r][0] * v[0] +
176  elt[r][1] * v[1] +
177  elt[r][2] * v[2];
178  }
179 
180  return kProd;
181  }
182 
183 
187  friend Vector3 operator* (const Vector3& rkVector,
188  const Matrix3& rkMatrix);
189 
193  Matrix3 operator* (float fScalar) const;
194 
196  friend Matrix3 operator* (double fScalar, const Matrix3& rkMatrix);
197  friend Matrix3 operator* (float fScalar, const Matrix3& rkMatrix);
198  friend Matrix3 operator* (int fScalar, const Matrix3& rkMatrix);
199 
200  Matrix3& operator*= (float k);
201  Matrix3& operator/= (float k);
202 
203 
204 private:
206  static void _mul(const Matrix3& A, const Matrix3& B, Matrix3& out);
207 public:
208 
211  // This is a static method so that it is not ambiguous whether "this"
212  // is an input or output argument.
213  inline static void mul(const Matrix3& A, const Matrix3& B, Matrix3& out) {
214  if ((&out == &A) || (&out == &B)) {
215  // We need a temporary anyway, so revert to the stack method.
216  out = A * B;
217  } else {
218  // Optimized in-place multiplication.
219  _mul(A, B, out);
220  }
221  }
222 
223 private:
224  static void _transpose(const Matrix3& A, Matrix3& out);
225 public:
226 
233  inline static void transpose(const Matrix3& A, Matrix3& out) {
234  if (&A == &out) {
235  out = A.transpose();
236  } else {
237  _transpose(A, out);
238  }
239  }
240 
242  bool isOrthonormal() const;
243 
244  Matrix3 transpose () const;
245  bool inverse (Matrix3& rkInverse, float fTolerance = 1e-06f) const;
246  Matrix3 inverse (float fTolerance = 1e-06f) const;
247  float determinant () const;
248 
250  void singularValueDecomposition (Matrix3& rkL, Vector3& rkS,
251  Matrix3& rkR) const;
253  void singularValueComposition (const Matrix3& rkL,
254  const Vector3& rkS, const Matrix3& rkR);
255 
257  void orthonormalize();
258 
260  void qDUDecomposition (Matrix3& rkQ, Vector3& rkD,
261  Vector3& rkU) const;
262 
277  void polarDecomposition(Matrix3 &R, Matrix3 &S) const;
278 
282  float spectralNorm () const;
283 
284  float squaredFrobeniusNorm() const;
285 
286  float frobeniusNorm() const;
287 
288  float l1Norm() const;
289 
290  float lInfNorm() const;
291 
292  float diffOneNorm(const Matrix3 &y) const;
293 
295  void toAxisAngle(Vector3& rkAxis, float& rfRadians) const;
296 
297  static Matrix3 fromDiagonal(const Vector3& d) {
298  return Matrix3(d.x, 0, 0,
299  0, d.y, 0,
300  0, 0, d.z);
301  }
302 
304  static Matrix3 fromAxisAngle(const Vector3& rkAxis, float fRadians);
305 
307  static Matrix3 fromUnitAxisAngle(const Vector3& rkAxis, float fRadians);
308 
314  bool toEulerAnglesXYZ (float& rfYAngle, float& rfPAngle,
315  float& rfRAngle) const;
316  bool toEulerAnglesXZY (float& rfYAngle, float& rfPAngle,
317  float& rfRAngle) const;
318  bool toEulerAnglesYXZ (float& rfYAngle, float& rfPAngle,
319  float& rfRAngle) const;
320  bool toEulerAnglesYZX (float& rfYAngle, float& rfPAngle,
321  float& rfRAngle) const;
322  bool toEulerAnglesZXY (float& rfYAngle, float& rfPAngle,
323  float& rfRAngle) const;
324  bool toEulerAnglesZYX (float& rfYAngle, float& rfPAngle,
325  float& rfRAngle) const;
326  static Matrix3 fromEulerAnglesXYZ (float fYAngle, float fPAngle, float fRAngle);
327  static Matrix3 fromEulerAnglesXZY (float fYAngle, float fPAngle, float fRAngle);
328  static Matrix3 fromEulerAnglesYXZ (float fYAngle, float fPAngle, float fRAngle);
329  static Matrix3 fromEulerAnglesYZX (float fYAngle, float fPAngle, float fRAngle);
330  static Matrix3 fromEulerAnglesZXY (float fYAngle, float fPAngle, float fRAngle);
331  static Matrix3 fromEulerAnglesZYX (float fYAngle, float fPAngle, float fRAngle);
332 
334  void eigenSolveSymmetric (float afEigenvalue[3],
335  Vector3 akEigenvector[3]) const;
336 
337  static void tensorProduct (const Vector3& rkU, const Vector3& rkV,
338  Matrix3& rkProduct);
339  std::string toString() const;
340 
341  static const float EPSILON;
342 
343  // Special values.
344  // The unguaranteed order of initialization of static variables across
345  // translation units can be a source of annoying bugs, so now the static
346  // special values (like Vector3::ZERO, Color3::WHITE, ...) are wrapped
347  // inside static functions that return references to them.
348  // These functions are intentionally not inlined, because:
349  // "You might be tempted to write [...] them as inline functions
350  // inside their respective header files, but this is something you
351  // must definitely not do. An inline function can be duplicated
352  // in every file in which it appears and this duplication
353  // includes the static object definition. Because inline functions
354  // automatically default to internal linkage, this would result in
355  // having multiple static objects across the various translation
356  // units, which would certainly cause problems. So you must
357  // ensure that there is only one definition of each wrapping
358  // function, and this means not making the wrapping functions inline",
359  // according to Chapter 10 of "Thinking in C++, 2nd ed. Volume 1" by Bruce Eckel,
360  // http://www.mindview.net/
361  static const Matrix3& zero();
362  static const Matrix3& identity();
363 
364 protected:
365 
366  // support for eigensolver
367  void tridiagonal (float afDiag[3], float afSubDiag[3]);
368  bool qLAlgorithm (float afDiag[3], float afSubDiag[3]);
369 
370  // support for singular value decomposition
371  static const float ms_fSvdEpsilon;
372  static const int ms_iSvdMaxIterations;
373  static void bidiagonalize (Matrix3& kA, Matrix3& kL,
374  Matrix3& kR);
375  static void golubKahanStep (Matrix3& kA, Matrix3& kL,
376  Matrix3& kR);
377 
378  // support for spectral norm
379  static float maxCubicRoot (float afCoeff[3]);
380 
381 };
382 
383 
384 //----------------------------------------------------------------------------
386 inline Vector3 operator* (const Vector3& rkPoint, const Matrix3& rkMatrix) {
387  Vector3 kProd;
388 
389  for (int r = 0; r < 3; ++r) {
390  kProd[r] =
391  rkPoint[0] * rkMatrix.elt[0][r] +
392  rkPoint[1] * rkMatrix.elt[1][r] +
393  rkPoint[2] * rkMatrix.elt[2][r];
394  }
395 
396  return kProd;
397 }
398 
399 
400 } // namespace
401 
402 #endif
403 
static const int ms_iSvdMaxIterations
Definition: Matrix3.h:372
bool fuzzyEq(const Matrix3 &b) const
Definition: Matrix3.cpp:83
bool toEulerAnglesZXY(float &rfYAngle, float &rfPAngle, float &rfRAngle) const
Definition: Matrix3.cpp:1499
void tridiagonal(float afDiag[3], float afSubDiag[3])
Definition: Matrix3.cpp:1684
void qDUDecomposition(Matrix3 &rkQ, Vector3 &rkD, Vector3 &rkU) const
Definition: Matrix3.cpp:901
static float maxCubicRoot(float afCoeff[3])
Definition: Matrix3.cpp:1106
float x
Definition: Vector3.h:62
void orthonormalize()
Definition: Matrix3.cpp:838
bool toEulerAnglesXYZ(float &rfYAngle, float &rfPAngle, float &rfRAngle) const
Definition: Matrix3.cpp:1383
bool toEulerAnglesXZY(float &rfYAngle, float &rfPAngle, float &rfRAngle) const
Definition: Matrix3.cpp:1412
void setRow(int iRow, const Vector3 &vector)
Definition: Matrix3.cpp:224
static const float ms_fSvdEpsilon
Definition: Matrix3.h:371
static Matrix3 fromEulerAnglesYXZ(float fYAngle, float fPAngle, float fRAngle)
Definition: Matrix3.cpp:1598
static Matrix3 diagonal(float e00, float e11, float e22)
Definition: Matrix3.h:99
Definition: BinaryInput.h:69
Matrix3 operator+(const Matrix3 &rkMatrix) const
Definition: Matrix3.cpp:250
void deserialize(class BinaryInput &b)
Definition: Matrix3.cpp:182
static void golubKahanStep(Matrix3 &kA, Matrix3 &kL, Matrix3 &kR)
Definition: Matrix3.cpp:577
void singularValueComposition(const Matrix3 &rkL, const Vector3 &rkS, const Matrix3 &rkR)
Definition: Matrix3.cpp:815
Definition: AABox.h:25
bool any(float x)
Definition: g3dmath.h:424
Matrix3 & operator/=(float k)
Definition: Matrix3.cpp:354
Matrix3 & operator=(const Matrix3 &rkMatrix)
Definition: Matrix3.h:148
static Matrix3 fromUnitAxisAngle(const Vector3 &rkAxis, float fRadians)
Definition: Matrix3.cpp:1350
static void _transpose(const Matrix3 &A, Matrix3 &out)
Definition: Matrix3.cpp:1919
float spectralNorm() const
Definition: Matrix3.cpp:1157
float * operator[](int iRow)
Definition: Matrix3.h:121
float y
Definition: Vector3.h:62
static Matrix3 fromAxisAngle(const Vector3 &rkAxis, float fRadians)
Definition: Matrix3.cpp:1346
Any toAny() const
Definition: Matrix3.cpp:53
Definition: Vector3.h:58
static const float EPSILON
Definition: Matrix3.h:341
float frobeniusNorm() const
Definition: Matrix3.cpp:1210
float lInfNorm() const
Definition: Matrix3.cpp:1230
void eigenSolveSymmetric(float afEigenvalue[3], Vector3 akEigenvector[3]) const
Definition: Matrix3.cpp:1825
static void _mul(const Matrix3 &A, const Matrix3 &B, Matrix3 &out)
Definition: Matrix3.cpp:1869
Matrix3 & operator-=(const Matrix3 &rkMatrix)
Definition: Matrix3.cpp:303
bool isRightHanded() const
Definition: Matrix3.cpp:95
bool qLAlgorithm(float afDiag[3], float afSubDiag[3])
Definition: Matrix3.cpp:1740
bool operator>=(const Matrix3 &) const
Easy loading and saving of human-readable configuration files.
Definition: Any.h:184
Definition: Quat.h:49
float squaredFrobeniusNorm() const
Definition: Matrix3.cpp:1198
void setColumn(int iCol, const Vector3 &vector)
Definition: Matrix3.cpp:216
#define debugAssert(exp)
Definition: debugAssert.h:160
static Matrix3 fromEulerAnglesZXY(float fYAngle, float fPAngle, float fRAngle)
Definition: Matrix3.cpp:1644
static Matrix3 fromEulerAnglesXZY(float fYAngle, float fPAngle, float fRAngle)
Definition: Matrix3.cpp:1577
bool inverse(Matrix3 &rkInverse, float fTolerance=1e-06f) const
Definition: Matrix3.cpp:404
void toAxisAngle(Vector3 &rkAxis, float &rfRadians) const
Definition: Matrix3.cpp:1262
bool toEulerAnglesYZX(float &rfYAngle, float &rfPAngle, float &rfRAngle) const
Definition: Matrix3.cpp:1470
bool toEulerAnglesYXZ(float &rfYAngle, float &rfPAngle, float &rfRAngle) const
Definition: Matrix3.cpp:1441
static Matrix3 fromRows(const Vector3 &r0, const Vector3 &r1, const Vector3 &r2)
Definition: Matrix3.h:69
G3D::int16 y
Definition: Vector2int16.h:38
bool operator<=(const Matrix3 &) const
bool operator!=(const Matrix3 &rkMatrix) const
Definition: Matrix3.cpp:245
bool isOrthonormal() const
Definition: Matrix3.cpp:107
static Matrix3 fromColumns(const Vector3 &c0, const Vector3 &c1, const Vector3 &c2)
Definition: Matrix3.h:59
Definition: Matrix3.h:37
std::string toString() const
Definition: Matrix3.cpp:1932
float diffOneNorm(const Matrix3 &y) const
Definition: Matrix3.cpp:1246
static void transpose(const Matrix3 &A, Matrix3 &out)
Definition: Matrix3.h:233
static const Matrix3 & zero()
Definition: Matrix3.cpp:65
Matrix3 operator-() const
Definition: Matrix3.cpp:329
Vector3 column(int c) const
Definition: Matrix3.cpp:203
float z
Definition: Vector3.h:62
void singularValueDecomposition(Matrix3 &rkL, Vector3 &rkS, Matrix3 &rkR) const
Definition: Matrix3.cpp:708
static Matrix3 fromDiagonal(const Vector3 &d)
Definition: Matrix3.h:297
Definition: BinaryOutput.h:52
bool operator==(const Matrix3 &rkMatrix) const
Definition: Matrix3.cpp:233
Matrix3 transpose() const
Definition: Matrix3.cpp:391
void polarDecomposition(Matrix3 &R, Matrix3 &S) const
Definition: Matrix3.cpp:1015
void set(float fEntry00, float fEntry01, float fEntry02, float fEntry10, float fEntry11, float fEntry12, float fEntry20, float fEntry21, float fEntry22)
Definition: Matrix3.cpp:165
static void bidiagonalize(Matrix3 &kA, Matrix3 &kL, Matrix3 &kR)
Definition: Matrix3.cpp:470
Matrix3 & operator*=(const Matrix3 &rkMatrix)
Definition: Matrix3.cpp:313
bool operator<(const Matrix3 &) const
float l1Norm() const
Definition: Matrix3.cpp:1215
static void mul(const Matrix3 &A, const Matrix3 &B, Matrix3 &out)
Definition: Matrix3.h:213
static Matrix3 fromEulerAnglesZYX(float fYAngle, float fPAngle, float fRAngle)
Definition: Matrix3.cpp:1664
const Vector3 & row(int r) const
Definition: Matrix3.cpp:210
static Matrix3 fromEulerAnglesYZX(float fYAngle, float fPAngle, float fRAngle)
Definition: Matrix3.cpp:1621
float elt[3][3]
Definition: Matrix3.h:41
bool toEulerAnglesZYX(float &rfYAngle, float &rfPAngle, float &rfRAngle) const
Definition: Matrix3.cpp:1528
bool operator>(const Matrix3 &) const
Matrix3 operator*(const Matrix3 &rkMatrix) const
Definition: Matrix3.cpp:278
G3D::Color3 operator*(float s, const G3D::Color3 &c)
Definition: Color3.h:275
float determinant() const
Definition: Matrix3.cpp:453
static const Matrix3 & identity()
Definition: Matrix3.cpp:70
static void tensorProduct(const Vector3 &rkU, const Vector3 &rkV, Matrix3 &rkProduct)
Definition: Matrix3.cpp:1851
Matrix3()
Definition: Matrix3.h:83
static Matrix3 fromEulerAnglesXYZ(float fYAngle, float fPAngle, float fRAngle)
Definition: Matrix3.cpp:1557
Matrix3 & operator+=(const Matrix3 &rkMatrix)
Definition: Matrix3.cpp:293
void serialize(class BinaryOutput &b) const
Definition: Matrix3.cpp:192