matrix4.hpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:12k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: matrix4.hpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:48:55  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.6
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef GUI_MATH___MATRIX4___HPP
  10. #define GUI_MATH___MATRIX4___HPP
  11. /*  $Id: matrix4.hpp,v 1000.2 2004/06/01 19:48:55 gouriano Exp $
  12.  * ===========================================================================
  13.  *
  14.  *                            PUBLIC DOMAIN NOTICE
  15.  *               National Center for Biotechnology Information
  16.  *
  17.  *  This software / database is a "United States Government Work" under the
  18.  *  terms of the United States Copyright Act.  It was written as part of
  19.  *  the author's official duties as a United States Government employee and
  20.  *  thus cannot be copyrighted.  This software / database is freely available
  21.  *  to the public for use. The National Library of Medicine and the U.S.
  22.  *  Government have not placed any restriction on its use or reproduction.
  23.  *
  24.  *  Although all reasonable efforts have been taken to ensure the accuracy
  25.  *  and reliability of the software and data, the NLM and the U.S.
  26.  *  Government do not and cannot warrant the performance or results that
  27.  *  may be obtained by using this software or data. The NLM and the U.S.
  28.  *  Government disclaim all warranties, express or implied, including
  29.  *  warranties of performance, merchantability or fitness for any particular
  30.  *  purpose.
  31.  *
  32.  *  Please cite the author in any work or product based on this material.
  33.  *
  34.  * ===========================================================================
  35.  *
  36.  * Authors:  Mike DiCuccio
  37.  *
  38.  * File Description:
  39.  *
  40.  */
  41. #include <corelib/ncbistd.hpp>
  42. #include <gui/math/vect4.hpp>
  43. /** @addtogroup GUI_MATH
  44.  *
  45.  * @{
  46.  */
  47. BEGIN_NCBI_SCOPE
  48. template <class T>
  49. class CMatrix4
  50. {
  51. public:
  52.     // ctors
  53.     CMatrix4();
  54.     CMatrix4 (T val);
  55.     CMatrix4 (T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T);
  56.     CMatrix4 (T[16]);
  57.     CMatrix4 (T[4][4]);
  58.     //
  59.     // operators
  60.     //
  61.     // operator: index
  62.     const T&    operator() (int i, int j) const { return m_Data[i * 4+j]; }
  63.     T&          operator() (int i, int j)       { return m_Data[i * 4+j]; }
  64.     // operator: index
  65.     const T&    operator[] (int i) const        { return m_Data[i]; }
  66.     T&          operator[] (int i)              { return m_Data[i]; }
  67.     // operator: addition
  68.     CMatrix4<T>& operator+= (T);
  69.     CMatrix4<T>& operator+= (const CMatrix4<T>&);
  70.     // operator: subtraction
  71.     CMatrix4<T>& operator-= (T);
  72.     CMatrix4<T>& operator-= (const CMatrix4<T>&);
  73.     // operator: multiplication
  74.     CMatrix4<T>& operator*= (T);
  75.     CMatrix4<T>& operator*= (const CMatrix4<T>&);
  76.     // operator: division
  77.     CMatrix4<T>& operator/= (T);
  78.     //
  79.     // named functions
  80.     // transpose the current matrix
  81.     void        Transpose();
  82.     // make the current matrix an identity matrix
  83.     void        Identity();
  84.     // clear the current matrix to a given value
  85.     void        Clear(T x = (T)0);
  86.     // return the determinant of the current matrix
  87.     T           Determinant() const;
  88.     // data accessor
  89.     const T*    GetData() const    { return m_Data; }
  90.     // return a vector representing a row
  91.     CVect4<T>   Row(int) const;
  92.     // return a vector representing a column
  93.     CVect4<T>   Column(int) const;
  94. private:
  95.     T m_Data[16];
  96. };
  97. END_NCBI_SCOPE
  98. //
  99. // global operations
  100. // this is included after the class declaration
  101. #include <gui/math/globals.hpp>
  102. BEGIN_NCBI_SCOPE
  103. //
  104. // default ctor
  105. template <class T> inline
  106. CMatrix4<T>::CMatrix4()
  107. {
  108.     Clear(T(0));
  109. }
  110. //
  111. // conversion ctors
  112. template <class T> inline
  113. CMatrix4<T>::CMatrix4(T val)
  114. {
  115.     Clear(val);
  116. }
  117. template <class T> inline
  118. CMatrix4<T>::CMatrix4(T m1,  T m2,  T m3,  T m4,
  119.                       T m5,  T m6,  T m7,  T m8,
  120.                       T m9,  T m10, T m11, T m12,
  121.                       T m13, T m14, T m15, T m16)
  122. {
  123.     m_Data[ 0] = m1;  m_Data[ 1] = m2;  m_Data[ 2] = m3;  m_Data[ 3] = m4;
  124.     m_Data[ 4] = m5;  m_Data[ 5] = m6;  m_Data[ 6] = m7;  m_Data[ 7] = m8;
  125.     m_Data[ 8] = m9;  m_Data[ 9] = m10; m_Data[10] = m11; m_Data[11] = m12;
  126.     m_Data[12] = m13; m_Data[13] = m14; m_Data[14] = m15; m_Data[15] = m16;
  127. }
  128. template <class T> inline
  129. CMatrix4<T>::CMatrix4(T m[16])
  130. {
  131.     for (int i = 0;  i < 16;  ++i) {
  132.         m_Data[i] = m[i];
  133.     }
  134. }
  135. template <class T> inline
  136. CMatrix4<T>::CMatrix4(T m[4][4])
  137. {
  138.     m_Data[ 0] = m[0][0];
  139.     m_Data[ 1] = m[0][1];
  140.     m_Data[ 2] = m[0][2];
  141.     m_Data[ 3] = m[0][3];
  142.     m_Data[ 4] = m[1][0];
  143.     m_Data[ 5] = m[1][1];
  144.     m_Data[ 6] = m[1][2];
  145.     m_Data[ 7] = m[1][3];
  146.     m_Data[ 8] = m[2][0];
  147.     m_Data[ 9] = m[2][1];
  148.     m_Data[10] = m[2][2];
  149.     m_Data[11] = m[2][3];
  150.     m_Data[12] = m[3][0];
  151.     m_Data[13] = m[3][1];
  152.     m_Data[14] = m[3][2];
  153.     m_Data[15] = m[3][3];
  154. }
  155. //
  156. // addition: scalar
  157. template <class T> inline CMatrix4<T>&
  158. CMatrix4<T>::operator+= (T scalar)
  159. {
  160.     for (int i = 0;  i < 16;  ++i) {
  161.         m_Data[i] += scalar;
  162.     }
  163.     return *this;
  164. }
  165. //
  166. // addition: matrix
  167. template <class T> inline CMatrix4<T>&
  168. CMatrix4<T>::operator+= (const CMatrix4<T>& m)
  169. {
  170.     for (int i = 0;  i < 16;  ++i) {
  171.         m_Data[i] += m[i];
  172.     }
  173.     return *this;
  174. }
  175. //
  176. // subtraction: scalar
  177. template <class T> inline CMatrix4<T>&
  178. CMatrix4<T>::operator-= (T scalar)
  179. {
  180.     for (int i = 0;  i < 16;  ++i) {
  181.         m_Data[i] -= scalar;
  182.     }
  183.     return *this;
  184. }
  185. //
  186. // subtraction: matrix
  187. template <class T> inline CMatrix4<T>&
  188. CMatrix4<T>::operator-= (const CMatrix4<T>& m)
  189. {
  190.     for (int i = 0;  i < 16;  ++i) {
  191.         m_Data[i] -= m[i];
  192.     }
  193.     return *this;
  194. }
  195. //
  196. // multiplication: scalar
  197. template <class T> inline CMatrix4<T>&
  198. CMatrix4<T>::operator*= (T scalar)
  199. {
  200.     for (int i = 0;  i < 16;  ++i) {
  201.         m_Data[i] *= scalar;
  202.     }
  203.     return *this;
  204. }
  205. //
  206. // multiplication: matrix
  207. template <class T> inline CMatrix4<T>&
  208. CMatrix4<T>::operator*= (const CMatrix4<T>& m)
  209. {
  210.     // given
  211.     // 
  212.     // a b c   1 2 3
  213.     // d e f   4 5 6
  214.     // g h i   7 8 9
  215.     // 
  216.     // result is:
  217.     //  (a1 + b4 + c7)  (a2 + b5 + c8)  (a3 + b6 + c9)
  218.     //  (d1 + e4 + f7)  (d2 + e5 + f8)  (d3 + e6 + f9)
  219.     //  (g1 + h4 + i7)  (g2 + h5 + i8)  (g3 + h6 + i9)
  220.     T t0;
  221.     T t1;
  222.     T t2;
  223.     T t3;
  224.     t0 = m_Data[ 0] * m[ 0] + m_Data[ 1] * m[ 4] +
  225.         m_Data[ 2] * m[ 8] + m_Data[ 3] * m[12];
  226.     t1 = m_Data[ 0] * m[ 1] + m_Data[ 1] * m[ 5] +
  227.         m_Data[ 2] * m[ 9] + m_Data[ 3] * m[13];
  228.     t2 = m_Data[ 0] * m[ 2] + m_Data[ 1] * m[ 6] +
  229.         m_Data[ 2] * m[10] + m_Data[ 3] * m[14];
  230.     t3 = m_Data[ 0] * m[ 3] + m_Data[ 1] * m[ 7] +
  231.         m_Data[ 2] * m[11] + m_Data[ 3] * m[15];
  232.     m_Data[0] = t0;
  233.     m_Data[1] = t1;
  234.     m_Data[2] = t2;
  235.     m_Data[3] = t3;
  236.     t0 = m_Data[ 4] * m[ 0] + m_Data[ 5] * m[ 4] +
  237.         m_Data[ 6] * m[ 8] + m_Data[ 7] * m[12];
  238.     t1 = m_Data[ 4] * m[ 1] + m_Data[ 5] * m[ 5] +
  239.         m_Data[ 6] * m[ 9] + m_Data[ 7] * m[13];
  240.     t2 = m_Data[ 4] * m[ 2] + m_Data[ 5] * m[ 6] +
  241.         m_Data[ 6] * m[10] + m_Data[ 7] * m[14];
  242.     t3 = m_Data[ 4] * m[ 3] + m_Data[ 5] * m[ 7] +
  243.         m_Data[ 6] * m[11] + m_Data[ 7] * m[15];
  244.     m_Data[4] = t0;
  245.     m_Data[5] = t1;
  246.     m_Data[6] = t2;
  247.     m_Data[7] = t3;
  248.     t0 = m_Data[ 8] * m[ 0] + m_Data[ 9] * m[ 4] +
  249.         m_Data[10] * m[ 8] + m_Data[11] * m[12];
  250.     t1 = m_Data[ 8] * m[ 1] + m_Data[ 9] * m[ 5] +
  251.         m_Data[10] * m[ 9] + m_Data[11] * m[13];
  252.     t2 = m_Data[ 8] * m[ 2] + m_Data[ 9] * m[ 6] +
  253.         m_Data[10] * m[10] + m_Data[11] * m[14];
  254.     t3 = m_Data[ 8] * m[ 3] + m_Data[ 9] * m[ 7] +
  255.         m_Data[10] * m[11] + m_Data[11] * m[15];
  256.     m_Data[ 8] = t0;
  257.     m_Data[ 9] = t1;
  258.     m_Data[10] = t2;
  259.     m_Data[11] = t3;
  260.     t0 = m_Data[12] * m[ 0] + m_Data[13] * m[ 4] +
  261.         m_Data[14] * m[ 8] + m_Data[15] * m[12];
  262.     t1 = m_Data[12] * m[ 1] + m_Data[13] * m[ 5] +
  263.         m_Data[14] * m[ 9] + m_Data[15] * m[13];
  264.     t2 = m_Data[12] * m[ 2] + m_Data[13] * m[ 6] +
  265.         m_Data[14] * m[10] + m_Data[15] * m[14];
  266.     t3 = m_Data[12] * m[ 3] + m_Data[13] * m[ 7] +
  267.         m_Data[14] * m[11] + m_Data[15] * m[15];
  268.     m_Data[12] = t0;
  269.     m_Data[13] = t1;
  270.     m_Data[14] = t2;
  271.     m_Data[15] = t3;
  272.     return *this;
  273. }
  274. //
  275. // division: scalar
  276. template <class T> inline CMatrix4<T>&
  277. CMatrix4<T>::operator/= (T scalar)
  278. {
  279.     scalar = T(1) / scalar;
  280.     for (int i = 0;  i < 16;  ++i) {
  281.         m_Data[i] *= scalar;
  282.     }
  283.     return *this;
  284. }
  285. //
  286. // transpose a matrix
  287. template <class T> inline void
  288. CMatrix4<T>::Transpose()
  289. {
  290.     // given
  291.     //   a b c d
  292.     //   e f g h
  293.     //   i j k l
  294.     //   m n o p
  295.     //   
  296.     // result is
  297.     //   a e i m
  298.     //   b f j n
  299.     //   c g k o
  300.     //   d h l p
  301.     std::swap(m_Data[ 1], m_Data[ 4]);
  302.     std::swap(m_Data[ 2], m_Data[ 8]);
  303.     std::swap(m_Data[ 3], m_Data[12]);
  304.     std::swap(m_Data[ 6], m_Data[ 9]);
  305.     std::swap(m_Data[ 7], m_Data[13]);
  306.     std::swap(m_Data[11], m_Data[14]);
  307. }
  308. //
  309. // create a unit matrix
  310. template <class T> inline void
  311. CMatrix4<T>::Identity()
  312. {
  313.     Clear((T)0);
  314.     m_Data[ 0] = 1;
  315.     m_Data[ 5] = 1;
  316.     m_Data[10] = 1;
  317.     m_Data[15] = 1;
  318. }
  319. //
  320. // clear a matrix so that all its values are the passed value
  321. template <class T> inline void
  322. CMatrix4<T>::Clear(T value)
  323. {
  324.     for (int i = 0;  i < 16;  ++i) {
  325.         m_Data[i] = value;
  326.     }
  327. }
  328. //
  329. // return a row as a vector
  330. template <class T> inline CVect4<T>
  331. CMatrix4<T>::Row(int i) const
  332. {
  333.     return CVect4<T> (m_Data[i<<2    ],
  334.                       m_Data[i<<2 + 1],
  335.                       m_Data[i<<2 + 2] ,
  336.                       m_Data[i<<2 + 3]);
  337. }
  338. //
  339. // return a column as a vector
  340. template <class T> inline CVect4<T>
  341. CMatrix4<T>::Column(int j) const
  342. {
  343.     return CVect4<T> (m_Data[     j],
  344.                       m_Data[ 4 + j],
  345.                       m_Data[ 8 + j],
  346.                       m_Data[12 + j]);
  347. }
  348. //
  349. // return the determinant of a 3x3 matrix
  350. template <class T> inline T
  351. CMatrix4<T>::Determinant() const
  352. {
  353.     // given
  354.     //  a b c d
  355.     //  e f g h
  356.     //  i j k l
  357.     //  m n o p
  358.     // 
  359.     // determinant is
  360.     // 
  361.     // + a[ f(kp - lo) - g(jp - ln) + h(jo - kn) ]
  362.     // - b[ e(kp - lo) - g(ip - lm) + h(io - km) ]
  363.     // + c[ e(jp - ln) - f(ip - lm) + h(in - jm) ]
  364.     // - d[ e(jo - kn) - f(io - km) + g(in - jm) ]
  365.     T det;
  366.     T kp = m_Data[10]*m_Data[15];
  367.     T lo = m_Data[11]*m_Data[14];
  368.     T jp = m_Data[ 9]*m_Data[15];
  369.     T ln = m_Data[11]*m_Data[13];
  370.     T jo = m_Data[ 9]*m_Data[14];
  371.     T kn = m_Data[10]*m_Data[13];
  372.     det = m_Data[0] * ( m_Data[5]*(kp - lo)
  373.                         - m_Data[6]*(jp - ln)
  374.                         + m_Data[7]*(jo - kn) );
  375.     T ip = m_Data[ 8]*m_Data[15];
  376.     T lm = m_Data[11]*m_Data[12];
  377.     T io = m_Data[ 8]*m_Data[14];
  378.     T km = m_Data[10]*m_Data[12];
  379.     det -= m_Data[1] * ( m_Data[4]*(kp - lo)
  380.                          - m_Data[6]*(ip - lm)
  381.                          + m_Data[7]*(io - km) );
  382.     T in = m_Data[ 8]*m_Data[13];
  383.     T jm = m_Data[ 9]*m_Data[12];
  384.     det += m_Data[3] * ( m_Data[4]*(jp - ln)
  385.                          - m_Data[5]*(ip - lm)
  386.                          + m_Data[7]*(in - jm) );
  387.     det -= m_Data[4] * ( m_Data[4]*(jo - kn)
  388.                          - m_Data[5]*(io - km)
  389.                          + m_Data[6]*(in - jm) );
  390.     return det;
  391. }
  392. END_NCBI_SCOPE
  393. /* @} */
  394. /*
  395.  * ===========================================================================
  396.  * $Log: matrix4.hpp,v $
  397.  * Revision 1000.2  2004/06/01 19:48:55  gouriano
  398.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.6
  399.  *
  400.  * Revision 1.6  2004/05/11 18:53:50  dicuccio
  401.  * Added doxygen modules info
  402.  *
  403.  * Revision 1.5  2004/05/03 13:10:01  dicuccio
  404.  * Removed gui/gui.hpp --> not necessary for math projects
  405.  *
  406.  * Revision 1.4  2004/05/03 12:43:35  dicuccio
  407.  * Added #include for gui/gui.hpp
  408.  *
  409.  * Revision 1.3  2004/04/26 17:28:18  ucko
  410.  * Add a missing type declaration in matrix += scalar code.
  411.  *
  412.  * Revision 1.2  2004/03/11 17:17:07  dicuccio
  413.  * FIxed include guards
  414.  *
  415.  * Revision 1.1  2003/06/09 19:30:50  dicuccio
  416.  * Initial revision
  417.  *
  418.  * ===========================================================================
  419.  */
  420. #endif // GUI_MATH___MATRIX4___HPP