Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlCore/Matrix2.hpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #ifndef Matrix2_INCLUDE_ONCE
00033 #define Matrix2_INCLUDE_ONCE
00034 
00035 #include <vlCore/checks.hpp>
00036 #include <vlCore/Vector2.hpp>
00037 #include <cstring> // memcpy
00038 
00039 namespace vl
00040 {
00041   //-----------------------------------------------------------------------------
00042   // Matrix2
00043   //-----------------------------------------------------------------------------
00048   template<typename T_Scalar>
00049   class Matrix2
00050   {
00051   public:
00052     typedef T_Scalar scalar_type;
00053     //-----------------------------------------------------------------------------
00054     template<typename T>
00055     explicit Matrix2(const Matrix2<T>& m)
00056     {
00057       e(0,0) = (T_Scalar)m.e(0,0); e(1,0) = (T_Scalar)m.e(1,0);
00058       e(0,1) = (T_Scalar)m.e(0,1); e(1,1) = (T_Scalar)m.e(1,1);
00059     }
00060     //-----------------------------------------------------------------------------
00061     Matrix2()
00062     {
00063       setIdentity();
00064     }
00065     //-----------------------------------------------------------------------------
00066     explicit Matrix2(T_Scalar n)
00067     {
00068       setIdentity();
00069       e(0,0) = e(1,1) = n;
00070     }
00071     //-----------------------------------------------------------------------------
00072     explicit Matrix2(T_Scalar e00, T_Scalar e01,
00073                       T_Scalar e10, T_Scalar e11 )
00074     {
00075       e(0,0) = e00; e(0,1) = e01;
00076       e(1,0) = e10; e(1,1) = e11;
00077     }
00078     //-----------------------------------------------------------------------------
00079     Matrix2& fill(T_Scalar val)
00080     {
00081       e(0,0) = e(1,0) = 
00082       e(0,1) = e(1,1) = val;
00083       return *this;
00084     }
00085     //-----------------------------------------------------------------------------
00086     T_Scalar diff(const Matrix2& other) const
00087     {
00088       T_Scalar err = 0;
00089       for(int i=0; i<2; ++i)
00090         for(int j=0; j<2; ++j)
00091           if (e(j,i) > other.e(j,i)) // avoid fabs/abs
00092             err += e(j,i) - other.e(j,i);
00093           else
00094             err += other.e(j,i) - e(j,i);
00095       return err;
00096     }
00097     //-----------------------------------------------------------------------------
00098     bool operator==(const Matrix2& m) const 
00099     {
00100       return memcmp(m.mVec, mVec, sizeof(T_Scalar)*4) == 0;
00101     }
00102     //-----------------------------------------------------------------------------
00103     bool operator!=(const Matrix2& m) const 
00104     {
00105       return !operator==(m);
00106     }
00107     //-----------------------------------------------------------------------------
00108     Matrix2& operator=(const Matrix2& m) 
00109     {
00110       memcpy(mVec, m.mVec, sizeof(T_Scalar)*4);
00111       return *this;
00112     }
00113     //-----------------------------------------------------------------------------
00114     Matrix2 operator+(const Matrix2& m) const
00115     {
00116       Matrix2 t;
00117       for(int i=0; i<2; ++i)
00118         for(int j=0; j<2; ++j)
00119           t.e(j,i) = e(j,i) + m.e(j,i);
00120       return t;
00121     }
00122     //-----------------------------------------------------------------------------
00123     Matrix2& operator+=(const Matrix2& m)
00124     {
00125       for(int i=0; i<2; ++i)
00126         for(int j=0; j<2; ++j)
00127           e(j,i) += m.e(j,i);
00128       return *this;
00129     }
00130     //-----------------------------------------------------------------------------
00131     Matrix2 operator-(const Matrix2& m) const
00132     {
00133       Matrix2 t;
00134       for(int i=0; i<2; ++i)
00135         for(int j=0; j<2; ++j)
00136           t.e(j,i) = e(j,i) - m.e(j,i);
00137       return t;
00138     }
00139     //-----------------------------------------------------------------------------
00140     Matrix2& operator-=(const Matrix2& m)
00141     {
00142       for(int i=0; i<2; ++i)
00143         for(int j=0; j<2; ++j)
00144           e(j,i) -= m.e(j,i);
00145       return *this;
00146     }
00147     //-----------------------------------------------------------------------------
00148     Matrix2& operator*=(const Matrix2& m)
00149     {
00150       return postMultiply(m);
00151     }
00152     //-----------------------------------------------------------------------------
00153     Matrix2 operator-() const
00154     {
00155       Matrix2 t;
00156       for(int i=0; i<2; ++i)
00157         for(int j=0; j<2; ++j)
00158           t.e(j,i) = -e(j,i);
00159       return t;
00160     }
00161     //-----------------------------------------------------------------------------
00162     Matrix2 operator+(T_Scalar d) const
00163     {
00164       Matrix2 t;
00165       for(int i=0; i<2; ++i)
00166         for(int j=0; j<2; ++j)
00167           t.e(j,i) = e(j,i) + d;
00168       return t;
00169     }
00170     //-----------------------------------------------------------------------------
00171     Matrix2& operator+=(T_Scalar d)
00172     {
00173       for(int i=0; i<2; ++i)
00174         for(int j=0; j<2; ++j)
00175           e(j,i) += d;
00176       return *this;
00177     }
00178     //-----------------------------------------------------------------------------
00179     Matrix2 operator-(T_Scalar d) const
00180     {
00181       Matrix2 t;
00182       for(int i=0; i<2; ++i)
00183         for(int j=0; j<2; ++j)
00184           t.e(j,i) = e(j,i) - d;
00185       return t;
00186     }
00187     //-----------------------------------------------------------------------------
00188     Matrix2& operator-=(T_Scalar d)
00189     {
00190       for(int i=0; i<2; ++i)
00191         for(int j=0; j<2; ++j)
00192           e(j,i) -= d;
00193       return *this;
00194     }
00195     //-----------------------------------------------------------------------------
00196     Matrix2 operator*(T_Scalar d) const
00197     {
00198       Matrix2 t;
00199       for(int i=0; i<2; ++i)
00200         for(int j=0; j<2; ++j)
00201           t.e(j,i) = e(j,i) * d;
00202       return t;
00203     }
00204     //-----------------------------------------------------------------------------
00205     Matrix2& operator*=(T_Scalar d)
00206     {
00207       for(int i=0; i<2; ++i)
00208         for(int j=0; j<2; ++j)
00209           e(j,i) *= d;
00210       return *this;
00211     }
00212     //-----------------------------------------------------------------------------
00213     Matrix2 operator/(T_Scalar d) const
00214     {
00215       d = (T_Scalar)1 / d;
00216       Matrix2 t;
00217       for(int i=0; i<2; ++i)
00218         for(int j=0; j<2; ++j)
00219           t.e(j,i) = e(j,i) * d;
00220       return t;
00221     }
00222     //-----------------------------------------------------------------------------
00223     Matrix2& operator/=(T_Scalar d)
00224     {
00225       d = (T_Scalar)1 / d;
00226       for(int i=0; i<2; ++i)
00227         for(int j=0; j<2; ++j)
00228           e(j,i) *= d;
00229       return *this;
00230     }
00231     //-----------------------------------------------------------------------------
00232     bool isIdentity() const
00233     {
00234       Matrix2 i;
00235       return memcmp(ptr(), i.ptr(), sizeof(T_Scalar)*4) == 0;
00236     }
00237     //-----------------------------------------------------------------------------
00238     T_Scalar* ptr()
00239     {
00240       return &e(0,0);
00241     }
00242     //-----------------------------------------------------------------------------
00243     const T_Scalar* ptr() const
00244     {
00245       return &e(0,0);
00246     }
00247     //-----------------------------------------------------------------------------
00248     Matrix2& transpose()
00249     {
00250       T_Scalar tmp;
00251       for(int i=0; i<2; ++i)
00252         for(int j=i; j<2; ++j)
00253         {
00254           tmp = e(j,i);
00255           e(j,i) = e(i,j);
00256           e(i,j) = tmp;
00257         }
00258         return *this;
00259     }
00260     //-----------------------------------------------------------------------------
00261     Matrix2 getTransposed() const
00262     {
00263       Matrix2 m;
00264       for(int i=0; i<2; ++i)
00265         for(int j=0; j<2; ++j)
00266           m.e(j,i) = e(i,j);
00267       return m;
00268     }
00269     //-----------------------------------------------------------------------------
00270     Matrix2& getTransposed(Matrix2& dest) const
00271     {
00272       for(int i=0; i<2; ++i)
00273         for(int j=0; j<2; ++j)
00274           dest.e(j,i) = e(i,j);
00275       return dest;
00276     }
00277     //-----------------------------------------------------------------------------
00278     bool isNull() const
00279     {
00280       for(int i=0; i<2; ++i)
00281         for(int j=0; j<2; ++j)
00282           if(mVec[j][i] != 0)
00283             return false;
00284       return true;
00285     }
00286     //-----------------------------------------------------------------------------
00287     Matrix2& setNull() 
00288     {
00289       fill(0);
00290       return *this;
00291     }
00292     //-----------------------------------------------------------------------------
00293     static Matrix2& getNull(Matrix2& out)
00294     {
00295       out.fill(0);
00296       return out;
00297     }
00298     //-----------------------------------------------------------------------------
00299     static Matrix2 getNull()
00300     {
00301       return Matrix2().fill(0);
00302     }
00303     //-----------------------------------------------------------------------------
00304     Matrix2& setIdentity()
00305     {
00306       static const T_Scalar I2d[] = 
00307       { 
00308         (T_Scalar)1, (T_Scalar)0,
00309         (T_Scalar)0, (T_Scalar)1
00310       };
00311       memcpy(mVec, I2d, sizeof(T_Scalar)*4);
00312       return *this;
00313     }
00314     //-----------------------------------------------------------------------------
00315     static Matrix2 getIdentity()
00316     {
00317       return Matrix2();
00318     }
00319     //-----------------------------------------------------------------------------
00320     static Matrix2& getIdentity(Matrix2& out)
00321     {
00322       out.setIdentity();
00323       return out;
00324     }
00325     //-----------------------------------------------------------------------------
00326     T_Scalar getInverse(Matrix2& dest) const
00327     {
00328       if (&dest == this)
00329       {
00330         Matrix2 tmp;
00331         T_Scalar det = getInverse(tmp);
00332         dest = tmp;
00333         return det;
00334       }
00335       else
00336       {
00337         const T_Scalar& a11 = e(0,0); 
00338         const T_Scalar& a12 = e(1,0); 
00339         const T_Scalar& a21 = e(0,1); 
00340         const T_Scalar& a22 = e(1,1); 
00341 
00342         dest.fill(0);
00343 
00344         T_Scalar det = a11*a22-a12*a21;
00345 
00346         if (det != 0)
00347           dest = Matrix2(+a22, -a12, -a21, +a11) / det;
00348 
00349         return det;
00350       }
00351     }
00352     //-----------------------------------------------------------------------------
00353     Matrix2 getInverse(T_Scalar *determinant=NULL) const
00354     {
00355       Matrix2 tmp;
00356       T_Scalar det = getInverse(tmp);
00357       if (determinant)
00358         *determinant = det;
00359       return tmp;
00360     }
00361     //-----------------------------------------------------------------------------
00362     Matrix2& invert(T_Scalar *determinant=NULL)
00363     {
00364       T_Scalar det = getInverse(*this);
00365       if (determinant)
00366         *determinant = det;
00367       return *this;
00368     }
00369     //-----------------------------------------------------------------------------
00370     static Matrix2& multiply(Matrix2& out, const Matrix2& p, const Matrix2& q)
00371     {
00372       VL_CHECK(out.ptr() != p.ptr() && out.ptr() != q.ptr());
00373 
00374       out.e(0,0) = q.e(0,0)*p.e(0,0) + q.e(1,0)*p.e(0,1);
00375       out.e(0,1) = q.e(0,1)*p.e(0,0) + q.e(1,1)*p.e(0,1);
00376 
00377       out.e(1,0) = q.e(0,0)*p.e(1,0) + q.e(1,0)*p.e(1,1);
00378       out.e(1,1) = q.e(0,1)*p.e(1,0) + q.e(1,1)*p.e(1,1);
00379 
00380       return out;
00381     }
00382     //-----------------------------------------------------------------------------
00383     Matrix2& postMultiply(const Matrix2& m)
00384     {
00385       Matrix2<T_Scalar> t;
00386       return *this = multiply(t, *this, m);
00387     }
00388     //-----------------------------------------------------------------------------
00389     Matrix2& preMultiply(const Matrix2& m)
00390     {
00391       Matrix2<T_Scalar> t;
00392       return *this = multiply(t, m, *this);
00393     }
00394     //-----------------------------------------------------------------------------
00395 
00396     const T_Scalar& e(int i, int j) const { return mVec[j][i]; }
00397     T_Scalar& e(int i, int j) { return mVec[j][i]; }
00398 
00399   private:
00400     const Vector2<T_Scalar>& operator[](unsigned int i) const { VL_CHECK(i<2); return mVec[i]; }
00401     Vector2<T_Scalar>& operator[](unsigned int i) { VL_CHECK(i<2); return mVec[i]; }
00402 
00403   protected:
00404     Vector2<T_Scalar> mVec[2];
00405   };
00406 
00407   //-----------------------------------------------------------------------------
00408   // OPERATORS
00409   //-----------------------------------------------------------------------------
00410   template<typename T_Scalar>
00411   inline Matrix2<T_Scalar> operator*(const Matrix2<T_Scalar>& p, const Matrix2<T_Scalar>& q)
00412   {
00413     Matrix2<T_Scalar> t;
00414     Matrix2<T_Scalar>::multiply(t, p, q);
00415     return t;
00416   }
00417   //-----------------------------------------------------------------------------
00418   template<typename T_Scalar>
00419   inline Matrix2<T_Scalar> operator+(T_Scalar d, const Matrix2<T_Scalar>& m)
00420   {
00421     return m + d;
00422   }
00423   //-----------------------------------------------------------------------------
00424   template<typename T_Scalar>
00425   inline Matrix2<T_Scalar> operator*(T_Scalar d, const Matrix2<T_Scalar>& m)
00426   {
00427     return m * d;
00428   }
00429   //-----------------------------------------------------------------------------
00430   // post multiplication: matrix * column vector
00431   template<typename T_Scalar>
00432   inline Vector2<T_Scalar> operator*(const Matrix2<T_Scalar>& m, const Vector2<T_Scalar>& v)
00433   {
00434     Vector2<T_Scalar> t;
00435     t.x() = v.x()*m.e(0,0) + v.y()*m.e(0,1);
00436     t.y() = v.x()*m.e(1,0) + v.y()*m.e(1,1);
00437     return t;
00438   }
00439   //-----------------------------------------------------------------------------
00440   // pre-multiplication: row vector * matrix
00441   template<typename T_Scalar>
00442   inline Vector2<T_Scalar> operator*(const Vector2<T_Scalar>& v, const Matrix2<T_Scalar>& m)
00443   {
00444     Vector2<T_Scalar> t;
00445     t.x() = v.x()*m.e(0,0) + v.y()*m.e(1,0);
00446     t.y() = v.x()*m.e(0,1) + v.y()*m.e(1,1);
00447     return t;
00448   }
00449   //-----------------------------------------------------------------------------
00450 
00452   typedef Matrix2<double> dmat2;
00454   typedef Matrix2<float>  fmat2;
00456   typedef Matrix2<int>    imat2;
00458   typedef Matrix2<unsigned int>  umat2;
00459 
00460   #if VL_PIPELINE_PRECISION == 2
00461 
00462     typedef dmat2 mat2;
00463   #else
00464 
00465     typedef fmat2 mat2;
00466   #endif
00467 }
00468 
00469 #endif

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:29.
Permission is granted to use this page to write and publish articles regarding Visualization Library.