home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 3 / RISC_DISC_3.iso / resources / etexts / gems / gemsv / ch7_7 / libgm / gmmat3.cc < prev    next >
C/C++ Source or Header  |  1995-03-07  |  7KB  |  281 lines

  1. // gmMatrix3.cc - 3x3 element matrix class
  2. //
  3. // libgm++: Graphics Math Library
  4. // Ferdi Scheepers and Stephen F May
  5. // 15 June 1994
  6.  
  7. #include "gmMat3.h"
  8. #include "gmVec2.h"
  9. #include "gmVec3.h"
  10.  
  11. // private function: RCD
  12. // - dot product of row i of matrix A and row j of matrix B
  13.  
  14. inline double RCD(const gmMatrix3& A, const gmMatrix3& B, int i, int j)
  15. {
  16.   return A[i][0] * B[0][j] + A[i][1] * B[1][j] + A[i][2] * B[2][j];
  17. }
  18.  
  19. // private function: MINOR
  20. // - MINOR of M[r][c]; r in {0,1,2}-{r0,r1}; c in {0,1,2}-{c0,c1}
  21.  
  22. inline double MINOR(const gmMatrix3& M, int r0, int r1, int c0, int c1)
  23. {
  24.   return M[r0][c0] * M[r1][c1] - M[r1][c0] * M[r0][c1];
  25. }
  26.  
  27. // CONSTRUCTORS
  28.  
  29. gmMatrix3::gmMatrix3()
  30. {
  31.   assign(0,0,0, 0,0,0, 0,0,0);
  32. }
  33.  
  34. gmMatrix3::gmMatrix3(const gmMatrix3& M)
  35. {
  36.   assign(M[0][0], M[0][1], M[0][2],
  37.          M[1][0], M[1][1], M[1][2],
  38.          M[2][0], M[2][1], M[2][2]);
  39. }
  40.  
  41. gmMatrix3::gmMatrix3(double a00, double a01, double a02,
  42.              double a10, double a11, double a12,
  43.              double a20, double a21, double a22)
  44. {
  45.   assign(a00, a01, a02,
  46.          a10, a11, a12,
  47.          a20, a21, a22);
  48. }
  49.  
  50. // ASSIGNMENT
  51.  
  52. gmMatrix3& gmMatrix3::assign(double a00, double a01, double a02,
  53.                      double a10, double a11, double a12,
  54.                      double a20, double a21, double a22)
  55. {
  56.   m_[0][0] = a00; m_[0][1] = a01; m_[0][2] = a02;
  57.   m_[1][0] = a10; m_[1][1] = a11; m_[1][2] = a12;
  58.   m_[2][0] = a20; m_[2][1] = a21; m_[2][2] = a22;
  59.   return *this;
  60. }
  61.  
  62. gmMatrix3& gmMatrix3::operator =(const gmMatrix3& M)
  63. {
  64.   assign(M[0][0], M[0][1], M[0][2],
  65.      M[1][0], M[1][1], M[1][2],
  66.          M[2][0], M[2][1], M[2][2]);
  67.   return *this;
  68. }
  69.  
  70. // OPERATORS
  71.  
  72. gmMatrix3& gmMatrix3::operator +=(const gmMatrix3& M)
  73. {
  74.   m_[0][0] += M[0][0]; m_[0][1] += M[0][1]; m_[0][2] += M[0][2];
  75.   m_[1][0] += M[1][0]; m_[1][1] += M[1][1]; m_[1][2] += M[1][2];
  76.   m_[2][0] += M[2][0]; m_[2][1] += M[2][1]; m_[2][2] += M[2][2];
  77.   return *this;
  78. }
  79.  
  80. gmMatrix3& gmMatrix3::operator -=(const gmMatrix3& M)
  81. {
  82.   m_[0][0] -= M[0][0]; m_[0][1] -= M[0][1]; m_[0][2] -= M[0][2];
  83.   m_[1][0] -= M[1][0]; m_[1][1] -= M[1][1]; m_[1][2] -= M[1][2];
  84.   m_[2][0] -= M[2][0]; m_[2][1] -= M[2][1]; m_[2][2] -= M[2][2];
  85.   return *this;
  86. }
  87.  
  88. gmMatrix3& gmMatrix3::operator *=(const gmMatrix3& M)
  89. {
  90.   assign(RCD(*this, M, 0, 0), RCD(*this, M, 0, 1), RCD(*this, M, 0, 2),
  91.      RCD(*this, M, 1, 0), RCD(*this, M, 1, 1), RCD(*this, M, 1, 2),
  92.      RCD(*this, M, 2, 0), RCD(*this, M, 2, 1), RCD(*this, M, 2, 2));
  93.   return *this;
  94. }
  95.  
  96. gmMatrix3& gmMatrix3::operator *=(double d)
  97. {
  98.   m_[0][0] *= d; m_[0][1] *= d; m_[0][2] *= d;
  99.   m_[1][0] *= d; m_[1][1] *= d; m_[1][2] *= d;
  100.   m_[2][0] *= d; m_[2][1] *= d; m_[2][2] *= d;
  101.   return *this;
  102. }
  103.  
  104. gmMatrix3& gmMatrix3::operator /=(double d)
  105. {
  106.   double di = 1 / d;
  107.   m_[0][0] *= di; m_[0][1] *= di; m_[0][2] *= di;
  108.   m_[1][0] *= di; m_[1][1] *= di; m_[1][2] *= di;
  109.   m_[2][0] *= di; m_[2][1] *= di; m_[2][2] *= di;
  110.   return *this;
  111. }
  112.  
  113. gmMatrix3 gmMatrix3::operator +(const gmMatrix3& M) const
  114. {
  115.   return gmMatrix3(m_[0][0] + M[0][0], m_[0][1] + M[0][1], m_[0][2] + M[0][2],
  116.            m_[1][0] + M[1][0], m_[1][1] + M[1][1], m_[1][2] + M[1][2],
  117.            m_[2][0] + M[2][0], m_[2][1] + M[2][1], m_[2][2] + M[2][2]);
  118. }
  119.  
  120. gmMatrix3 gmMatrix3::operator -(const gmMatrix3& M) const
  121. {
  122.   return gmMatrix3(m_[0][0] - M[0][0], m_[0][1] - M[0][1], m_[0][2] - M[0][2],
  123.            m_[1][0] - M[1][0], m_[1][1] - M[1][1], m_[1][2] - M[1][2],
  124.            m_[2][0] - M[2][0], m_[2][1] - M[2][1], m_[2][2] - M[2][2]);
  125. }
  126.  
  127. gmMatrix3 gmMatrix3::operator -() const
  128. {
  129.   return gmMatrix3(-m_[0][0], -m_[0][1], -m_[0][2],
  130.            -m_[1][0], -m_[1][1], -m_[1][2],
  131.                    -m_[2][0], -m_[2][1], -m_[2][2]);
  132. }
  133.  
  134. gmMatrix3 gmMatrix3::operator *(const gmMatrix3& M) const
  135. {
  136.   return
  137.     gmMatrix3(RCD(*this, M, 0, 0), RCD(*this, M, 0, 1), RCD(*this, M, 0, 2),
  138.               RCD(*this, M, 1, 0), RCD(*this, M, 1, 1), RCD(*this, M, 1, 2),
  139.               RCD(*this, M, 2, 0), RCD(*this, M, 2, 1), RCD(*this, M, 2, 2));
  140. }
  141.  
  142. gmMatrix3 gmMatrix3::operator *(double d) const
  143. {
  144.   return gmMatrix3(m_[0][0] * d, m_[0][1] * d, m_[0][2] * d,
  145.            m_[1][0] * d, m_[1][1] * d, m_[1][2] * d,
  146.                    m_[2][0] * d, m_[2][1] * d, m_[2][2] * d);
  147. }
  148.  
  149. gmMatrix3 gmMatrix3::operator /(double d) const
  150. {
  151.   assert(!gmIsZero(d));
  152.   double di = 1 / d;
  153.   return gmMatrix3(m_[0][0] * di, m_[0][1] * di, m_[0][2] * di,
  154.            m_[1][0] * di, m_[1][1] * di, m_[1][2] * di,
  155.                    m_[2][0] * di, m_[2][1] * di, m_[2][2] * di);
  156. }
  157.  
  158. gmMatrix3 operator *(double d, const gmMatrix3& M)
  159. {
  160.   return gmMatrix3(M[0][0] * d, M[0][1] * d, M[0][2] * d,
  161.            M[1][0] * d, M[1][1] * d, M[1][2] * d,
  162.                    M[2][0] * d, M[2][1] * d, M[2][2] * d);
  163. }
  164.  
  165. bool gmMatrix3::operator ==(const gmMatrix3& M) const
  166. {
  167.   return(gmFuzEQ(m_[0][0], M[0][0]) &&
  168.          gmFuzEQ(m_[0][1], M[0][1]) &&
  169.      gmFuzEQ(m_[0][2], M[0][2]) &&
  170.      
  171.      gmFuzEQ(m_[1][0], M[1][0]) &&
  172.          gmFuzEQ(m_[1][1], M[1][1]) &&
  173.      gmFuzEQ(m_[1][2], M[1][2]) &&
  174.  
  175.      gmFuzEQ(m_[2][0], M[2][0]) &&
  176.          gmFuzEQ(m_[2][1], M[2][1]) &&
  177.      gmFuzEQ(m_[2][2], M[2][2]));
  178. }
  179.  
  180. bool gmMatrix3::operator !=(const gmMatrix3& M) const
  181. {
  182.   return (!(*this == M));
  183. }
  184.  
  185. gmVector3 gmMatrix3::operator *(const gmVector3& v) const
  186. {
  187.   return gmVector3(m_[0][0] * v[0] + m_[0][1] * v[1] + m_[0][2] * v[2],
  188.                    m_[1][0] * v[0] + m_[1][1] * v[1] + m_[1][2] * v[2],
  189.                    m_[2][0] * v[0] + m_[2][1] * v[1] + m_[2][2] * v[2]);
  190. }
  191.  
  192. gmVector3 operator *(const gmVector3& v, const gmMatrix3& M)
  193. {
  194.   return gmVector3(v[0] * M[0][0] + v[1] * M[1][0] + v[2] * M[2][0],
  195.                    v[0] * M[0][1] + v[1] * M[1][1] + v[2] * M[2][1],
  196.                    v[0] * M[0][2] * v[1] * M[1][2] + v[2] * M[2][2]);
  197. }
  198.  
  199. // OPERATIONS
  200.  
  201. gmMatrix3 gmMatrix3::transpose() const
  202. {
  203.   return gmMatrix3(m_[0][0], m_[1][0], m_[2][0],
  204.            m_[0][1], m_[1][1], m_[2][1],
  205.                    m_[0][2], m_[1][2], m_[2][2]);
  206. }
  207.  
  208. gmMatrix3 gmMatrix3::inverse() const
  209. {
  210.   assert(!isSingular());
  211.   return adjoint() * gmInv(determinant());
  212. }
  213.  
  214. gmMatrix3 gmMatrix3::adjoint() const
  215. {
  216.   gmMatrix3 A;
  217.   
  218.   A[0][0] =  MINOR(*this, 1, 2, 1, 2);
  219.   A[0][1] = -MINOR(*this, 0, 2, 1, 2);
  220.   A[0][2] =  MINOR(*this, 0, 1, 1, 2);
  221.   A[1][0] = -MINOR(*this, 1, 2, 0, 2);
  222.   A[1][1] =  MINOR(*this, 0, 2, 0, 2);
  223.   A[1][2] = -MINOR(*this, 0, 1, 0, 2);
  224.   A[2][0] =  MINOR(*this, 1, 2, 0, 1);
  225.   A[2][1] = -MINOR(*this, 0, 2, 0, 1);
  226.   A[2][2] =  MINOR(*this, 0, 1, 0, 1);
  227.  
  228.   return A;
  229. }
  230.  
  231. double gmMatrix3::determinant() const
  232. {
  233.   return m_[0][0] * MINOR(*this, 1, 2, 1, 2) -
  234.          m_[0][1] * MINOR(*this, 1, 2, 0, 2) +
  235.      m_[0][2] * MINOR(*this, 1, 2, 0, 1);
  236. }
  237.  
  238. bool gmMatrix3::isSingular() const
  239. {
  240.   return gmIsZero(determinant());
  241. }
  242.  
  243. gmVector2 gmMatrix3::transform(const gmVector2& v) const
  244. {
  245.   return gmVector2(v[0] * m_[0][0] + v[1] * m_[1][0] + m_[2][0],
  246.                    v[0] * m_[0][1] + v[1] * m_[1][1] + m_[2][1]);
  247. }
  248.  
  249. // TRANSFORMATION MATRICES
  250.  
  251. gmMatrix3 gmMatrix3::identity()
  252. {
  253.   return gmMatrix3(1, 0, 0,
  254.                    0, 1, 0,
  255.                    0, 0, 1);
  256. }
  257.  
  258. gmMatrix3 gmMatrix3::rotate(double angle)
  259. {
  260.   double sine = sin(gmRadians(angle));
  261.   double cosine = cos(gmRadians(angle));
  262.   
  263.   return gmMatrix3( cosine, sine,   0,
  264.                    -sine,   cosine, 0,
  265.                     0,      0,      1);
  266. }
  267.  
  268. gmMatrix3 gmMatrix3::scale(double x, double y)
  269. {
  270.   return gmMatrix3(x, 0, 0,
  271.            0, y, 0,
  272.            0, 0, 1);
  273. }
  274.  
  275. gmMatrix3 gmMatrix3::translate(double x, double y)
  276. {
  277.   return gmMatrix3(1, 0, 0,
  278.            0, 1, 0,
  279.            x, y, 1);
  280. }
  281.