⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gmmat4.cc

📁 This contains Graphic gems code
💻 CC
字号:
// gmMatrix4.cc - 4x4 element matrix class//// libgm++: Graphics Math Library// Ferdi Scheepers and Stephen F May// 15 June 1994#include "gmMat4.h"#include "gmVec3.h"#include "gmVec4.h"// private function: RCD// - dot product of row i of matrix A and row j of matrix Binline double RCD(const gmMatrix4& A, const gmMatrix4& B, int i, int j){  return A[i][0] * B[0][j] + A[i][1] * B[1][j] + A[i][2] * B[2][j] +         A[i][3] * B[3][j];}// private function: MINOR// - MINOR of M[r][c]; r in {0,1,2,3}-{r0,r1,r2}; c in {0,1,2,3}-{c0,c1,c2}inline double MINOR(const gmMatrix4& M,                    int r0, int r1, int r2, int c0, int c1, int c2){  return M[r0][c0] * (M[r1][c1] * M[r2][c2] - M[r2][c1] * M[r1][c2]) -	 M[r0][c1] * (M[r1][c0] * M[r2][c2] - M[r2][c0] * M[r1][c2]) +	 M[r0][c2] * (M[r1][c0] * M[r2][c1] - M[r2][c0] * M[r1][c1]);}// CONSTRUCTORSgmMatrix4::gmMatrix4(){  assign(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0);}gmMatrix4::gmMatrix4(const gmMatrix4& M){  assign(M[0][0], M[0][1], M[0][2], M[0][3],	 M[1][0], M[1][1], M[1][2], M[1][3],	 M[2][0], M[2][1], M[2][2], M[2][3],	 M[3][0], M[3][1], M[3][2], M[3][3]);}gmMatrix4::gmMatrix4(double a00, double a01, double a02, double a03,		     double a10, double a11, double a12, double a13,		     double a20, double a21, double a22, double a23,		     double a30, double a31, double a32, double a33){  assign(a00, a01, a02, a03,         a10, a11, a12, a13,	 a20, a21, a22, a23,	 a30, a31, a32, a33);}// ASSIGNMENTgmMatrix4& gmMatrix4::assign(double a00, double a01, double a02, double a03,		             double a10, double a11, double a12, double a13,		             double a20, double a21, double a22, double a23,		             double a30, double a31, double a32, double a33){  m_[0][0] = a00; m_[0][1] = a01; m_[0][2] = a02; m_[0][3] = a03;  m_[1][0] = a10; m_[1][1] = a11; m_[1][2] = a12; m_[1][3] = a13;  m_[2][0] = a20; m_[2][1] = a21; m_[2][2] = a22; m_[2][3] = a23;  m_[3][0] = a30; m_[3][1] = a31; m_[3][2] = a32; m_[3][3] = a33;  return *this;}gmMatrix4& gmMatrix4::operator =(const gmMatrix4& M){  assign(M[0][0], M[0][1], M[0][2], M[0][3],	 M[1][0], M[1][1], M[1][2], M[1][3],	 M[2][0], M[2][1], M[2][2], M[2][3],	 M[3][0], M[3][1], M[3][2], M[3][3]);  return *this;}////////////////////////////////////////////////////////////////////////////// OPERATORSgmMatrix4& gmMatrix4::operator +=(const gmMatrix4& M){  m_[0][0] += M[0][0]; m_[0][1] += M[0][1];  m_[0][2] += M[0][2]; m_[0][3] += M[0][3];    m_[1][0] += M[1][0]; m_[1][1] += M[1][1];  m_[1][2] += M[1][2]; m_[1][3] += M[1][3];    m_[2][0] += M[2][0]; m_[2][1] += M[2][1];  m_[2][2] += M[2][2]; m_[2][3] += M[2][3];    m_[3][0] += M[3][0]; m_[3][1] += M[3][1];  m_[3][2] += M[3][2]; m_[3][3] += M[3][3];  return *this;}gmMatrix4& gmMatrix4::operator -=(const gmMatrix4& M){  m_[0][0] -= M[0][0]; m_[0][1] -= M[0][1];  m_[0][2] -= M[0][2]; m_[0][3] -= M[0][3];    m_[1][0] -= M[1][0]; m_[1][1] -= M[1][1];  m_[1][2] -= M[1][2]; m_[1][3] -= M[1][3];    m_[2][0] -= M[2][0]; m_[2][1] -= M[2][1];  m_[2][2] -= M[2][2]; m_[2][3] -= M[2][3];    m_[3][0] -= M[3][0]; m_[3][1] -= M[3][1];  m_[3][2] -= M[3][2]; m_[3][3] -= M[3][3];  return *this;}gmMatrix4& gmMatrix4::operator *=(const gmMatrix4& M){  assign(RCD(*this, M, 0, 0), RCD(*this, M, 0, 1), 	 RCD(*this, M, 0, 2), RCD(*this, M, 0, 3),	 RCD(*this, M, 1, 0), RCD(*this, M, 1, 1),	 RCD(*this, M, 1, 2), RCD(*this, M, 1, 3),	 RCD(*this, M, 2, 0), RCD(*this, M, 2, 1),	 RCD(*this, M, 2, 2), RCD(*this, M, 2, 3),	 RCD(*this, M, 3, 0), RCD(*this, M, 3, 1),	 RCD(*this, M, 3, 2), RCD(*this, M, 3, 3));  return *this;}gmMatrix4& gmMatrix4::operator *=(double d){  m_[0][0] *= d; m_[0][1] *= d; m_[0][2] *= d; m_[0][3] *= d;  m_[1][0] *= d; m_[1][1] *= d; m_[1][2] *= d; m_[1][3] *= d;  m_[2][0] *= d; m_[2][1] *= d; m_[2][2] *= d; m_[2][3] *= d;  m_[3][0] *= d; m_[3][1] *= d; m_[3][2] *= d; m_[3][3] *= d;  return *this;}gmMatrix4& gmMatrix4::operator /=(double d){  double di = 1 / d;  m_[0][0] *= di; m_[0][1] *= di; m_[0][2] *= di; m_[0][3] *= di;  m_[1][0] *= di; m_[1][1] *= di; m_[1][2] *= di; m_[1][3] *= di;  m_[2][0] *= di; m_[2][1] *= di; m_[2][2] *= di; m_[2][3] *= di;  m_[3][0] *= di; m_[3][1] *= di; m_[3][2] *= di; m_[3][3] *= di;  return *this;}gmMatrix4 gmMatrix4::operator +(const gmMatrix4& M) const{  return gmMatrix4(m_[0][0] + M[0][0], m_[0][1] + M[0][1],		   m_[0][2] + M[0][2], m_[0][3] + M[0][3],		   m_[1][0] + M[1][0], m_[1][1] + M[1][1],		   m_[1][2] + M[1][2], m_[1][3] + M[1][3],		   m_[2][0] + M[2][0], m_[2][1] + M[2][1],		   m_[2][2] + M[2][2], m_[2][3] + M[2][3],		   m_[3][0] + M[3][0], m_[3][1] + M[3][1],		   m_[3][2] + M[3][2], m_[3][3] + M[3][3]);}gmMatrix4 gmMatrix4::operator -(const gmMatrix4& M) const{  return gmMatrix4(m_[0][0] - M[0][0], m_[0][1] - M[0][1],		   m_[0][2] - M[0][2], m_[0][3] - M[0][3],		   m_[1][0] - M[1][0], m_[1][1] - M[1][1],		   m_[1][2] - M[1][2], m_[1][3] - M[1][3],		   m_[2][0] - M[2][0], m_[2][1] - M[2][1],		   m_[2][2] - M[2][2], m_[2][3] - M[2][3],		   m_[3][0] - M[3][0], m_[3][1] - M[3][1],		   m_[3][2] - M[3][2], m_[3][3] - M[3][3]);}gmMatrix4 gmMatrix4::operator -() const{  return gmMatrix4(-m_[0][0], -m_[0][1], -m_[0][2], -m_[0][3],		   -m_[1][0], -m_[1][1], -m_[1][2], -m_[1][3],		   -m_[2][0], -m_[2][1], -m_[2][2], -m_[2][3],		   -m_[3][0], -m_[3][1], -m_[3][2], -m_[3][3]);}gmMatrix4 gmMatrix4::operator *(const gmMatrix4& M) const{  return gmMatrix4(RCD(*this, M, 0, 0), RCD(*this, M, 0, 1), 		   RCD(*this, M, 0, 2), RCD(*this, M, 0, 3),		   RCD(*this, M, 1, 0), RCD(*this, M, 1, 1),		   RCD(*this, M, 1, 2), RCD(*this, M, 1, 3),		   RCD(*this, M, 2, 0), RCD(*this, M, 2, 1),		   RCD(*this, M, 2, 2), RCD(*this, M, 2, 3),		   RCD(*this, M, 3, 0), RCD(*this, M, 3, 1),		   RCD(*this, M, 3, 2), RCD(*this, M, 3, 3));}gmMatrix4 gmMatrix4::operator *(double d) const{  return gmMatrix4(m_[0][0] * d, m_[0][1] * d, m_[0][2] * d, m_[0][3] * d,		   m_[1][0] * d, m_[1][1] * d, m_[1][2] * d, m_[1][3] * d,		   m_[2][0] * d, m_[2][1] * d, m_[2][2] * d, m_[2][3] * d,		   m_[3][0] * d, m_[3][1] * d, m_[3][2] * d, m_[3][3] * d);}gmMatrix4 gmMatrix4::operator /(double d) const{  assert(!gmIsZero(d));  double di = 1 / d;  return gmMatrix4(m_[0][0] * di, m_[0][1] * di, m_[0][2] * di, m_[0][3] * di,		   m_[1][0] * di, m_[1][1] * di, m_[1][2] * di, m_[1][3] * di,		   m_[2][0] * di, m_[2][1] * di, m_[2][2] * di, m_[2][3] * di,		   m_[3][0] * di, m_[3][1] * di, m_[3][2] * di, m_[3][3] * di);}gmMatrix4 operator *(double d, const gmMatrix4& M){  return gmMatrix4(M[0][0] * d, M[0][1] * d, M[0][2] * d, M[0][3] * d,		   M[1][0] * d, M[1][1] * d, M[1][2] * d, M[1][3] * d,		   M[2][0] * d, M[2][1] * d, M[2][2] * d, M[2][3] * d,		   M[3][0] * d, M[3][1] * d, M[3][2] * d, M[3][3] * d);}bool gmMatrix4::operator ==(const gmMatrix4& M) const{  return (gmFuzEQ(m_[0][0], M[0][0]) && gmFuzEQ(m_[0][1], M[0][1]) &&	  gmFuzEQ(m_[0][2], M[0][2]) && gmFuzEQ(m_[0][3], M[0][3]) &&	 	  gmFuzEQ(m_[1][0], M[1][0]) && gmFuzEQ(m_[1][1], M[1][1]) &&	  gmFuzEQ(m_[1][2], M[1][2]) && gmFuzEQ(m_[1][3], M[1][3]) && 	  gmFuzEQ(m_[2][0], M[2][0]) && gmFuzEQ(m_[2][1], M[2][1]) &&	  gmFuzEQ(m_[2][2], M[2][2]) && gmFuzEQ(m_[2][3], M[2][3]) &&	  gmFuzEQ(m_[3][0], M[3][0]) && gmFuzEQ(m_[3][1], M[3][1]) &&	  gmFuzEQ(m_[3][2], M[3][2]) && gmFuzEQ(m_[3][3], M[3][3]));}bool gmMatrix4::operator !=(const gmMatrix4& M) const{  return (!(*this == M));}gmVector4 gmMatrix4::operator *(const gmVector4& v) const{  return gmVector4(    m_[0][0] * v[0] + m_[0][1] * v[1] + m_[0][2] * v[2] + m_[0][3] * v[3],    m_[1][0] * v[0] + m_[1][1] * v[1] + m_[1][2] * v[2] + m_[1][3] * v[3],    m_[2][0] * v[0] + m_[2][1] * v[1] + m_[2][2] * v[2] + m_[2][3] * v[3],    m_[3][0] * v[0] + m_[3][1] * v[1] + m_[3][2] * v[2] + m_[3][3] * v[3]);}gmVector4 operator *(const gmVector4& v, const gmMatrix4& M){  return gmVector4(    v[0] * M[0][0] + v[1] * M[1][0] + v[2] * M[2][0] + v[3] * M[3][0],    v[0] * M[0][1] + v[1] * M[1][1] + v[2] * M[2][1] + v[3] * M[3][1],    v[0] * M[0][2] + v[1] * M[1][2] + v[2] * M[2][2] + v[3] * M[3][2],    v[0] * M[0][3] + v[1] * M[1][3] + v[2] * M[2][3] + v[3] * M[3][3]);}// OPERATIONSgmMatrix4 gmMatrix4::transpose() const{  return gmMatrix4(m_[0][0], m_[1][0], m_[2][0], m_[3][0],		   m_[0][1], m_[1][1], m_[2][1], m_[3][1],		   m_[0][2], m_[1][2], m_[2][2], m_[3][2],		   m_[0][3], m_[1][3], m_[2][3], m_[3][3]);}gmMatrix4 gmMatrix4::inverse() const{  assert(!isSingular());  return adjoint() * gmInv(determinant());}gmMatrix4 gmMatrix4::adjoint() const{  gmMatrix4 A;    A[0][0] =  MINOR(*this, 1, 2, 3, 1, 2, 3);  A[0][1] = -MINOR(*this, 0, 2, 3, 1, 2, 3);  A[0][2] =  MINOR(*this, 0, 1, 3, 1, 2, 3);  A[0][3] = -MINOR(*this, 0, 1, 2, 1, 2, 3);  A[1][0] = -MINOR(*this, 1, 2, 3, 0, 2, 3);  A[1][1] =  MINOR(*this, 0, 2, 3, 0, 2, 3);  A[1][2] = -MINOR(*this, 0, 1, 3, 0, 2, 3);  A[1][3] =  MINOR(*this, 0, 1, 2, 0, 2, 3);  A[2][0] =  MINOR(*this, 1, 2, 3, 0, 1, 3);  A[2][1] = -MINOR(*this, 0, 2, 3, 0, 1, 3);  A[2][2] =  MINOR(*this, 0, 1, 3, 0, 1, 3);  A[2][3] = -MINOR(*this, 0, 1, 2, 0, 1, 3);  A[3][0] = -MINOR(*this, 1, 2, 3, 0, 1, 2);  A[3][1] =  MINOR(*this, 0, 2, 3, 0, 1, 2);  A[3][2] = -MINOR(*this, 0, 1, 3, 0, 1, 2);  A[3][3] =  MINOR(*this, 0, 1, 2, 0, 1, 2);  return A;}double gmMatrix4::determinant() const{  return m_[0][0] * MINOR(*this, 1, 2, 3, 1, 2, 3) -	 m_[0][1] * MINOR(*this, 1, 2, 3, 0, 2, 3) +	 m_[0][2] * MINOR(*this, 1, 2, 3, 0, 1, 3) -	 m_[0][3] * MINOR(*this, 1, 2, 3, 0, 1, 2);}bool gmMatrix4::isSingular() const{  return gmIsZero(determinant());}gmVector3 gmMatrix4::transform(const gmVector3& v) const{  return gmVector3(    v[0] * m_[0][0] + v[1] * m_[1][0] + v[2] * m_[2][0] + m_[3][0],    v[0] * m_[0][1] + v[1] * m_[1][1] + v[2] * m_[2][1] + m_[3][1],    v[0] * m_[0][2] + v[1] * m_[1][2] + v[2] * m_[2][2] + m_[3][2]);}////////////////////////////////////////////////////////////////////////////// TRANSFORMATION MATRICESgmMatrix4 gmMatrix4::identity(){  return gmMatrix4(1, 0, 0, 0,		   0, 1, 0, 0,		   0, 0, 1, 0,		   0, 0, 0, 1);}gmMatrix4 gmMatrix4::rotate(double angle, const gmVector3& axis){  gmMatrix4 m_;  double length = axis.length();  double a = axis[0] / length;  double b = axis[1] / length;  double c = axis[2] / length;  double aa = a * a;  double bb = b * b;  double cc = c * c;  double sine = sin(gmRadians(angle));  double cosine = cos(gmRadians(angle));  double omcos = 1 - cosine;  m_[0][0] = aa + (1 - aa) * cosine;  m_[1][1] = bb + (1 - bb) * cosine;  m_[2][2] = cc + (1 - cc) * cosine;  m_[0][1] = a * b * omcos + c * sine;  m_[0][2] = a * c * omcos - b * sine;  m_[1][0] = a * b * omcos - c * sine;  m_[1][2] = b * c * omcos + a * sine;  m_[2][0] = a * c * omcos + b * sine;  m_[2][1] = b * c * omcos - a * sine;  m_[0][3] = m_[1][3] = m_[2][3] = m_[3][0] = m_[3][1] = m_[3][2] = 0;  m_[3][3] = 1;     return m_;}gmMatrix4 gmMatrix4::scale(double x, double y, double z){  return gmMatrix4(x, 0, 0, 0,		   0, y, 0, 0,		   0, 0, z, 0,		   0, 0, 0, 1);}gmMatrix4 gmMatrix4::translate(double x, double y, double z){  return gmMatrix4(1, 0, 0, 0,		   0, 1, 0, 0,		   0, 0, 1, 0,		   x, y, z, 1);}////////////////////////////////////////////////////////////////////////////// CUBIC BASIS MATRICESgmMatrix4 gmMatrix4::bezierBasis(){  return gmMatrix4(-1,  3, -3,  1,	 	    3, -6,  3,  0,		   -3,  3,  0,  0,		    1,  0,  0,  0);}gmMatrix4 gmMatrix4::bsplineBasis(){    return gmMatrix4(-1,  3, -3,  1,		    3, -6,  3,  0,		   -3,  0,  3,  0,		    1,  4,  1,  0) / 6;}gmMatrix4 gmMatrix4::catmullromBasis(){  return gmMatrix4(-1,  3, -3,  1,		    2, -5,  4, -1,		   -1,  0,  1,  0,		    0,  2,  0,  0) / 2;}gmMatrix4 gmMatrix4::hermiteBasis(){  return gmMatrix4( 2,  1, -2,  1,		   -3, -2,  3, -1,		    0,  1,  0,  0,		    1,  0,  0,  0);}gmMatrix4 gmMatrix4::tensedBSplineBasis(double tension){  gmMatrix4 m;  double sixth = 1.0 / 6.0;  m[0][0] = sixth * (-tension);  m[0][1] = sixth * (12.0 - 9.0 * tension);  m[0][2] = sixth * (9.0 * tension - 12.0);  m[0][3] = sixth * tension;  m[1][0] = sixth * 3.0 * tension;  m[1][1] = sixth * (12.0 * tension - 18.0);  m[1][2] = sixth * (18.0 - 15.0 * tension);  m[1][3] = 0.0;  m[2][0] = sixth * -3.0 * tension;  m[2][1] = 0.0;  m[2][2] = sixth * 3.0 * tension;  m[2][3] = 0.0;  m[3][0] = sixth * tension;  m[3][1] = sixth * (6.0 - 2.0 * tension);  m[3][2] = sixth * tension;  m[3][3] = 0.0;  return m;}gmMatrix4 gmMatrix4::cardinalBasis(double tension){  gmMatrix4 m;    m[0][0] = -tension;  m[0][1] = 2.0 - tension;  m[0][2] = tension - 2.0;  m[0][3] = tension;  m[1][0] = 2.0 * tension;  m[1][1] = tension - 3.0;  m[1][2] = 3 - 2.0 * tension;  m[1][3] = -tension;  m[2][0] = -tension;  m[2][1] = 0.0;  m[2][2] = tension;  m[2][3] = 0.0;  m[3][0] = 0.0;  m[3][1] = 1.0;  m[3][2] = 0.0;  m[3][3] = 0.0;    return m;}gmMatrix4 gmMatrix4::tauBasis(double bias, double tension){  gmMatrix4 m;    m[0][0] = tension * (bias - 1.0);  m[0][1] = 2.0 - tension * bias;  m[0][2] = tension * (1.0 - bias) - 2.0;  m[0][3] = tension * bias;  m[1][0] = tension * 2.0 * (1.0 - bias);  m[1][1] = tension * (3.0 * bias - 1.0) - 3.0;  m[1][2] = 3.0 - tension;  m[1][3] = -tension * bias;  m[2][0] = tension * (bias - 1.0);  m[2][1] = tension * (1.0 - 2.0 * bias);  m[2][2] = tension * bias;  m[2][3] = 0.0;  m[3][0] = 0.0;  m[3][1] = 1.0;  m[3][2] = 0.0;  m[3][3] = 0.0;    return m;}gmMatrix4 gmMatrix4::betaSplineBasis(double bias, double tension){  gmMatrix4 m;  double bias2, bias3, d;  bias2 = bias * bias;  bias3 = bias * bias2;  d = 1.0 / (tension + 2.0 * bias3 + 4.0 * bias2 + 4.0 * bias + 2.0);  m[0][0] = -d * 2.0 * bias3;  m[0][1] = d * 2.0 * (tension + bias3 + bias2 + bias);  m[0][2] = -d * 2.0 * (tension + bias2 + bias + 1.0);  m[0][3] = d * 2.0;  m[1][0] = d * 6.0 * bias3;  m[1][1] = -d * 3.0 * (tension + 2.0 * bias3 + 2.0 * bias2);  m[1][2] = d * 3.0 * (tension + 2 * bias2);  m[1][3] = 0.0;    m[2][0] = -d * 6.0 * bias3;  m[2][1] = d * 6.0 * (bias3 - bias);  m[2][2] = d * 6.0 * bias;  m[2][3] = 0.0;  m[3][0] = d * 2.0 * bias3;  m[3][1] = d * (tension + 4 * (bias2 + bias));  m[3][2] = d * 2.0;  m[3][3] = 0.0;  return m;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -