00001 /* 00002 Copyright (c) 2012, The Cinder Project: http://libcinder.org All rights reserved. 00003 This code is intended for use with the Cinder C++ library: http://libcinder.org 00004 00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that 00006 the following conditions are met: 00007 00008 * Redistributions of source code must retain the above copyright notice, this list of conditions and 00009 the following disclaimer. 00010 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 00011 the following disclaimer in the documentation and/or other materials provided with the distribution. 00012 00013 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 00014 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00015 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00016 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00017 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00018 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00019 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00020 POSSIBILITY OF SUCH DAMAGE. 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 // MatrixAffine2 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 // This class is OpenGL friendly and stores the m as how OpenGL would expect it. 00048 // m[i,j]: 00049 // | m[0,0] m[0,1] m[0,2] | 00050 // | m[1,0] m[1,1] m[1,2] | 00051 // 00052 // m[idx] 00053 // | m[0] m[2] m[4] | 00054 // | m[1] m[3] m[5] | 00055 // 00056 // mathematically this is: 00057 // | m[0] m[2] m[4] | 00058 // | m[1] m[3] m[5] | 00059 // | 0 0 1 | 00060 union { 00061 T m[6]; 00062 struct { 00063 // This looks like it's transposed from the above, but it's really not. 00064 // It just has to be written this way so it follows the right ordering 00065 // in the memory layout as well as being mathematically correct. 00066 T m00, m10; 00067 T m01, m11; 00068 T m02, m12; 00069 }; 00070 // [Cols][Rows] 00071 T mcols[3][2]; 00072 }; 00073 00074 MatrixAffine2(); 00075 MatrixAffine2( T s ); 00076 MatrixAffine2( const T *dt ); 00077 // m[0]=d0, m[1]=d1, m[2]=d2 ... m[5]=d5 00078 MatrixAffine2( T d0, T d1, T d2, T d3, T d4, T d5 ); 00079 // Creates matrix with column vectors vx, vy and z 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 // Accessors 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 // m[0]=d0, m[1]=d1, m[2]=d2 ... m[5]=d5 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 // returns an identity matrix 00182 static MatrixAffine2<T> identity() { return MatrixAffine2( 1, 0, 0, 1, 0, 0 ); } 00183 // returns 1 filled matrix 00184 static MatrixAffine2<T> one() { return MatrixAffine2( (T)1 ); } 00185 // returns 0 filled matrix 00186 static MatrixAffine2<T> zero() { return MatrixAffine2( (T)0 ); } 00187 00188 // creates translation matrix 00189 static MatrixAffine2<T> makeTranslate( const Vec2<T> &v ); 00190 00191 // creates rotation matrix by \a radians 00192 static MatrixAffine2<T> makeRotate( T radians ); 00193 // creates rotation matrix by \a radians around the point \a pt 00194 static MatrixAffine2<T> makeRotate( T radians, const Vec2<T> &pt ); 00195 00196 // creates scale matrix 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 // Typedefs 00748 typedef MatrixAffine2<float> MatrixAffine2f; 00749 typedef MatrixAffine2<double> MatrixAffine2d; 00750 00751 } // namespace cinder