Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Tools/Math/Matrix.h

Go to the documentation of this file.
00001 /** 
00002  * \file Matrix.h
00003  * Template classes for various 3x3 matrices.
00004  *
00005  * \author Martin Kallnik, martin.kallnik@gmx.de
00006  * \author Thomas Kindler, thomas.kindler@gmx.de 
00007  * \author Max Risler
00008  */
00009 
00010 #ifndef __Matrix_h__
00011 #define __Matrix_h__
00012 
00013 #include "Vector3.h"
00014 
00015 /**
00016  * This class represents a 3x3-matrix 
00017  *
00018  */
00019 template <class V> class Matrix3x3 {
00020 public:
00021   /** 
00022    * The columns of the matrix 
00023    */
00024   Vector3<V> c[3];
00025 
00026   /**
00027    * Default constructor. 
00028    */
00029   Matrix3x3<V>()
00030   {
00031     c[0]=Vector3<V>(1,0,0);
00032     c[1]=Vector3<V>(0,1,0);
00033     c[2]=Vector3<V>(0,0,1);
00034   }
00035 
00036   /**
00037    * Constructor.
00038    *
00039    * \param  c0  the first column of the matrix.
00040    * \param  c1  the second column of the matrix.
00041    * \param  c2  the third column of the matrix.
00042   */
00043   Matrix3x3<V>(
00044     const Vector3<V>& c0, 
00045     const Vector3<V>& c1, 
00046     const Vector3<V>& c2
00047   )
00048   {
00049     c[0] = c0;
00050     c[1] = c1;
00051     c[2] = c2;
00052   }
00053 
00054   /**
00055    * Assignment operator.
00056    *
00057    * \param  other   The other matrix that is assigned to this one
00058    * \return         A reference to this object after the assignment.
00059   */
00060   Matrix3x3<V>& operator=(const Matrix3x3<V>& other)
00061   {
00062     c[0] = other.c[0]; 
00063     c[1] = other.c[1]; 
00064     c[2] = other.c[2]; 
00065     return *this;
00066   }
00067 
00068   /**
00069    * Copy constructor.
00070    *
00071    * \param other The other matrix that is copied to this one
00072    */
00073   Matrix3x3<V>(const Matrix3x3<V>& other) 
00074   { 
00075     *this = other;
00076   }
00077 
00078   /**
00079    * Multiplication of this matrix by vector.
00080    *
00081    * \param  vector  The vector this one is multiplied by 
00082    * \return         A new vector containing the result
00083    *                 of the calculation.
00084   */
00085   Vector3<V> operator*(const Vector3<V>& vector) const
00086   {
00087     return (c[0]*vector.x + c[1]*vector.y + c[2]*vector.z);
00088   }
00089 
00090   /**
00091    * Multiplication of this matrix by another matrix.
00092    *
00093    * \param  other  The other matrix this one is multiplied by 
00094    * \return        A new matrix containing the result
00095    *                of the calculation.
00096   */
00097   Matrix3x3<V> operator*(const Matrix3x3<V>& other) const
00098   {
00099     return Matrix3x3<V>(
00100       (*this)*other.c[0], 
00101       (*this)*other.c[1], 
00102       (*this)*other.c[2]
00103     );
00104   }
00105 
00106   /**
00107    * Multiplication of this matrix by another matrix.
00108    * 
00109    * \param  other  The other matrix this one is multiplied by 
00110    * \return        A reference this object after the calculation.
00111   */
00112   Matrix3x3<V>& operator*=(const Matrix3x3<V>& other)
00113   {
00114     return *this = *this * other;
00115   }
00116 
00117   /**
00118    * Multiplication of this matrix by a factor.
00119    *
00120    * \param  factor  The factor this matrix is multiplied by 
00121    * \return         A reference to this object after the calculation.
00122   */
00123   Matrix3x3<V>& operator*=(const V& factor)
00124   {
00125     c[0] *= factor;
00126     c[1] *= factor;
00127     c[2] *= factor;
00128     return *this;
00129   }
00130 
00131   /**
00132    * Division of this matrix by a factor.
00133    *
00134    * \param  factor  The factor this matrix is divided by 
00135    * \return         A reference to this object after the calculation.
00136    */
00137   Matrix3x3<V>& operator/=(const V& factor)
00138   {
00139     *this *= 1 / factor;
00140     return *this;
00141   }
00142 
00143   /**
00144    * Multiplication of this matrix by a factor.
00145    *
00146    * \param  factor  The factor this matrix is multiplied by 
00147    * \return         A new object that contains the result of the calculation.
00148    */
00149   Matrix3x3<V> operator*(const V& factor) const
00150   {
00151     return Matrix3x3<V>(*this) *= factor;
00152   }
00153 
00154   /**
00155    * Division of this matrix by a factor.
00156    *
00157    * \param  factor  The factor this matrix is divided by 
00158    * \return         A new object that contains the result of the calculation.
00159    */
00160   Matrix3x3<V> operator/(const V& factor) const
00161   {
00162     return Matrix3x3<V>(*this) /= factor;
00163   }
00164 
00165   /**
00166    * Comparison of another matrix with this one.
00167    *
00168    * \param  other  The other matrix that will be compared to this one
00169    * \return        Whether the two matrices are equal.
00170    */
00171   bool operator==(const Matrix3x3<V>& other) const
00172   {
00173     return (
00174       c[0] == other.c[0] && 
00175       c[1] == other.c[1] && 
00176       c[2] == other.c[2]
00177     );
00178   }
00179 
00180   /**
00181    * Comparison of another matrix with this one.
00182    *
00183    * \param  other  The other matrix that will be compared to this one
00184    * \return        Whether the two matrixs are unequal.
00185    */
00186   bool operator!=(const Matrix3x3<V>& other) const
00187   {
00188     return !(*this == other);
00189   }
00190 
00191   /**
00192    * Array-like member access.
00193    * \param  i index
00194    * \return reference to column
00195    */
00196   Vector3<V>& operator[](int i) 
00197   {
00198     return c[i];
00199   }
00200   
00201   /**
00202    * Transpose the matrix
00203    *
00204    * \return  A new object containing transposed matrix
00205    */
00206   Matrix3x3<V> transpose() const
00207   {
00208     return Matrix3x3<V>(
00209       Vector3<V>(c[0].x, c[1].x, c[2].x),
00210       Vector3<V>(c[0].y, c[1].y, c[2].y),
00211       Vector3<V>(c[0].z, c[1].z, c[2].z)
00212     );
00213   }
00214   
00215   /**
00216    * Calculation of the determinant of this matrix.
00217    * 
00218    * \return The determinant.
00219    */
00220   V det() const 
00221   { 
00222     return 
00223       c[0].x * (c[1].y * c[2].z - c[1].z * c[2].y) +
00224       c[0].y * (c[1].z * c[2].x - c[1].x * c[2].z) +
00225       c[0].z * (c[1].x * c[2].y - c[1].y * c[2].x);
00226   }
00227   
00228   /**
00229    * Calculate determinant of 2x2 Submatrix  
00230    * | a b |
00231    * | c d |
00232    *
00233    * \return  determinant.
00234    */
00235   static V det2(V a, V b, V c, V d)
00236   {
00237     return a*d - b*c;
00238   }
00239 
00240   /**
00241    * Calculate the adjoint of this matrix.
00242    *
00243    * \return the adjoint matrix.
00244    */
00245   Matrix3x3<V> adjoint() const
00246   {
00247     return Matrix3x3<V>(
00248       Vector3<V>(
00249         det2(c[1].y, c[2].y, c[1].z, c[2].z), 
00250         det2(c[2].x, c[1].x, c[2].z, c[1].z), 
00251         det2(c[1].x, c[2].x, c[1].y, c[2].y)
00252       ),
00253       Vector3<V>(
00254         det2(c[2].y, c[0].y, c[2].z, c[0].z), 
00255         det2(c[0].x, c[2].x, c[0].z, c[2].z), 
00256         det2(c[2].x, c[0].x, c[2].y, c[0].y)
00257       ),
00258       Vector3<V>(
00259         det2(c[0].y, c[1].y, c[0].z, c[1].z), 
00260         det2(c[1].x, c[0].x, c[1].z, c[0].z), 
00261         det2(c[0].x, c[1].x, c[0].y, c[1].y)      
00262       )
00263     );
00264   
00265   }  
00266 
00267   /**
00268    * Calculate the inverse of this matrix.
00269    *
00270    * \return The inverse matrix
00271    */
00272   Matrix3x3<V> invert() const
00273   {
00274     return adjoint().transpose() / det();
00275   }
00276 };
00277 
00278 
00279 /**
00280  * Streaming operator that reads a Matrix3x3<V> from a stream.
00281  *
00282  * \param   stream     The stream from which is read.
00283  * \param   matrix3x3  The Matrix3x3<V> object.
00284  * \return  The stream.
00285  */ 
00286 template <class V> In& operator>>(In& stream, Matrix3x3<V>& matrix3x3);
00287 
00288 
00289 /**
00290  * Streaming operator that writes a Matrix3x3<V> to a stream.
00291  *
00292  * \param   stream      The stream to write on.
00293  * \param   matrix3x3   The Matrix3x3<V> object.
00294  * \return  The stream.
00295  */ 
00296 template <class V> Out& operator<<(Out& stream, const Matrix3x3<V>& matrix3x3);
00297 
00298 
00299 /**
00300  * Representation for 3x3 RotationMatrices
00301  */
00302 class RotationMatrix : public Matrix3x3<double> {
00303 public:
00304   /** 
00305    * Default constructor. 
00306    */
00307   RotationMatrix() {}
00308 
00309   /**
00310    * Constructor.
00311    *
00312    * \param  c0  the first column of the matrix.
00313    * \param  c1  the second column of the matrix.
00314    * \param  c2  the third column of the matrix.
00315    */
00316   RotationMatrix(
00317     const Vector3<double>& c0,
00318     const Vector3<double>& c1,
00319     const Vector3<double>& c2
00320   )
00321   : Matrix3x3<double>(c0,c1,c2) 
00322   {
00323   }
00324 
00325   /**
00326    * Assignment operator.
00327    * 
00328    * \param  other  The other matrix that is assigned to this one
00329    * \return        A reference to this object after the assignment.
00330    */
00331   RotationMatrix& operator=(const Matrix3x3<double>& other)
00332   {
00333     c[0] = other.c[0]; 
00334     c[1] = other.c[1]; 
00335     c[2] = other.c[2]; 
00336     return *this;
00337   }
00338 
00339   /**
00340    * Copy constructor.
00341    *
00342    * \param  other  The other matrix that is copied to this one
00343    */
00344   RotationMatrix(const Matrix3x3<double>& other)
00345   {
00346     *this = other;
00347   }
00348   
00349   /**
00350    * RotationMatrix from RPY-angles.
00351    *   Roll  rotates along z axis,
00352    *   Pitch rotates along y axis,  
00353    *   Yaw   rotates along x axis
00354    *
00355    *   R(roll,pitch,yaw) = R(z,roll)*R(y,pitch)*R(x,yaw)
00356    *
00357    * \see  "Robotik 1 Ausgabe Sommersemester 2001" by Prof. Dr. O. von Stryk
00358    * \attention  RPY-angles are not clearly defined!
00359    */
00360   RotationMatrix& fromKardanRPY(const double yaw, const double pitch, const double roll);
00361 
00362   /**
00363    * Invert the matrix.
00364    *
00365    * \note: Inverted rotation matrix is transposed matrix.
00366    */
00367   RotationMatrix invert()
00368   {
00369     return transpose();
00370   }
00371 
00372   /** 
00373    * Rotation around the x-axis.
00374    *
00375    * \param   angle  The angle this pose will be rotated by
00376    * \return  A reference to this object after the calculation.
00377    */
00378   RotationMatrix& rotateX(const double angle);
00379 
00380   /** 
00381    * Rotation around the y-axis.
00382    *
00383    * \param   angle  The angle this pose will be rotated by
00384    * \return  A reference to this object after the calculation.
00385    */
00386   RotationMatrix& rotateY(const double angle);
00387 
00388   /** 
00389    * Rotation around the z-axis.
00390    *
00391    * \param   angle  The angle this pose will be rotated by
00392    * \return  A reference to this object after the calculation.
00393    */
00394   RotationMatrix& rotateZ(const double angle);
00395 
00396   /**
00397    * Get the x-angle of a RotationMatrix.
00398    *
00399    * \return  The angle around the x-axis between the original
00400    *          and the rotated z-axis projected on the y-z-plane
00401    */
00402   double getXAngle() const;
00403 
00404   /**
00405    * Get the y-angle of a RotationMatrix.
00406    *
00407    * \return  The angle around the y-axis between the original
00408    *          and the rotated x-axis projected on the x-z-plane
00409    */
00410   double getYAngle() const;
00411 
00412   /**
00413    * Get the z-angle of a RotationMatrix.
00414    *
00415    * \return  The angle around the z-axis between the original
00416    *          and the rotated x-axis projected on the x-y-plane
00417    */
00418   double getZAngle() const;
00419 
00420   /**
00421    * Create and return a RotationMatrix, rotated around x-axis
00422    *
00423    * \param   angle 
00424    * \return  rotated RotationMatrix
00425    */
00426   static RotationMatrix getRotationX(const double angle)
00427   {
00428     return RotationMatrix().rotateX(angle);
00429   }
00430 
00431   /**
00432    * Create and return a RotationMatrix, rotated around y-axis
00433    *
00434    * \param   angle 
00435    * \return  rotated RotationMatrix
00436    */
00437   static RotationMatrix getRotationY(const double angle)
00438   {
00439     return RotationMatrix().rotateY(angle);
00440   }
00441 
00442   /**
00443    * Create and return a RotationMatrix, rotated around z-axis
00444    *
00445    * \param   angle 
00446    * \return  rotated RotationMatrix
00447    */
00448   static RotationMatrix getRotationZ(const double angle)
00449   {
00450     return RotationMatrix().rotateZ(angle);
00451   }
00452 };
00453 
00454 /**
00455  * Streaming operator that reads a RotationMatrix from a stream.
00456  *
00457  * \param  stream          The stream from which is read.
00458  * \param  rotationMatrix  The RotationMatrix object.
00459  * \return The stream.
00460  */ 
00461 In& operator>>(In& stream, RotationMatrix& rotationMatrix);
00462 
00463 /**
00464  * Streaming operator that writes a RotationMatrix to a stream.
00465  *
00466  * \param  stream          The stream to write on.
00467  * \param  rotationMatrix  The RotationMatrix object.
00468  * \return The stream.
00469  */ 
00470 Out& operator<<(Out& stream, const RotationMatrix& rotationMatrix);
00471 
00472 
00473 
00474 #endif // __Matrix_h__
00475 
00476 /*
00477 * Change log :
00478 * 
00479 * $Log: Matrix.h,v $
00480 * Revision 1.3  2004/09/09 10:15:56  spranger
00481 * fixed doxygen-errors
00482 *
00483 * Revision 1.2  2004/06/14 23:17:54  kindler
00484 * - corrected an error in *= operator (& was missing)
00485 * - added methods for calculating the adjoint and inverse
00486 * - added [] operator for direct element access
00487 * - fixed det() method (was unusable before due to syntax errors)
00488 * - converted to new-style doxygen comments
00489 *
00490 * Revision 1.1.1.1  2004/05/22 17:37:11  cvsadm
00491 * created new repository GT2004_WM
00492 *
00493 * Revision 1.2  2003/12/02 13:44:55  cesarz
00494 * added streaming operators
00495 *
00496 * Revision 1.1  2003/10/07 10:13:24  cvsadm
00497 * Created GT2004 (M.J.)
00498 *
00499 * Revision 1.1.1.1  2003/07/02 09:40:28  cvsadm
00500 * created new repository for the competitions in Padova from the 
00501 * tamara CVS (Tuesday 2:00 pm)
00502 *
00503 * removed unused solutions
00504 *
00505 * Revision 1.4  2002/11/19 17:38:31  dueffert
00506 * doxygen bugs corrected
00507 *
00508 * Revision 1.3  2002/11/19 15:43:04  dueffert
00509 * doxygen comments corrected
00510 *
00511 * Revision 1.2  2002/11/12 23:00:47  dueffert
00512 * started restore greenhills compatibility
00513 *
00514 * Revision 1.1  2002/09/22 13:10:50  risler
00515 * new Math headers added
00516 */

Generated on Thu Sep 23 19:57:39 2004 for GT2004 by doxygen 1.3.6