aboutsummaryrefslogtreecommitdiff
path: root/dep/include/g3dlite/G3D/Matrix3.h
diff options
context:
space:
mode:
authormaximius <none@none>2009-10-17 15:51:44 -0700
committermaximius <none@none>2009-10-17 15:51:44 -0700
commite585187b248f48b3c6e9247b49fa07c6565d65e5 (patch)
tree637c5b7ddacf41040bef4ea4f75a97da64c6a9bc /dep/include/g3dlite/G3D/Matrix3.h
parent26b5e033ffde3d161382fc9addbfa99738379641 (diff)
*Backed out changeset 3be01fb200a5
--HG-- branch : trunk
Diffstat (limited to 'dep/include/g3dlite/G3D/Matrix3.h')
-rw-r--r--dep/include/g3dlite/G3D/Matrix3.h60
1 files changed, 60 insertions, 0 deletions
diff --git a/dep/include/g3dlite/G3D/Matrix3.h b/dep/include/g3dlite/G3D/Matrix3.h
index 3c7849a4121..0fd85b306c9 100644
--- a/dep/include/g3dlite/G3D/Matrix3.h
+++ b/dep/include/g3dlite/G3D/Matrix3.h
@@ -1,50 +1,67 @@
/**
@file Matrix3.h
+
3x3 matrix class
+
@maintainer Morgan McGuire, matrix@graphics3d.com
+
@cite Portions based on Dave Eberly's Magic Software Library at <A HREF="http://www.magic-software.com">http://www.magic-software.com</A>
+
@created 2001-06-02
@edited 2006-04-05
*/
+
#ifndef G3D_MATRIX3_H
#define G3D_MATRIX3_H
+
#include "G3D/platform.h"
#include "G3D/System.h"
#include "G3D/Vector3.h"
#include "G3D/Vector4.h"
+
namespace G3D {
+
/**
3x3 matrix. Do not subclass.
*/
class Matrix3 {
private:
+
float elt[3][3];
+
// Hidden operators
bool operator<(const Matrix3&) const;
bool operator>(const Matrix3&) const;
bool operator<=(const Matrix3&) const;
bool operator>=(const Matrix3&) const;
+
public:
+
/** Initial values are undefined for performance. See also
Matrix3::zero(), Matrix3::identity(), Matrix3::fromAxisAngle, etc.*/
inline Matrix3() {}
+
Matrix3 (const float aafEntry[3][3]);
Matrix3 (const Matrix3& rkMatrix);
Matrix3 (float fEntry00, float fEntry01, float fEntry02,
float fEntry10, float fEntry11, float fEntry12,
float fEntry20, float fEntry21, float fEntry22);
+
bool fuzzyEq(const Matrix3& b) const;
+
/** Constructs a matrix from a quaternion.
@cite Graphics Gems II, p. 351--354
@cite Implementation from Watt and Watt, pg 362*/
Matrix3(const class Quat& q);
+
/**
Sets all elements.
*/
void set(float fEntry00, float fEntry01, float fEntry02,
float fEntry10, float fEntry11, float fEntry12,
float fEntry20, float fEntry21, float fEntry22);
+
/**
* member access, allows use of construct mat[r][c]
*/
@@ -53,68 +70,84 @@ public:
debugAssert(iRow < 3);
return (float*)&elt[iRow][0];
}
+
inline const float* operator[] (int iRow) const {
debugAssert(iRow >= 0);
debugAssert(iRow < 3);
return (const float*)&elt[iRow][0];
}
+
inline operator float* () {
return (float*)&elt[0][0];
}
+
inline operator const float* () const{
return (const float*)&elt[0][0];
}
+
Vector3 getColumn (int iCol) const;
Vector3 getRow (int iRow) const;
void setColumn(int iCol, const Vector3 &vector);
void setRow(int iRow, const Vector3 &vector);
+
// assignment and comparison
inline Matrix3& operator= (const Matrix3& rkMatrix) {
System::memcpy(elt, rkMatrix.elt, 9 * sizeof(float));
return *this;
}
+
bool operator== (const Matrix3& rkMatrix) const;
bool operator!= (const Matrix3& rkMatrix) const;
+
// arithmetic operations
Matrix3 operator+ (const Matrix3& rkMatrix) const;
Matrix3 operator- (const Matrix3& rkMatrix) const;
/** Matrix-matrix multiply */
Matrix3 operator* (const Matrix3& rkMatrix) const;
Matrix3 operator- () const;
+
Matrix3& operator+= (const Matrix3& rkMatrix);
Matrix3& operator-= (const Matrix3& rkMatrix);
Matrix3& operator*= (const Matrix3& rkMatrix);
+
/**
* matrix * vector [3x3 * 3x1 = 3x1]
*/
inline Vector3 operator* (const Vector3& v) const {
Vector3 kProd;
+
for (int r = 0; r < 3; ++r) {
kProd[r] =
elt[r][0] * v[0] +
elt[r][1] * v[1] +
elt[r][2] * v[2];
}
+
return kProd;
}
+
/**
* vector * matrix [1x3 * 3x3 = 1x3]
*/
friend Vector3 operator* (const Vector3& rkVector,
const Matrix3& rkMatrix);
+
/**
* matrix * scalar
*/
Matrix3 operator* (float fScalar) const;
+
/** scalar * matrix */
friend Matrix3 operator* (double fScalar, const Matrix3& rkMatrix);
friend Matrix3 operator* (float fScalar, const Matrix3& rkMatrix);
friend Matrix3 operator* (int fScalar, const Matrix3& rkMatrix);
+
private:
/** Multiplication where out != A and out != B */
static void _mul(const Matrix3& A, const Matrix3& B, Matrix3& out);
public:
+
/** Optimized implementation of out = A * B. It is safe (but slow) to call
with A, B, and out possibly pointer equal to one another.*/
// This is a static method so that it is not ambiguous whether "this"
@@ -128,11 +161,14 @@ public:
_mul(A, B, out);
}
}
+
private:
static void _transpose(const Matrix3& A, Matrix3& out);
public:
+
/** Optimized implementation of out = A.transpose(). It is safe (but slow) to call
with A and out possibly pointer equal to one another.
+
Note that <CODE>A.transpose() * v</CODE> can be computed
more efficiently as <CODE>v * A</CODE>.
*/
@@ -143,27 +179,36 @@ public:
_transpose(A, out);
}
}
+
/** Returns true if the rows and column L2 norms are 1.0 and the rows are orthogonal. */
bool isOrthonormal() const;
+
Matrix3 transpose () const;
bool inverse (Matrix3& rkInverse, float fTolerance = 1e-06) const;
Matrix3 inverse (float fTolerance = 1e-06) const;
float determinant () const;
+
/** singular value decomposition */
void singularValueDecomposition (Matrix3& rkL, Vector3& rkS,
Matrix3& rkR) const;
/** singular value decomposition */
void singularValueComposition (const Matrix3& rkL,
const Vector3& rkS, const Matrix3& rkR);
+
/** Gram-Schmidt orthonormalization (applied to columns of rotation matrix) */
void orthonormalize();
+
/** orthogonal Q, diagonal D, upper triangular U stored as (u01,u02,u12) */
void qDUDecomposition (Matrix3& rkQ, Vector3& rkD,
Vector3& rkU) const;
+
float spectralNorm () const;
+
/** matrix must be orthonormal */
void toAxisAngle(Vector3& rkAxis, float& rfRadians) const;
+
static Matrix3 fromAxisAngle(const Vector3& rkAxis, float fRadians);
+
/**
* The matrix must be orthonormal. The decomposition is yaw*pitch*roll
* where yaw is rotation about the Up vector, pitch is rotation about the
@@ -187,13 +232,17 @@ public:
static Matrix3 fromEulerAnglesYZX (float fYAngle, float fPAngle, float fRAngle);
static Matrix3 fromEulerAnglesZXY (float fYAngle, float fPAngle, float fRAngle);
static Matrix3 fromEulerAnglesZYX (float fYAngle, float fPAngle, float fRAngle);
+
/** eigensolver, matrix must be symmetric */
void eigenSolveSymmetric (float afEigenvalue[3],
Vector3 akEigenvector[3]) const;
+
static void tensorProduct (const Vector3& rkU, const Vector3& rkV,
Matrix3& rkProduct);
std::string toString() const;
+
static const float EPSILON;
+
// Special values.
// The unguaranteed order of initialization of static variables across
// translation units can be a source of annoying bugs, so now the static
@@ -214,15 +263,18 @@ public:
// http://www.mindview.net/
static const Matrix3& zero();
static const Matrix3& identity();
+
// Deprecated.
/** @deprecated Use Matrix3::zero() */
static const Matrix3 ZERO;
/** @deprecated Use Matrix3::identity() */
static const Matrix3 IDENTITY;
+
protected:
// support for eigensolver
void tridiagonal (float afDiag[3], float afSubDiag[3]);
bool qLAlgorithm (float afDiag[3], float afSubDiag[3]);
+
// support for singular value decomposition
static const float ms_fSvdEpsilon;
static const int ms_iSvdMaxIterations;
@@ -230,23 +282,31 @@ protected:
Matrix3& kR);
static void golubKahanStep (Matrix3& kA, Matrix3& kL,
Matrix3& kR);
+
// support for spectral norm
static float maxCubicRoot (float afCoeff[3]);
+
};
+
//----------------------------------------------------------------------------
/** <code>v * M == M.transpose() * v</code> */
inline Vector3 operator* (const Vector3& rkPoint, const Matrix3& rkMatrix) {
Vector3 kProd;
+
for (int r = 0; r < 3; ++r) {
kProd[r] =
rkPoint[0] * rkMatrix.elt[0][r] +
rkPoint[1] * rkMatrix.elt[1][r] +
rkPoint[2] * rkMatrix.elt[2][r];
}
+
return kProd;
}
+
} // namespace
+
#endif
+