00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef mat2_h
00022 #define mat2_h
00023
00024 #include "mm.h"
00025
00026 namespace gutz {
00027
00028 template <class T>
00029 class vec2;
00030
00031 template <class T>
00032 class mat2 {
00033
00034 public:
00035
00036 inline mat2 ();
00037 inline mat2 (const T);
00038 inline mat2 (const T*);
00039 inline mat2 (const T, const T, const T, const T);
00040 inline mat2 (const vec2<T>&, const vec2<T>&);
00041 inline mat2 (const mat2<T>& M);
00042
00043 inline ~mat2 () {}
00044
00045
00046 inline mat2& operator+= (const mat2&);
00047 inline mat2& operator-= (const mat2&);
00048 inline mat2& operator*= (const T);
00049 inline mat2& operator/= (const T);
00050 inline mat2& operator*= (const mat2&);
00051
00052 inline mat2 operator+ (const mat2&) const;
00053 inline mat2 operator- (const mat2&) const;
00054 inline mat2 operator- () const;
00055 inline mat2 operator* (const T) const;
00056 inline mat2 operator/ (const T) const;
00057 inline mat2 operator* (const mat2&) const;
00058 inline vec2<T> operator* (const vec2<T>&) const;
00059
00060 inline T* v ();
00061 inline const T* v () const;
00062 inline void set (const T, const T, const T, const T);
00063 inline T& operator[] (const int);
00064
00065 inline void zero ();
00066 inline void eye ();
00067
00068 inline vec2<T>& x() const;
00069 inline vec2<T>& y() const;
00070
00071 inline mat2 inv () const;
00072 inline mat2 tp () const;
00073
00074 public:
00075 T m[4];
00076 };
00077
00078
00079
00080
00081 typedef mat2<uchar> mat2ub;
00082 typedef mat2<int> mat2i;
00083 typedef mat2<uint> mat2ui;
00084 typedef mat2<float> mat2f;
00085 typedef mat2<double> mat2d;
00086
00087
00088
00089
00090
00091 template <class T>
00092 inline
00093 mat2<T>
00094 operator* (const T, const mat2<T>&);
00095
00096
00097 template <class T>
00098 mat2<T>
00099 rot (const T);
00100
00101
00102 template <class T>
00103 mat2<T>
00104 diag (const vec2<T>&);
00105
00106 template <class T>
00107 std::ostream&
00108 operator<< (std::ostream& os, const mat2<T>& M)
00109 {
00110 os << M.m[0] << " " << M.m[2] << "\n"
00111 << M.m[1] << " " << M.m[3];
00112 return os;
00113 }
00114
00115 template <class T>
00116 std::istream&
00117 operator>> (std::istream& os, mat2<T>& M)
00118 {
00119 is >> M.m[0] >> M.m[2];
00120 is >> M.m[1] >> M.m[3];
00121 return is;
00122 }
00123
00124 template <class T>
00125 bool
00126 str2mat2 (const std::string& s, mat2<T>& v)
00127 {
00128 std::istringstream z(s);
00129 mat2<T> w;
00130 bool status = z.eof();
00131 for (int i=0; i<3; i++)
00132 {
00133 z >> w.m[i];
00134 status = status || z.fail() || z.eof();
00135 }
00136 z >> w.m[3];
00137 status = status || z.fail();
00138 if (!status) v = w.tp();
00139 return status;
00140 }
00141
00142 template <class T>
00143 bool
00144 str2mat2 (const std::string*, mat2<T>&);
00145
00146
00147
00148
00149
00150 template <class T>
00151 mat2<T>::mat2 ()
00152 {
00153 m[0] = 1; m[1] = 0;
00154 m[2] = 0; m[3] = 1;
00155 }
00156
00157 template <class T>
00158 mat2<T>::mat2 (const T c)
00159 {
00160 m[0] = c; m[1] = c;
00161 m[2] = c; m[3] = c;
00162 }
00163
00164 template <class T>
00165 mat2<T>::mat2 (const T* v)
00166 {
00167 m[0] = v[0]; m[1] = v[1];
00168 m[2] = v[2]; m[3] = v[3];
00169 }
00170
00171 template <class T>
00172 mat2<T>::mat2 (const T m0, const T m1,
00173 const T m2, const T m3)
00174 {
00175 m[0] = m0; m[1] = m1;
00176 m[2] = m2; m[3] = m3;
00177 }
00178
00179 template <class T>
00180 mat2<T>::mat2 (const vec2<T>& c0, const vec2<T>& c1)
00181 {
00182 m[0] = c0.x; m[1] = c0.y;
00183 m[2] = c1.x; m[3] = c1.y;
00184 }
00185
00186 template <class T>
00187 mat2<T>::mat2 (const mat2<T>& M)
00188 {
00189 m[0] = M.m[0];
00190 m[1] = M.m[1];
00191 m[2] = M.m[2];
00192 m[3] = M.m[3];
00193 }
00194
00195
00196 template <class T>
00197 mat2<T>&
00198 mat2<T>::operator+= (const mat2<T>& M)
00199 {
00200 m[0] += M.m[0]; m[1] += M.m[1];
00201 m[2] += M.m[2]; m[3] += M.m[3];
00202 return *this;
00203 }
00204
00205 template <class T>
00206 mat2<T>&
00207 mat2<T>::operator-= (const mat2<T>& M)
00208 {
00209 m[0] -= M.m[0]; m[1] -= M.m[1];
00210 m[2] -= M.m[2]; m[3] -= M.m[3];
00211 return *this;
00212 }
00213
00214 template <class T>
00215 mat2<T>&
00216 mat2<T>::operator*= (T c)
00217 {
00218 m[0] *= c; m[1] *= c;
00219 m[2] *= c; m[3] *= c;
00220 return *this;
00221 }
00222
00223 template <class T>
00224 mat2<T>&
00225 mat2<T>::operator/= (T c)
00226 {
00227 T d = 1/c;
00228 m[0] *= d; m[1] *= d;
00229 m[2] *= d; m[3] *= d;
00230 return *this;
00231 }
00232
00233 template <class T>
00234 mat2<T>&
00235 mat2<T>::operator*= (const mat2& M)
00236 {
00237 mat2<T> temp(*this);
00238 m[0] = temp.m[0]*M.m[0] + temp.m[2]*M.m[1];
00239 m[1] = temp.m[1]*M.m[0] + temp.m[3]*M.m[1];
00240 m[2] = temp.m[0]*M.m[2] + temp.m[2]*M.m[3];
00241 m[3] = temp.m[1]*M.m[2] + temp.m[3]*M.m[3];
00242 return *this;
00243 }
00244
00245 template <class T>
00246 mat2<T>
00247 mat2<T>::operator+ (const mat2& M) const
00248 {
00249 return mat2(m[0] + M.m[0], m[1] + M.m[1],
00250 m[2] + M.m[2], m[3] + M.m[3]);
00251 }
00252
00253 template <class T>
00254 mat2<T>
00255 mat2<T>::operator- (const mat2& M) const
00256 {
00257 return mat2(m[0] - M.m[0], m[1] - M.m[1],
00258 m[2] - M.m[2], m[3] - M.m[3]);
00259 }
00260
00261 template <class T>
00262 mat2<T>
00263 mat2<T>::operator- () const
00264 {
00265 return mat2(-m[0], -m[2],
00266 -m[1], -m[3]);
00267 }
00268
00269 template <class T>
00270 mat2<T>
00271 mat2<T>::operator* (T c) const
00272 {
00273 return mat2(m[0]*c, m[2]*c,
00274 m[1]*c, m[3]*c);
00275 }
00276
00277 template <class T>
00278 mat2<T>
00279 mat2<T>::operator/ (T c) const
00280 {
00281 T d = 1/c;
00282 return mat2(m[0]*d, m[1]*d,
00283 m[2]*d, m[3]*d);
00284 }
00285
00286 template <class T>
00287 mat2<T>
00288 mat2<T>::operator* (const mat2& M) const
00289 {
00290 return mat2(m[0]*M.m[0] + m[2]*M.m[1], m[1]*M.m[0] + m[3]*M.m[1],
00291 m[0]*M.m[2] + m[2]*M.m[3], m[1]*M.m[2] + m[3]*M.m[3]);
00292 }
00293
00294 template <class T>
00295 vec2<T>
00296 mat2<T>::operator* (const vec2<T>& v) const
00297 {
00298 return vec2<T>(m[0]*v.x + m[2]*v.y, m[1]*v.x + m[3]*v.y);
00299 }
00300
00301 template <class T>
00302 T*
00303 mat2<T>::v ()
00304 {
00305 return m;
00306 }
00307
00308 template <class T>
00309 const T*
00310 mat2<T>::v () const
00311 {
00312 return m;
00313 }
00314
00315
00316 template <class T>
00317 void
00318 mat2<T>::set (const T m0, const T m1,
00319 const T m2, const T m3)
00320 {
00321 m[0] = m0; m[1] = m1;
00322 m[2] = m2; m[3] = m3;
00323 }
00324
00325 template <class T>
00326 T&
00327 mat2<T>::operator[] (const int i)
00328 {
00329 return v()[i];
00330 }
00331
00332 template <class T>
00333 void
00334 mat2<T>::zero ()
00335 {
00336 m[0] = 0; m[1] = 0;
00337 m[2] = 0; m[3] = 0;
00338 }
00339
00340 template <class T>
00341 void
00342 mat2<T>::eye ()
00343 {
00344 m[0] = 1; m[1] = 0;
00345 m[2] = 0; m[3] = 1;
00346 }
00347
00348 template <class T>
00349 vec2<T>&
00350 mat2<T>::x () const
00351 {
00352 return (vec2<T>&)m[0];
00353 }
00354
00355 template <class T>
00356 vec2<T>&
00357 mat2<T>::y () const
00358 {
00359 return (vec2<T>&)m[2];
00360 }
00361
00362 template <class T>
00363 mat2<T>
00364 mat2<T>::inv () const
00365 {
00366 T d = 1 / (m[0]*m[3] - m[2]*m[1]);
00367 return mat2(m[3]*d, -m[2]*d,
00368 -m[1]*d, m[0]*d);
00369 }
00370
00371 template <class T>
00372 mat2<T>
00373 mat2<T>::tp () const
00374 {
00375 return mat2(m[0], m[2],
00376 m[1], m[3]);
00377 }
00378
00379 template <class T>
00380 mat2<T>
00381 operator* (const T c, const mat2<T>& M)
00382 {
00383 return mat2<T> (M.m[0]*c, M.m[1]*c,
00384 M.m[2]*c, M.m[3]*c);
00385 }
00386
00387 template <class T>
00388 mat2<T>
00389 rot (const T angle)
00390 {
00391 T ca = cos(angle);
00392 T sa = sin(angle);
00393 return mat2<T>(ca, sa,
00394 -sa, ca);
00395 }
00396
00397 template <class T>
00398 mat2<T>
00399 diag (const vec2<T>& v)
00400 {
00401 return mat2<T>(v.x, 0,
00402 0, v.y);
00403 }
00404
00405 template <class T>
00406 bool
00407 str2mat2 (const std::string* s, mat2<T>& M)
00408 {
00409 if (!s) return true;
00410 return str2mat2(*s, M);
00411 }
00412
00413
00414
00415 typedef mat2<float> mat2f;
00416 typedef mat2<double> mat2d;
00417
00418 #if __win32
00419 inline
00420 mat2d
00421 mm_castf2d (mat2f M)
00422 {
00423 return mat2d(M.m[0], M.m[1],
00424 M.m[2], M.m[3]);
00425 }
00426
00427 inline
00428 mat2f
00429 mm_castd2f (mat2d M)
00430 {
00431 return mat2f((float)M.m[0], (float)M.m[1],
00432 (float)M.m[2], (float)M.m[3]);
00433 }
00434 #else //__real_os
00435 template <class T1, class T2>
00436 mat2<T2>
00437 mm_cast (mat2<T1> v)
00438 {
00439 return mat2<T2>(M.m[0], M.m[1],
00440 M.m[2], M.m[3]);
00441 }
00442 #endif
00443
00444 }
00445
00446 #endif // mat2_h