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

mat4.H

Go to the documentation of this file.
00001 #ifndef MAT4_H_IS_INCLUDED
00002 #define MAT4_H_IS_INCLUDED
00003 
00004 /*! \file Mat4.H
00005  *  \brief Contains the declaration of the Mat4 class, a 4x4 matrix class.
00006  *  \ingroup group_MLIB
00007  *
00008  */
00009  
00010 #include "mlib/vec4.H"
00011 #include "mlib/point3.H"
00012 #include "mlib/line.H"
00013 
00014 namespace mlib {
00015 
00016 /*! \brief A 4x4 matrix class with double precision floating point elements.
00017  *  \ingroup gourp_MLIB
00018  *
00019  *  Mat4 is a 4x4 matrix class that can be used to perform general affine
00020  *  or projective transformations in 3D space.
00021  *
00022  *  To transform a point or a vector, PREmultiply it by a Mat4 instance.
00023  *
00024  *  \libgfx Mat4 uses some code from the Mat4 class in libgfx.
00025  *
00026  *  \todo Add eigenvector and eigenvalue finding functions.
00027  *
00028  */
00029 template <typename M, typename P, typename V, typename L, typename Q>
00030 class Mat4 {
00031    
00032    protected:
00033    
00034       Vec4 row[4];            //!< Rows of the matrix stored as 4D vectors.
00035       bool perspective;       //!< Is this matrix a perspective transform?
00036 
00037    public:
00038    
00039       //! \name Constructors
00040       //@{
00041 
00042       //! \brief Default constructor.  Creates an identity matrix.
00043       inline Mat4()
00044          : perspective(false)
00045       {
00046          row[0] = row[1] = row[2] = row[3] = Vec4(0.0, 0.0, 0.0, 0.0);
00047          row[0][0] = row[1][1] = row[2][2] = row[3][3] = 1.0;
00048       }
00049       
00050       //! \brief Constructor that creates a matrix with rows equal to the
00051       //! vectors givens as arguments.  Perspective can also be set.
00052       inline Mat4(Vec4 row0, Vec4 row1, Vec4 row2, Vec4 row3, bool perspec = false)
00053          : perspective(perspec)
00054       { row[0] = row0; row[1] = row1; row[2] = row2; row[3] = row3; }
00055    
00056       //! \brief  This constructor creates a rigid motion transform from an
00057       //! origin and directions of x, y and z axes.
00058       Mat4(const P &origin, const V &x_dir, const V &y_dir, const V &z_dir);
00059    
00060       //! \brief This constructor creates a linear map (no translation)
00061       //! whose columns are the given vectors.
00062       Mat4(const V &col0, const V &col1, const V &col2);
00063    
00064       //! \brief This constructor creates a rigid motion transform from an
00065       //! origin and direction of x and y axis. If yDir is not perpendicular to
00066       //! xDir, yDir will be adjusted.
00067       Mat4(const P &origin, const V &xDir, const V &yDir);
00068    
00069       //! \brief This constructor creates a rigid motion transform from an
00070       //! origin (axis.point) and the direction of the z axis (axis.vector). The
00071       //! directions of the x and y axes are determined according to an 
00072       //! arbitrary axis algorithm.
00073       Mat4(const L& axis);
00074    
00075       //! \brief The constructor creates a rigid motion transform from an origin.
00076       //! The x, y and z axis are aligned with the world x, y and z axis.
00077       Mat4(const P& origin);
00078       
00079       //@}
00080       
00081       //! \name Element Access Functions
00082       //! Functions that allow you to get or set the elements of the matrix in
00083       //! various different ways.
00084       //@{
00085    
00086       //! \brief Returns a reference to the cell (i1, i2) in the matrix.
00087       //! No bounds checking is performed in this function.
00088       double& operator ()(int i1, int i2)       { return row[i1][i2]; }
00089       //! \brief Returns the value in the cell (i1, i2) in the matrix.
00090       //! No bounds checking is performed in this function.
00091       double  operator ()(int i1, int i2) const { return row[i1][i2]; }
00092       
00093       //! \brief Returns a reference to row \p i as a Vec4.  No bounds checking
00094       //! is performed in this function.
00095       Vec4&   operator [](int i)                { return row[i]; }
00096       //! \brief Returns the value of row \p i as a Vec4.  No bounds checking
00097       //! is performed in this function.
00098       Vec4    operator [](int i) const          { return row[i]; }
00099    
00100       //! Returns a vector containing the lengths of the axes of the coordinate
00101       //! system defined by the matrix.
00102       V    get_scale() const
00103          { return V(X().length(),Y().length(),Z().length()); }
00104       
00105       //! Returns by reference the origin and axes of the coordinate system
00106       //! defined by the matrix.
00107       void get_coord_system(P& o, V& x, V& y, V& z) const
00108          { x = X(); y = Y(); z = Z(); o = origin(); }
00109    
00110       //! \brief Returns the x-axis of the coordinate system defined by the
00111       //! matrix as a vector.
00112       V    X()      const  { return V(row[0][0], row[1][0], row[2][0]); }
00113       //! \brief Returns the y-axis of the coordinate system defined by the
00114       //! matrix as a vector.
00115       V    Y()      const  { return V(row[0][1], row[1][1], row[2][1]); }
00116       //! \brief Returns the z-axis of the coordinate system defined by the
00117       //! matrix as a vector.
00118       V    Z()      const  { return V(row[0][2], row[1][2], row[2][2]); }
00119       //! \brief Returns the origin of the coordinate system defined by the
00120       //! matrix as a point.
00121       P    origin() const  { return P(row[0][3], row[1][3], row[2][3]); }
00122       
00123       
00124       //! \brief Returns the elements of the matrix as a 1D array (in row major
00125       //! layout).
00126       //! \libgfx This function is borrowed from the libgfx Mat4 class.
00127       const double  *matrix() const  { return row[0]; }
00128    
00129       //! \brief Set the x-axis of the coordinate system defined by the matrix.
00130       void set_X(const V& x)
00131          { row[0][0] = x[0]; row[1][0] = x[1]; row[2][0] = x[2]; }
00132       //! \brief Set the y-axis of the coordinate system defined by the matrix.
00133       void set_Y(const V& y)
00134          { row[0][1] = y[0]; row[1][1] = y[1]; row[2][1] = y[2]; }
00135       //! \brief Set the z-axis of the coordinate system defined by the matrix.
00136       void set_Z(const V& z)
00137          { row[0][2] = z[0]; row[1][2] = z[1]; row[2][2] = z[2]; }
00138       //! \brief Set the origin of the coordinate system defined by the matrix.
00139       void set_origin(const P& o)
00140          { row[0][3] = o[0]; row[1][3] = o[1]; row[2][3] = o[2]; }
00141    
00142       //! \brief Returns the rotation part of the transform.
00143       M    rotation() const { return M(P(0,0,0), X(), Y(), Z()); }
00144       
00145       //@}
00146        
00147       //! \name Special Transform Constructors
00148       //! Static functions to create matrices that perform special
00149       //! transformations.
00150       //@{
00151          
00152       //! \brief Create a matrix that does the rotation described by the
00153       //! quaternion \a quat.
00154       static M rotation   (const  Q& quat);
00155       //! \brief Create a matrix that rotates \a angle radians about the axis
00156       //! described by line \a axis.
00157       static M rotation   (const  L& axis,    double   angle);
00158       //! \brief Create a matrix that rotates \a angle radians about the axis
00159       //! described by vector \a axis.
00160       static M rotation   (const  V& axis,    double   angle);
00161       
00162       //! \brief Create a matrix that performs a shearing transform.
00163       static M shear      (const  V& normal,  const V& shear_vec);
00164       
00165       //! \brief Create a matrix that does a uniform scale by \a factor along
00166       //! the x-, y- and z-directions, centered at the point fixed_pt.
00167       static M scaling    (const  P& fixed_pt, double   factor);
00168       //! \brief Create a matrix that scales along x-, y- and z-axes by the
00169       //! amount in the corresponding component of \a xyz_factors and that
00170       //! leaves the point fixed_pt unmoved.
00171       static M scaling    (const  P& fixed_pt, const V& xyz_factors);
00172       //! \brief Create a matrix that scales along the x-, y- and z-axes by the
00173       //! amount in the corresponding component of \a xyz_factors.
00174       static M scaling    (const  V& xyz_factors);
00175       //! \brief Create a matrix that scales by \a x along the x-axis, \a y
00176       //! along the y-axis and \a z along the z-axis.
00177       static M scaling    (double x, double y, double z)
00178          { return scaling(V(x,y,z)); }
00179       //! \brief Create a matrix that does a uniform scale by \a factor.
00180       static M scaling    (double    factor);
00181       
00182       //! \brief Create a matrix that scales along the direction of \a axis.vector
00183       //! leaving point \a axis.point unmoved.
00184       static M stretching (const  L& axis);
00185       
00186       //! \brief Create a matrix that does a translation along the vector \a vec.
00187       static M translation(const  V& vec);
00188    
00189       //! \brief Contruct a rotation / non-uniform scale matrix that maps the
00190       //! line segment joining \a anchor and \a old_pt to the segment joining
00191       //! \a anchor and \a new-pt.
00192       static M anchor_scale_rot(const P& anchor,
00193                                 const P& old_pt,
00194                                 const P& new_pt);
00195    
00196       //! \brief Map a triple of points (src1,src2,src3) to a triple of points 
00197       //! (dst1,dst2,dst3).  Point src1 maps to dst1, line (src1,src2) maps to
00198       //! line (dst1,dst2) and plane (src1,src2,src3) maps to plane
00199       //! (dst1,dst2,dst3).
00200       static M align(const P& src1, const P& src2, const P& src3,
00201                      const P& dst1, const P& dst2, const P& dst3);
00202       
00203       static M align(const P&  src1, const V& src2, const V& src3,
00204                      const P&  dst1, const V& dst2, const V& dst3);
00205    
00206       static M align(const P&  src1, const V&    src2,
00207                      const P&  dst1, const V&    dst2);
00208    
00209       static M align_and_scale(const P& o, const V& x, const V& y, const V& z);
00210       
00211       //! \brief Creates a matrix that performs a perspective transformation
00212       //! exactly like gluPerspective.
00213       static M glu_perspective(double fovy, double aspect,
00214              double zmin=0.0, double zmax=0.0);
00215 
00216       //! \brief Creates a matrix that performs a transformation exactly like
00217       //! gluLookAt.
00218       static M glu_lookat(const V& from, const V& at, const V& up);
00219 
00220       //! \brief Creates a matrix that performs the OpenGL viewport
00221       //! transformation.
00222       static M gl_viewport(double w, double h);
00223       
00224       //@}
00225       
00226       //! \name Matrix Operations
00227       //@{
00228    
00229       //! \brief Return the transpose of the matrix.
00230       M        transpose       ()                    const;
00231       //! \brief Return the determinant of the matrix.
00232       //! \libgfx This function was take directly from libgfx (it was only
00233       //! modified to make it into a member function).
00234       double   det             ()                    const
00235          { return row[0] * -cross(row[1], row[2], row[3]); }
00236       //! \brief Return the trace of the matrix.
00237       //! \libgfx This function was take directly from libgfx (it was only
00238       //! modified to make it into a member function).
00239       double   trace           ()                    const
00240          { return (*this)(0,0)+(*this)(1,1)+(*this)(2,2)+(*this)(3,3); }
00241       //! \brief Return the adjoint of the matrix.
00242       M        adjoint         ()                    const;
00243       //! \brief Return a copy of the matrix with the axes of the coordinate
00244       //! system it defines normalized.
00245       M        unscaled        ()                    const;
00246       //! \brief Returns a normalized basis version of the matrix.
00247       M        normalized_basis()                    const;
00248       //! \brief Returns a orthogonalized version of the matrix.
00249       M        orthogonalized  ()                    const;
00250       //! \brief Returns the inverse of the matrix.
00251       //         If debug is true, warns of near-zero determinant.
00252       M        inverse(bool debug = false) const;
00253       double   inverse(Mat4<M,P,V,L,Q> &inv) const;
00254       //! \brief Returns the derivative of the matrix at point \a p.
00255       M        derivative(const P& p)                const;
00256       
00257       //@}
00258       
00259       //! \name Matrix Property Queries
00260       //! Functions that check various properties of the matrix.
00261       //@{
00262          
00263       //! \brief Set whether this matrix represents a perspective transform or
00264       //! not.
00265       void set_perspective(bool p)  { perspective = p;   }
00266       //! \brief Does this matrix represent a perspective transform?
00267       bool is_perspective()  const  { return perspective;}
00268    
00269       //! \brief Is the matrix valid?
00270       bool     is_valid                   () const;
00271       //! \brief Is the matrix equal to the identity matrix?
00272       bool     is_identity                () const;
00273       //! \brief Is the matrix orthogonal (no shearing)?
00274       bool     is_orthogonal              () const;
00275       //! \brief Is the matrix equal_scaling orthogonal (no shearing, no
00276       //! nonequal scaling)?
00277       bool     is_equal_scaling_orthogonal() const;
00278       //! \brief Is the matrix orthonormal (orthogonal, no scaling)?
00279       bool     is_orthonormal() const
00280          { return (is_orthogonal() && get_scale().is_equal(V(1,1,1))); }
00281         
00282       //@}
00283       
00284       //! \name Overloaded Operators
00285       //! Overloaded mathematical and logical operators.
00286       //@{
00287    
00288       //! \brief Overloaded equality operator.  Only checks to see if top 3 rows
00289       //! are equal.
00290       int operator == (const M &m) const
00291          { return origin() == m.origin() && 
00292                   X() == m.X() && Y() == m.Y() && Z() == m.Z(); }
00293       
00294       //@}
00295 
00296 }; // class Mat4
00297 
00298 } // namespace mlib
00299 
00300 namespace mlib {
00301 
00302 //! \brief Mat4 by Mat4 multiplication.
00303 //! \relates Mat4
00304 template <typename M, typename P, typename V, typename L, typename Q>
00305 M operator*(const Mat4<M,P,V,L,Q> &m, const Mat4<M,P,V,L,Q> &m2);
00306 
00307 //! \brief Mat4 by 3D point multiplication.
00308 //! \relates Mat4
00309 template <typename M, typename P, typename V, typename L, typename Q>
00310 P operator*(const Mat4<M,P,V,L,Q> &m, const P &p);
00311 
00312 //! \brief Mat4 by 3D vector multiplication.
00313 //! \relates Mat4
00314 template <typename M, typename P, typename V, typename L, typename Q>
00315 V operator*(const Mat4<M,P,V,L,Q> &m, const Vec3<V> &v);
00316 
00317 //! \brief Mat4 by 3D line multiplication.
00318 //! \relates Mat4
00319 template <typename M, typename P, typename V, typename L, typename Q>
00320 L operator*(const Mat4<M,P,V,L,Q> &m, const Line<L,P,V> &l);
00321 
00322 //! \brief Component wise matrix addition.
00323 //! \relates Mat4
00324 template <typename M, typename P, typename V, typename L, typename Q>
00325 inline M operator+(const Mat4<M,P,V,L,Q>& n, const Mat4<M,P,V,L,Q>& m)
00326    { return M(n[0]+m[0], n[1]+m[1], n[2]+m[2], n[3]+m[3],
00327               n.is_perspective() || m.is_perspective()); }
00328 
00329 //! \brief Component wise matrix subtraction.
00330 //! \relates Mat4
00331 template <typename M, typename P, typename V, typename L, typename Q>
00332 inline M operator-(const Mat4<M,P,V,L,Q>& n, const Mat4<M,P,V,L,Q>& m)
00333    { return M(n[0]-m[0], n[1]-m[1], n[2]-m[2], n[3]-m[3],
00334               n.is_perspective() || m.is_perspective()); }
00335 
00336 //! \brief Component wise matrix negation.
00337 //! \relates Mat4
00338 template <typename M, typename P, typename V, typename L, typename Q>
00339 inline M operator-(const Mat4<M,P,V,L,Q>& n)
00340    { return M(-n[0], -n[1], -n[2], -n[3], n.is_perspective()); }
00341 
00342 //! \brief Scalar by matrix multiplication.
00343 //! \relates Mat4
00344 template <typename M, typename P, typename V, typename L, typename Q>
00345 inline M operator*(double s, const Mat4<M,P,V,L,Q>& m)
00346    { return M(m[0]*s, m[1]*s, m[2]*s, m[3]*s, m.is_perspective()); }
00347 
00348 //! \brief Matrix by scalar multiplication.
00349 //! \relates Mat4
00350 template <typename M, typename P, typename V, typename L, typename Q>
00351 inline M operator*(const Mat4<M,P,V,L,Q>& m, double s)
00352    { return s*m; }
00353 
00354 //! \brief Matrix by scalara division.
00355 //! \relates Mat4
00356 template <typename M, typename P, typename V, typename L, typename Q>
00357 inline M operator/(const Mat4<M,P,V,L,Q>& m, double s)
00358    { return M(m[0]/s, m[1]/s, m[2]/s, m[3]/s, m.is_perspective()); }
00359 
00360 //! \brief Stream insertion operator for Mat4 class.
00361 //! \relates Mat4
00362 template <typename M,typename P,typename V, typename L, typename Q>
00363 std::ostream &operator <<(std::ostream &os, const Mat4<M,P,V,L,Q> &x);
00364 
00365 } // namespace mlib
00366 
00367 #ifdef JOT_NEEDS_TEMPLATES_IN_H_FILE
00368 #include "mat4.C"
00369 #endif
00370 
00371 #endif // MAT4_H_IS_INCLUDED

Generated on Mon Sep 18 11:39:32 2006 for jot by  doxygen 1.4.4