Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://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