00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #pragma once
00025
00026 #include "cinder/Cinder.h"
00027 #include "cinder/CinderMath.h"
00028 #include "cinder/Vector.h"
00029
00030 #include <iomanip>
00031
00032 namespace cinder {
00033
00035
00037 template<typename T>
00038 class MatrixAffine2
00039 {
00040 public:
00041 typedef T TYPE;
00042 typedef T value_type;
00043
00044 static const size_t MEM_LEN = sizeof(T)*6;
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 union {
00061 T m[6];
00062 struct {
00063
00064
00065
00066 T m00, m10;
00067 T m01, m11;
00068 T m02, m12;
00069 };
00070
00071 T mcols[3][2];
00072 };
00073
00074 MatrixAffine2();
00075 MatrixAffine2( T s );
00076 MatrixAffine2( const T *dt );
00077
00078 MatrixAffine2( T d0, T d1, T d2, T d3, T d4, T d5 );
00079
00080 MatrixAffine2( const Vec2<T> &vx, const Vec2<T> &vy, const Vec2<T> &vz );
00081
00082 template<typename FromT>
00083 MatrixAffine2( const MatrixAffine2<FromT> &src );
00084 MatrixAffine2( const MatrixAffine2<T> &src );
00085
00086 MatrixAffine2<T>& operator=( const MatrixAffine2<T>& rhs );
00087 MatrixAffine2<T>& operator=( T rhs );
00088
00089 template<typename FromT>
00090 MatrixAffine2<T>& operator=( const MatrixAffine2<FromT> &rhs );
00091
00092 bool equalCompare( const MatrixAffine2<T>& rhs, T epsilon ) const;
00093 bool operator==( const MatrixAffine2<T> &rhs ) const { return equalCompare( rhs, (T)EPSILON ); }
00094 bool operator!=( const MatrixAffine2<T> &rhs ) const { return ! ( *this == rhs ); }
00095
00096 MatrixAffine2<T>& operator*=( const MatrixAffine2<T> &rhs );
00097 MatrixAffine2<T>& operator+=( const MatrixAffine2<T> &rhs );
00098 MatrixAffine2<T>& operator-=( const MatrixAffine2<T> &rhs );
00099
00100 MatrixAffine2<T>& operator*=( T s );
00101 MatrixAffine2<T>& operator/=( T s );
00102 MatrixAffine2<T>& operator+=( T s );
00103 MatrixAffine2<T>& operator-=( T s );
00104
00105 const MatrixAffine2<T> operator*( const MatrixAffine2<T> &rhs ) const;
00106 const MatrixAffine2<T> operator+( const MatrixAffine2<T> &rhs ) const;
00107 const MatrixAffine2<T> operator-( const MatrixAffine2<T> &rhs ) const;
00108
00110 Vec2<T> transformPoint( const Vec2<T> &rhs ) const;
00112 const Vec2<T> operator*( const Vec2<T> &rhs ) const;
00114 Vec2<T> transformVec( const Vec2<T> &v ) const;
00115
00116 const MatrixAffine2<T> operator*( T rhs ) const;
00117 const MatrixAffine2<T> operator/( T rhs ) const;
00118 const MatrixAffine2<T> operator+( T rhs ) const;
00119 const MatrixAffine2<T> operator-( T rhs ) const;
00120
00121
00122 T& at( int row, int col );
00123 const T& at( int row, int col ) const;
00124
00125 T& operator[]( int idx ) { return m[idx]; }
00126 const T& operator[]( int idx ) const { return m[idx]; }
00127
00128
00129 void set( const T *dt );
00130
00131 void set( T d0, T d1, T d2, T d3, T d4, T d5 );
00132
00133 Vec2<T> getColumn( int col ) const;
00134 void setColumn( int col, const Vec2<T> &v );
00135
00136 Vec3<T> getRow( int row ) const;
00137 void setRow( int row, const Vec3<T> &v );
00138
00139 void getColumns( Vec2<T> *c0, Vec2<T> *c1, Vec2<T> *c2 ) const;
00140 void setColumns( const Vec2<T> &c0, const Vec2<T> &c1, const Vec2<T> &c2 );
00141
00142 void getRows( Vec3<T> *r0, Vec3<T> *r1, Vec3<T> *r2 ) const;
00143 void setRows( const Vec3<T> &r0, const Vec3<T> &r1, const Vec3<T> &r2 );
00144
00146 void setToNull();
00148 void setToIdentity();
00149
00151 bool isSingular() const;
00152
00154 void invert(T epsilon = EPSILON ) { *this = invertCopy( epsilon ); }
00156 MatrixAffine2<T> invertCopy( T epsilon = EPSILON ) const;
00157
00159 void translate( const Vec2<T> &v );
00161 MatrixAffine2 translateCopy( const Vec2<T> &v ) const { MatrixAffine2 result = *this; result.translate( v ); return result; }
00162
00164 void rotate( T radians ) { *this *= MatrixAffine2<T>::makeRotate( radians ); }
00166 void rotate( T radians, const Vec2<T> &pt ) { *this *= MatrixAffine2<T>::makeRotate( radians, pt ); }
00168 MatrixAffine2 rotateCopy( const Vec2<T> &v ) const { MatrixAffine2 result = *this; result.rotate( v ); return result; }
00170 MatrixAffine2 rotateCopy( const Vec2<T> &v, const Vec2<T> &pt ) const { MatrixAffine2 result = *this; result.rotate( v, pt ); return result; }
00171
00173 void scale( T s );
00175 void scale( const Vec2<T> &v );
00177 MatrixAffine2 scaleCopy( T s ) const { MatrixAffine2 result = *this; result.scale( s ); return result; }
00179 MatrixAffine2 scaleCopy( const Vec2<T> &v ) const { MatrixAffine2 result = *this; result.scale( v ); return result; }
00180
00181
00182 static MatrixAffine2<T> identity() { return MatrixAffine2( 1, 0, 0, 1, 0, 0 ); }
00183
00184 static MatrixAffine2<T> one() { return MatrixAffine2( (T)1 ); }
00185
00186 static MatrixAffine2<T> zero() { return MatrixAffine2( (T)0 ); }
00187
00188
00189 static MatrixAffine2<T> makeTranslate( const Vec2<T> &v );
00190
00191
00192 static MatrixAffine2<T> makeRotate( T radians );
00193
00194 static MatrixAffine2<T> makeRotate( T radians, const Vec2<T> &pt );
00195
00196
00197 static MatrixAffine2<T> makeScale( T s );
00198 static MatrixAffine2<T> makeScale( const Vec2<T> &v );
00199
00200 static MatrixAffine2<T> makeSkewX( T radians );
00201 static MatrixAffine2<T> makeSkewY( T radians );
00202
00203 friend std::ostream& operator<<( std::ostream &lhs, const MatrixAffine2<T> &rhs )
00204 {
00205 for( int i = 0; i < 2; i++) {
00206 lhs << " |";
00207 for( int j = 0; j < 3; j++) {
00208 lhs << std::setw( 12 ) << std::setprecision( 5 ) << rhs.m[j*2+i];
00209 }
00210 lhs << "|" << std::endl;
00211 }
00212
00213 return lhs;
00214 }
00215 };
00216
00217 template<typename T>
00218 MatrixAffine2<T>::MatrixAffine2()
00219 {
00220 setToIdentity();
00221 }
00222
00223 template<typename T>
00224 MatrixAffine2<T>::MatrixAffine2( T s )
00225 {
00226 for( int i = 0; i < 6; ++i )
00227 m[i] = s;
00228 }
00229
00230 template<typename T>
00231 MatrixAffine2<T>::MatrixAffine2( const T *dt )
00232 {
00233 set( dt );
00234 }
00235
00236 template<typename T>
00237 MatrixAffine2<T>::MatrixAffine2( T d0, T d1, T d2, T d3, T d4, T d5 )
00238 {
00239 set( d0, d1, d2, d3, d4, d5 );
00240 }
00241
00242 template<typename T>
00243 MatrixAffine2<T>::MatrixAffine2( const Vec2<T> &vx, const Vec2<T> &vy, const Vec2<T> &vz )
00244 {
00245 m00 = vx.x; m01 = vy.x; m02 = vz.x;
00246 m10 = vx.y; m11 = vy.y; m12 = vz.y;
00247 }
00248
00249 template<typename T>
00250 template<typename FromT >
00251 MatrixAffine2<T>::MatrixAffine2( const MatrixAffine2<FromT> &src )
00252 {
00253 for( int i = 0; i < 6; ++i ) {
00254 m[i] = static_cast<T>( src.m[i] );
00255 }
00256 }
00257
00258 template<typename T>
00259 MatrixAffine2<T>::MatrixAffine2( const MatrixAffine2<T>& src )
00260 {
00261 std::memcpy( m, src.m, MEM_LEN );
00262 }
00263
00264 template<typename T>
00265 MatrixAffine2<T>& MatrixAffine2<T>::operator=( const MatrixAffine2<T>& rhs )
00266 {
00267 memcpy( m, rhs.m, MEM_LEN );
00268 return *this;
00269 }
00270
00271 template<typename T>
00272 MatrixAffine2<T>& MatrixAffine2<T>::operator=( T rhs )
00273 {
00274 for( int i = 0; i < 6; ++i ) {
00275 m[i] = rhs;
00276 }
00277 return *this;
00278 }
00279
00280 template<typename T>
00281 template<typename FromT >
00282 MatrixAffine2<T>& MatrixAffine2<T>::operator=( const MatrixAffine2<FromT>& rhs )
00283 {
00284 for( int i = 0; i < 6; i++ ) {
00285 m[i] = static_cast<T>(rhs.m[i]);
00286 }
00287 return *this;
00288 }
00289
00290 template<typename T>
00291 bool MatrixAffine2<T>::equalCompare( const MatrixAffine2<T>& rhs, T epsilon ) const
00292 {
00293 for( int i = 0; i < 6; ++i ) {
00294 if( math<T>::abs(m[i] - rhs.m[i]) >= epsilon )
00295 return false;
00296 }
00297 return true;
00298 }
00299
00300 template<typename T>
00301 MatrixAffine2<T>& MatrixAffine2<T>::operator*=( const MatrixAffine2<T> &rhs )
00302 {
00303 MatrixAffine2<T> mat;
00304
00305 mat.m[0] = m[0]*rhs.m[0] + m[2]*rhs.m[1];
00306 mat.m[1] = m[1]*rhs.m[0] + m[3]*rhs.m[1];
00307
00308 mat.m[2] = m[0]*rhs.m[2] + m[2]*rhs.m[3];
00309 mat.m[3] = m[1]*rhs.m[2] + m[3]*rhs.m[3];
00310
00311 mat.m[4] = m[0]*rhs.m[4] + m[2]*rhs.m[5] + m[4];
00312 mat.m[5] = m[1]*rhs.m[4] + m[3]*rhs.m[5] + m[5];
00313
00314 *this = mat;
00315 return *this;
00316 }
00317
00318 template<typename T>
00319 MatrixAffine2<T>& MatrixAffine2<T>::operator+=( const MatrixAffine2<T> &rhs )
00320 {
00321 for( int i = 0; i < 6; ++i )
00322 m[i] += rhs.m[i];
00323 return *this;
00324 }
00325
00326 template<typename T>
00327 MatrixAffine2<T>& MatrixAffine2<T>::operator-=( const MatrixAffine2<T> &rhs )
00328 {
00329 for( int i = 0; i < 6; ++i )
00330 m[i] -= rhs.m[i];
00331 return *this;
00332 }
00333
00334 template<typename T>
00335 MatrixAffine2<T>& MatrixAffine2<T>::operator*=( T s )
00336 {
00337 for( int i = 0; i < 6; ++i )
00338 m[i] *= s;
00339 return *this;
00340 }
00341
00342 template<typename T>
00343 MatrixAffine2<T>& MatrixAffine2<T>::operator/=( T s )
00344 {
00345 T invS = 1 / s;
00346 for( int i = 0; i < 6; ++i )
00347 m[i] *= invS;
00348 return *this;
00349 }
00350
00351 template<typename T>
00352 MatrixAffine2<T>& MatrixAffine2<T>::operator+=( T s )
00353 {
00354 for( int i = 0; i < 6; ++i )
00355 m[i] += s;
00356 return *this;
00357 }
00358
00359 template<typename T>
00360 MatrixAffine2<T>& MatrixAffine2<T>::operator-=( T s )
00361 {
00362 for( int i = 0; i < 6; ++i )
00363 m[i] -= s;
00364 return *this;
00365 }
00366
00367 template<typename T>
00368 const MatrixAffine2<T> MatrixAffine2<T>::operator*( const MatrixAffine2<T> &rhs ) const
00369 {
00370 MatrixAffine2<T> ret;
00371
00372 ret.m[0] = m[0]*rhs.m[0] + m[2]*rhs.m[1];
00373 ret.m[1] = m[1]*rhs.m[0] + m[3]*rhs.m[1];
00374
00375 ret.m[2] = m[0]*rhs.m[2] + m[2]*rhs.m[3];
00376 ret.m[3] = m[1]*rhs.m[2] + m[3]*rhs.m[3];
00377
00378 ret.m[4] = m[0]*rhs.m[4] + m[2]*rhs.m[5] + m[4];
00379 ret.m[5] = m[1]*rhs.m[4] + m[3]*rhs.m[5] + m[5];
00380
00381 return ret;
00382 }
00383
00384 template<typename T>
00385 const MatrixAffine2<T> MatrixAffine2<T>::operator+( const MatrixAffine2<T> &rhs ) const
00386 {
00387 MatrixAffine2<T> ret;
00388 for( int i = 0; i < 6; ++i )
00389 ret.m[i] = m[i] + rhs.m[i];
00390 return ret;
00391 }
00392
00393 template<typename T>
00394 const MatrixAffine2<T> MatrixAffine2<T>::operator-( const MatrixAffine2<T> &rhs ) const
00395 {
00396 MatrixAffine2<T> ret;
00397 for( int i = 0; i < 6; ++i )
00398 ret.m[i] = m[i] - rhs.m[i];
00399 return ret;
00400 }
00401
00402 template<typename T>
00403 Vec2<T> MatrixAffine2<T>::transformPoint( const Vec2<T> &rhs ) const
00404 {
00405 return Vec2<T>( rhs.x * m[0] + rhs.y * m[2] + m[4], rhs.x * m[1] + rhs.y * m[3] + m[5] );
00406 }
00407
00408 template<typename T>
00409 const Vec2<T> MatrixAffine2<T>::operator*( const Vec2<T> &rhs ) const
00410 {
00411 return Vec2<T>( rhs.x * m[0] + rhs.y * m[2] + m[4], rhs.x * m[1] + rhs.y * m[3] + m[5] );
00412 }
00413
00414 template<typename T>
00415 Vec2<T> MatrixAffine2<T>::transformVec( const Vec2<T> &v ) const
00416 {
00417 return Vec2<T>( v.x * m[0] + v.y * m[2], v.x * m[1] + v.y * m[3] );
00418 }
00419
00420 template<typename T>
00421 const MatrixAffine2<T> MatrixAffine2<T>::operator*( T rhs ) const
00422 {
00423 MatrixAffine2<T> ret;
00424 for( int i = 0; i < 6; ++i )
00425 ret.m[i] = m[i]*rhs;
00426 return ret;
00427 }
00428
00429 template<typename T>
00430 const MatrixAffine2<T> MatrixAffine2<T>::operator/( T rhs ) const
00431 {
00432 MatrixAffine2<T> ret;
00433 T invS = 1 / rhs;
00434 for( int i = 0; i < 6; ++i )
00435 ret.m[i] = m[i] * invS;
00436 return ret;
00437 }
00438
00439 template<typename T>
00440 const MatrixAffine2<T> MatrixAffine2<T>::operator+( T rhs ) const
00441 {
00442 MatrixAffine2<T> ret;
00443 for( int i = 0; i < 6; ++i )
00444 ret.m[i] = m[i] + rhs;
00445 return ret;
00446 }
00447
00448 template<typename T>
00449 const MatrixAffine2<T> MatrixAffine2<T>::operator-( T rhs ) const
00450 {
00451 MatrixAffine2<T> ret;
00452 for( int i = 0; i < 6; ++i )
00453 ret.m[i] = m[i] - rhs;
00454 return ret;
00455 }
00456
00457 template<typename T>
00458 T& MatrixAffine2<T>::at( int row, int col )
00459 {
00460 assert(row >= 0 && row < 2);
00461 assert(col >= 0 && col < 3);
00462 return m[col*2 + row];
00463 }
00464
00465 template<typename T>
00466 const T& MatrixAffine2<T>::at( int row, int col ) const
00467 {
00468 assert(row >= 0 && row < 2);
00469 assert(col >= 0 && col < 3);
00470 return m[col*2 + row];
00471 }
00472
00473 template<typename T>
00474 void MatrixAffine2<T>::set( const T *d )
00475 {
00476 m[0] = d[0]; m[3] = d[3];
00477 m[1] = d[1]; m[4] = d[4];
00478 m[2] = d[2]; m[5] = d[5];
00479 }
00480
00481 template<typename T>
00482 void MatrixAffine2<T>::set( T d0, T d1, T d2, T d3, T d4, T d5 )
00483 {
00484 m[0] = d0; m[3] = d3;
00485 m[1] = d1; m[4] = d4;
00486 m[2] = d2; m[5] = d5;
00487 }
00488
00489 template<typename T>
00490 Vec2<T> MatrixAffine2<T>::getColumn( int col ) const
00491 {
00492 size_t i = col*2;
00493 return Vec2<T>(
00494 m[i + 0],
00495 m[i + 1]
00496 );
00497 }
00498
00499 template<typename T>
00500 void MatrixAffine2<T>::setColumn( int col, const Vec2<T> &v )
00501 {
00502 size_t i = col*2;
00503 m[i + 0] = v.x;
00504 m[i + 1] = v.y;
00505 }
00506
00507 template<typename T>
00508 Vec3<T> MatrixAffine2<T>::getRow( int row ) const
00509 {
00510 return Vec3<T>(
00511 m[row + 0],
00512 m[row + 3],
00513 m[row + 6]
00514 );
00515 }
00516
00517 template<typename T>
00518 void MatrixAffine2<T>::setRow( int row, const Vec3<T> &v )
00519 {
00520 m[row + 0] = v.x;
00521 m[row + 3] = v.y;
00522 m[row + 6] = v.z;
00523 }
00524
00525 template<typename T>
00526 void MatrixAffine2<T>::getColumns( Vec2<T> *c0, Vec2<T> *c1, Vec2<T> *c2 ) const
00527 {
00528 *c0 = getColumn( 0 );
00529 *c1 = getColumn( 1 );
00530 *c2 = getColumn( 2 );
00531 }
00532
00533 template<typename T>
00534 void MatrixAffine2<T>::setColumns( const Vec2<T> &c0, const Vec2<T> &c1, const Vec2<T> &c2 )
00535 {
00536 setColumn( 0, c0 );
00537 setColumn( 1, c1 );
00538 setColumn( 2, c2 );
00539 }
00540
00541 template<typename T>
00542 void MatrixAffine2<T>::getRows( Vec3<T> *r0, Vec3<T> *r1, Vec3<T> *r2 ) const
00543 {
00544 *r0 = getRow( 0 );
00545 *r1 = getRow( 1 );
00546 *r2 = getRow( 2 );
00547 }
00548
00549 template<typename T>
00550 void MatrixAffine2<T>::setRows( const Vec3<T> &r0, const Vec3<T> &r1, const Vec3<T> &r2 )
00551 {
00552 setRow( 0, r0 );
00553 setRow( 1, r1 );
00554 setRow( 2, r2 );
00555 }
00556
00557 template<typename T>
00558 void MatrixAffine2<T>::setToNull()
00559 {
00560 std::memset( m, 0, MEM_LEN );
00561 }
00562
00563 template<typename T>
00564 void MatrixAffine2<T>::setToIdentity()
00565 {
00566 m[0] = 1; m[2] = 0; m[4] = 0;
00567 m[1] = 0; m[3] = 1; m[5] = 0;
00568 }
00569
00570 template<typename T>
00571 bool MatrixAffine2<T>::isSingular() const
00572 {
00573 return fabs( m[0] * m[3] - m[2] * m[1] ) <= (T)EPSILON;
00574 }
00575
00576 template<typename T>
00577 MatrixAffine2<T> MatrixAffine2<T>::invertCopy( T epsilon ) const
00578 {
00579 MatrixAffine2<T> inv;
00580
00581 inv.m[0] = m[3];
00582 inv.m[1] = -m[1];
00583 inv.m[2] = -m[2];
00584 inv.m[3] = m[0];
00585 inv.m[4] = m[2]*m[5] - m[3]*m[4];
00586 inv.m[5] = m[1]*m[4] - m[0]*m[5];
00587
00588 T det = m[0]*inv.m[0] + m[1]*inv.m[2];
00589
00590 if( fabs( det ) > epsilon ) {
00591 T invDet = 1 / det;
00592 inv.m[0] *= invDet;
00593 inv.m[1] *= invDet;
00594 inv.m[2] *= invDet;
00595 inv.m[3] *= invDet;
00596 inv.m[4] *= invDet;
00597 inv.m[5] *= invDet;
00598 }
00599
00600 return inv;
00601 }
00602
00603 template<typename T>
00604 void MatrixAffine2<T>::translate( const Vec2<T> &v )
00605 {
00606 m[4] += m[0]*v.x + m[2]*v.y;
00607 m[5] += m[1]*v.x + m[3]*v.y;
00608 }
00609
00610 template<typename T>
00611 void MatrixAffine2<T>::scale( const Vec2<T> &s )
00612 {
00613 m[0] *= s.x;
00614 m[1] *= s.x;
00615
00616 m[2] *= s.y;
00617 m[3] *= s.y;
00618 }
00619
00620 template<typename T>
00621 MatrixAffine2<T> MatrixAffine2<T>::makeTranslate( const Vec2<T> &v )
00622 {
00623 MatrixAffine2<T> ret;
00624
00625 ret.m[0] = 1;
00626 ret.m[1] = 0;
00627
00628 ret.m[2] = 0;
00629 ret.m[3] = 1;
00630
00631 ret.m[4] = v.x;
00632 ret.m[5] = v.y;
00633
00634 return ret;
00635 }
00636
00637 template<typename T>
00638 MatrixAffine2<T> MatrixAffine2<T>::makeRotate( T radians )
00639 {
00640 T sine = math<T>::sin( radians );
00641 T cosine = math<T>::cos( radians );
00642
00643 MatrixAffine2<T> ret;
00644
00645 ret.m[0] = cosine;
00646 ret.m[1] = sine;
00647
00648 ret.m[2] = -sine;
00649 ret.m[3] = cosine;
00650
00651 ret.m[4] = 0;
00652 ret.m[5] = 0;
00653
00654 return ret;
00655 }
00656
00657 template<typename T>
00658 MatrixAffine2<T> MatrixAffine2<T>::makeRotate( T radians, const Vec2<T> &pt )
00659 {
00660 T sine = math<T>::sin( radians );
00661 T cosine = math<T>::cos( radians );
00662
00663 MatrixAffine2<T> ret;
00664
00665 ret.m[0] = cosine;
00666 ret.m[1] = sine;
00667
00668 ret.m[2] = -sine;
00669 ret.m[3] = cosine;
00670
00671 ret.m[4] = pt.x - cosine * pt.x + sine * pt.y;
00672 ret.m[5] = pt.y - sine * pt.x - cosine * pt.y;
00673
00674 return ret;
00675 }
00676
00677 template<typename T>
00678 MatrixAffine2<T> MatrixAffine2<T>::makeScale( T s )
00679 {
00680 MatrixAffine2<T> ret;
00681
00682 ret.m[0] = s;
00683 ret.m[1] = 0;
00684
00685 ret.m[2] = 0;
00686 ret.m[3] = s;
00687
00688 ret.m[4] = 0;
00689 ret.m[5] = 0;
00690
00691 return ret;
00692 }
00693
00694 template<typename T>
00695 MatrixAffine2<T> MatrixAffine2<T>::makeScale( const Vec2<T> &s )
00696 {
00697 MatrixAffine2<T> ret;
00698
00699 ret.m[0] = s.x;
00700 ret.m[1] = 0;
00701
00702 ret.m[2] = 0;
00703 ret.m[3] = s.y;
00704
00705 ret.m[4] = 0;
00706 ret.m[5] = 0;
00707
00708 return ret;
00709 }
00710
00711 template<typename T>
00712 MatrixAffine2<T> MatrixAffine2<T>::makeSkewX( T radians )
00713 {
00714 MatrixAffine2<T> ret;
00715
00716 ret.m[0] = 1;
00717 ret.m[1] = 0;
00718
00719 ret.m[2] = math<T>::tan( radians );
00720 ret.m[3] = 1;
00721
00722 ret.m[4] = 0;
00723 ret.m[5] = 0;
00724
00725 return ret;
00726 }
00727
00728 template<typename T>
00729 MatrixAffine2<T> MatrixAffine2<T>::makeSkewY( T radians )
00730 {
00731 MatrixAffine2<T> ret;
00732
00733 ret.m[0] = 1;
00734 ret.m[1] = math<T>::tan( radians );
00735
00736 ret.m[2] = 0;
00737 ret.m[3] = 1;
00738
00739 ret.m[4] = 0;
00740 ret.m[5] = 0;
00741
00742 return ret;
00743 }
00744
00745
00747
00748 typedef MatrixAffine2<float> MatrixAffine2f;
00749 typedef MatrixAffine2<double> MatrixAffine2d;
00750
00751 }