diff options
Diffstat (limited to 'dep/include/g3dlite/G3D/Matrix3.h')
-rw-r--r-- | dep/include/g3dlite/G3D/Matrix3.h | 366 |
1 files changed, 0 insertions, 366 deletions
diff --git a/dep/include/g3dlite/G3D/Matrix3.h b/dep/include/g3dlite/G3D/Matrix3.h deleted file mode 100644 index 06ec7e67474..00000000000 --- a/dep/include/g3dlite/G3D/Matrix3.h +++ /dev/null @@ -1,366 +0,0 @@ -/** - @file Matrix3.h - - 3x3 matrix class - - @maintainer Morgan McGuire, http://graphics.cs.williams.edu - - @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/Vector3.h" -#include "G3D/Vector4.h" -#include "G3D/debugAssert.h" - -#include <cstring> - -namespace G3D { - -#ifdef _MSC_VER -// Turn off "conditional expression is constant" warning; MSVC generates this -// for debug assertions in inlined methods. -# pragma warning (disable : 4127) -#endif - -class Any; - -/** - 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: - - Matrix3(const Any& any); - - operator Any() const; - - /** Initial values are undefined for performance. See also - Matrix3::zero(), Matrix3::identity(), Matrix3::fromAxisAngle, etc.*/ - inline Matrix3() {} - - Matrix3 (class BinaryInput& b); - 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); - - void serialize(class BinaryOutput& b) const; - void deserialize(class BinaryInput& b); - - /** Returns true if column(0).cross(column(1)).dot(column(2)) > 0. */ - bool isRightHanded() const; - - /** - 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] - */ - inline float* operator[] (int iRow) { - debugAssert(iRow >= 0); - 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 column(int c) const; - const Vector3& row(int r) const; - - void setColumn(int iCol, const Vector3 &vector); - void setRow(int iRow, const Vector3 &vector); - - // assignment and comparison - inline Matrix3& operator= (const Matrix3& rkMatrix) { - 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); - - Matrix3& operator*= (float k); - Matrix3& operator/= (float k); - - -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" - // is an input or output argument. - inline static void mul(const Matrix3& A, const Matrix3& B, Matrix3& out) { - if ((&out == &A) || (&out == &B)) { - // We need a temporary anyway, so revert to the stack method. - out = A * B; - } else { - // Optimized in-place multiplication. - _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>. - */ - inline static void transpose(const Matrix3& A, Matrix3& out) { - if (&A == &out) { - out = A.transpose(); - } else { - _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; - - /** - Polar decomposition of a matrix. Based on pseudocode from Nicholas J - Higham, "Computing the Polar Decomposition -- with Applications Siam - Journal of Science and Statistical Computing, Vol 7, No. 4, October - 1986. - - Decomposes A into R*S, where R is orthogonal and S is symmetric. - - Ken Shoemake's "Matrix animation and polar decomposition" - in Proceedings of the conference on Graphics interface '92 - seems to be better known in the world of graphics, but Higham's version - uses a scaling constant that can lead to faster convergence than - Shoemake's when the initial matrix is far from orthogonal. - */ - void polarDecomposition(Matrix3 &R, Matrix3 &S) const; - - /** - * Matrix norms. - */ - float spectralNorm () const; - - float squaredFrobeniusNorm() const; - - float frobeniusNorm() const; - - float l1Norm() const; - - float lInfNorm() const; - - float diffOneNorm(const Matrix3 &y) const; - - /** matrix must be orthonormal */ - void toAxisAngle(Vector3& rkAxis, float& rfRadians) const; - - static Matrix3 fromDiagonal(const Vector3& d) { - return Matrix3(d.x, 0, 0, - 0, d.y, 0, - 0, 0, d.z); - } - - 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 - * right axis, and roll is rotation about the Direction axis. - */ - bool toEulerAnglesXYZ (float& rfYAngle, float& rfPAngle, - float& rfRAngle) const; - bool toEulerAnglesXZY (float& rfYAngle, float& rfPAngle, - float& rfRAngle) const; - bool toEulerAnglesYXZ (float& rfYAngle, float& rfPAngle, - float& rfRAngle) const; - bool toEulerAnglesYZX (float& rfYAngle, float& rfPAngle, - float& rfRAngle) const; - bool toEulerAnglesZXY (float& rfYAngle, float& rfPAngle, - float& rfRAngle) const; - bool toEulerAnglesZYX (float& rfYAngle, float& rfPAngle, - float& rfRAngle) const; - static Matrix3 fromEulerAnglesXYZ (float fYAngle, float fPAngle, float fRAngle); - static Matrix3 fromEulerAnglesXZY (float fYAngle, float fPAngle, float fRAngle); - static Matrix3 fromEulerAnglesYXZ (float fYAngle, float fPAngle, float fRAngle); - 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 - // special values (like Vector3::ZERO, Color3::WHITE, ...) are wrapped - // inside static functions that return references to them. - // These functions are intentionally not inlined, because: - // "You might be tempted to write [...] them as inline functions - // inside their respective header files, but this is something you - // must definitely not do. An inline function can be duplicated - // in every file in which it appears œóõ½ and this duplication - // includes the static object definition. Because inline functions - // automatically default to internal linkage, this would result in - // having multiple static objects across the various translation - // units, which would certainly cause problems. So you must - // ensure that there is only one definition of each wrapping - // function, and this means not making the wrapping functions inline", - // according to Chapter 10 of "Thinking in C++, 2nd ed. Volume 1" by Bruce Eckel, - // http://www.mindview.net/ - static const Matrix3& zero(); - 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; - static void bidiagonalize (Matrix3& kA, Matrix3& kL, - 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 - |