00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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>
00038
00039 namespace vl
00040 {
00041
00042
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))
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
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
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
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