00001 /* 00002 Copyright (c) 2011, 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 // Matrix22 00036 template< typename T > 00037 class Matrix22 00038 { 00039 public: 00040 typedef T TYPE; 00041 typedef T value_type; 00042 // 00043 static const size_t DIM = 2; 00044 static const size_t DIM_SQ = DIM*DIM; 00045 static const size_t MEM_LEN = sizeof(T)*DIM_SQ; 00046 00047 // 00048 // This class is OpenGL friendly and stores the m as how OpenGL would expect it. 00049 // m[i,j]: 00050 // | m[0,0] m[0,1] | 00051 // | m[1,0] m[1,1] | 00052 // 00053 // m[idx] 00054 // | m[0] m[2] | 00055 // | m[1] m[3] | 00056 // 00057 union { 00058 T m[4]; 00059 struct { 00060 // This looks like it's transposed from the above, but it's really not. 00061 // It just has to be written this way so it follows the right ordering 00062 // in the memory layout as well as being mathematically correct. 00063 T m00, m10; 00064 T m01, m11; 00065 }; 00066 // [Cols][Rows] 00067 T mcols[2][2]; 00068 }; 00069 00070 Matrix22(); 00071 00072 Matrix22( T s ); 00073 00074 // OpenGL layout - unless srcIsRowMajor is true 00075 Matrix22( const T *dt, bool srcIsRowMajor = false ); 00076 00077 // OpenGL layout: m[0]=d0, m[1]=d1, m[2]=d2, m[3]=d3 - unless srcIsRowMajor is true 00078 Matrix22( T d0, T d1, T d2, T d3, bool srcIsRowMajor = false ); 00079 00080 // Creates matrix with column vectors vx and vy 00081 Matrix22( const Vec2<T> &vx, const Vec2<T> &vy ); 00082 00083 template< typename FromT > 00084 Matrix22( const Matrix22<FromT>& src ); 00085 00086 Matrix22( const Matrix22<T>& src ); 00087 00088 operator T*() { return (T*)m; } 00089 operator const T*() const { return (const T*)m; } 00090 00091 Matrix22<T>& operator=( const Matrix22<T>& rhs ); 00092 Matrix22<T>& operator=( const T &rhs ); 00093 00094 template< typename FromT > 00095 Matrix22<T>& operator=( const Matrix22<FromT>& rhs ); 00096 00097 bool equalCompare( const Matrix22<T>& rhs, T epsilon ) const; 00098 bool operator==( const Matrix22<T> &rhs ) const { return equalCompare( rhs, (T)EPSILON ); } 00099 bool operator!=( const Matrix22<T> &rhs ) const { return ! ( *this == rhs ); } 00100 00101 Matrix22<T>& operator*=( const Matrix22<T> &rhs ); 00102 Matrix22<T>& operator+=( const Matrix22<T> &rhs ); 00103 Matrix22<T>& operator-=( const Matrix22<T> &rhs ); 00104 00105 Matrix22<T>& operator*=( T s ); 00106 Matrix22<T>& operator/=( T s ); 00107 Matrix22<T>& operator+=( T s ); 00108 Matrix22<T>& operator-=( T s ); 00109 00110 const Matrix22<T> operator*( const Matrix22<T> &rhs ) const; 00111 const Matrix22<T> operator+( const Matrix22<T> &rhs ) const; 00112 const Matrix22<T> operator-( const Matrix22<T> &rhs ) const; 00113 00114 // post-multiplies column vector [rhs.x rhs.y] 00115 const Vec2<T> operator*( const Vec2<T> &rhs ) const; 00116 00117 const Matrix22<T> operator*( T rhs ) const; 00118 const Matrix22<T> operator/( T rhs ) const; 00119 const Matrix22<T> operator+( T rhs ) const; 00120 const Matrix22<T> operator-( T rhs ) const; 00121 00122 // Accessors 00123 T& at( int row, int col ); 00124 const T& at( int row, int col ) const; 00125 00126 // OpenGL layout - unless srcIsRowMajor is true 00127 void set( const T *dt, bool srcIsRowMajor = false ); 00128 // OpenGL layout: m[0]=d0, m[1]=d1, m[2]=d2, m[3]=d3 - unless srcIsRowMajor is true 00129 void set( T d0, T d1, T d2, T d3, bool srcIsRowMajor = false ); 00130 00131 Vec2<T> getColumn( int col ) const; 00132 void setColumn( int col, const Vec2<T> &v ); 00133 00134 Vec2<T> getRow( int row ) const; 00135 void setRow( int row, const Vec2<T> &v ); 00136 00137 void getColumns( Vec2<T> *c0, Vec2<T> *c1 ) const; 00138 void setColumns( const Vec2<T> &c0, const Vec2<T> &c1 ); 00139 00140 void getRows( Vec2<T> *r0, Vec2<T> *r1 ) const; 00141 void setRows( const Vec2<T> &r0, const Vec2<T> &r1 ); 00142 00143 void setToNull(); 00144 void setToIdentity(); 00145 00146 T determinant() const; 00147 T trace() const; 00148 00149 Matrix22<T> diagonal() const; 00150 00151 Matrix22<T> lowerTriangular() const; 00152 Matrix22<T> upperTriangular() const; 00153 00154 void transpose(); 00155 Matrix22<T> transposed() const; 00156 00157 void invert (T epsilon = EPSILON ) { *this = inverted( epsilon ); } 00158 Matrix22<T> inverted( T epsilon = EPSILON ) const; 00159 00160 // pre-multiplies row vector v - no divide by w 00161 Vec2<T> preMultiply( const Vec2<T> &v ) const; 00162 00163 // post-multiplies column vector v - no divide by w 00164 Vec2<T> postMultiply( const Vec2<T> &v ) const; 00165 00166 // post-multiplies column vector [rhs.x rhs.y] 00167 Vec2<T> transformVec( const Vec2<T> &v ) const { return postMultiply( v ); } 00168 00169 // rotate by radians (conceptually, rotate is before 'this') 00170 void rotate( T radians ) { Matrix22 rot = createRotation( radians ); Matrix22 mat = *this; *this = rot*mat; } 00171 00172 // concatenate scale (conceptually, scale is before 'this') 00173 void scale( T s ) { Matrix22 sc = createScale( s ); Matrix22 mat = *this; *this = sc*mat; } 00174 void scale( const Vec2<T> &v ) { Matrix22 sc = createScale( v ); Matrix22 mat = *this; *this = sc*mat; } 00175 00176 // transposes rotation sub-matrix and inverts translation 00177 Matrix22<T> invertTransform() const; 00178 00179 // returns an identity matrix 00180 static Matrix22<T> identity() { return Matrix22( 1, 0, 0, 1 ); } 00181 // returns 1 filled matrix 00182 static Matrix22<T> one() { return Matrix22( (T)1 ); } 00183 // returns 0 filled matrix 00184 static Matrix22<T> zero() { return Matrix22( (T)0 ); } 00185 00186 // creates rotation matrix 00187 static Matrix22<T> createRotation( T radians ); 00188 00189 // creates scale matrix 00190 static Matrix22<T> createScale( T s ); 00191 static Matrix22<T> createScale( const Vec2<T> &v ); 00192 00193 friend std::ostream& operator<<( std::ostream& lhs, const Matrix22<T>& rhs ) { 00194 for( int i = 0; i < 2; i++ ) { 00195 lhs << "|\t"; 00196 for( int j = 0; j < 2; j++ ) { 00197 lhs << rhs.at( i, j ) << "\t"; 00198 } 00199 lhs << "|" << std::endl; 00200 } 00201 00202 return lhs; 00203 } 00204 00205 }; 00206 00207 template< typename T > 00208 Matrix22<T>::Matrix22() 00209 { 00210 setToIdentity(); 00211 } 00212 00213 template< typename T > 00214 Matrix22<T>::Matrix22( T s ) 00215 { 00216 for( int i = 0; i < DIM_SQ; ++i ) { 00217 m[i] = s; 00218 } 00219 } 00220 00221 template< typename T > 00222 Matrix22<T>::Matrix22( const T *dt, bool srcIsRowMajor ) 00223 { 00224 set( dt, srcIsRowMajor ); 00225 } 00226 00227 template< typename T > 00228 Matrix22<T>::Matrix22( T d0, T d1, T d2, T d3, bool srcIsRowMajor ) 00229 { 00230 set( d0, d1, 00231 d2, d3, srcIsRowMajor ); 00232 } 00233 00234 template< typename T > 00235 Matrix22<T>::Matrix22( const Vec2<T> &vx, const Vec2<T> &vy ) 00236 { 00237 m00 = vx.x; m01 = vy.x; 00238 m10 = vx.y; m11 = vy.y; 00239 } 00240 00241 template< typename T > 00242 template< typename FromT > 00243 Matrix22<T>::Matrix22( const Matrix22<FromT>& src ) 00244 { 00245 for( int i = 0; i < DIM_SQ; ++i ) { 00246 m[i] = static_cast<T>( src.m[i] ); 00247 } 00248 } 00249 00250 template< typename T > 00251 Matrix22<T>::Matrix22( const Matrix22<T>& src ) 00252 { 00253 std::memcpy( m, src.m, MEM_LEN ); 00254 } 00255 00256 template< typename T > 00257 Matrix22<T>& Matrix22<T>::operator=( const Matrix22<T>& rhs ) 00258 { 00259 memcpy( m, rhs.m, MEM_LEN ); 00260 return *this; 00261 } 00262 00263 template< typename T > 00264 Matrix22<T>& Matrix22<T>::operator=( const T &rhs ) 00265 { 00266 for( int i = 0; i < DIM_SQ; ++i ) { 00267 m[i] = rhs; 00268 } 00269 return *this; 00270 } 00271 00272 template< typename T > 00273 template< typename FromT > 00274 Matrix22<T>& Matrix22<T>::operator=( const Matrix22<FromT>& rhs ) 00275 { 00276 for( int i = 0; i < DIM_SQ; i++ ) { 00277 m[i] = static_cast<T>(rhs.m[i]); 00278 } 00279 return *this; 00280 } 00281 00282 template< typename T > 00283 bool Matrix22<T>::equalCompare( const Matrix22<T>& rhs, T epsilon ) const 00284 { 00285 for( int i = 0; i < DIM_SQ; ++i ) { 00286 T diff = fabs( m[i] - rhs.m[i] ); 00287 if( diff >= epsilon ) 00288 return false; 00289 } 00290 return true; 00291 } 00292 00293 template< typename T > 00294 Matrix22<T>& Matrix22<T>::operator*=( const Matrix22<T> &rhs ) 00295 { 00296 Matrix22<T> mat; 00297 00298 mat.m[0] = m[0]*rhs.m[0] + m[2]*rhs.m[1]; 00299 mat.m[1] = m[1]*rhs.m[0] + m[3]*rhs.m[1]; 00300 00301 mat.m[2] = m[0]*rhs.m[2] + m[2]*rhs.m[3]; 00302 mat.m[3] = m[1]*rhs.m[2] + m[3]*rhs.m[3]; 00303 00304 *this = mat; 00305 00306 return *this; 00307 } 00308 00309 template< typename T > 00310 Matrix22<T>& Matrix22<T>::operator+=( const Matrix22<T> &rhs ) 00311 { 00312 for( int i = 0; i < DIM_SQ; ++i ) { 00313 m[i] += rhs.m[i]; 00314 } 00315 return *this; 00316 } 00317 00318 template< typename T > 00319 Matrix22<T>& Matrix22<T>::operator-=( const Matrix22<T> &rhs ) 00320 { 00321 for( int i = 0; i < DIM_SQ; ++i ) { 00322 m[i] -= rhs.m[i]; 00323 } 00324 return *this; 00325 } 00326 00327 template< typename T > 00328 Matrix22<T>& Matrix22<T>::operator*=( T s ) 00329 { 00330 for( int i = 0; i < DIM_SQ; ++i ) { 00331 m[i] *= s; 00332 } 00333 return *this; 00334 } 00335 00336 template< typename T > 00337 Matrix22<T>& Matrix22<T>::operator/=( T s ) 00338 { 00339 T invS = (T)1/s; 00340 for( int i = 0; i < DIM_SQ; ++i ) { 00341 m[i] *= invS; 00342 } 00343 return *this; 00344 } 00345 00346 template< typename T > 00347 Matrix22<T>& Matrix22<T>::operator+=( T s ) 00348 { 00349 for( int i = 0; i < DIM_SQ; ++i ) { 00350 m[i] += s; 00351 } 00352 return *this; 00353 } 00354 00355 template< typename T > 00356 Matrix22<T>& Matrix22<T>::operator-=( T s ) 00357 { 00358 for( int i = 0; i < DIM_SQ; ++i ) { 00359 m[i] -= s; 00360 } 00361 return *this; 00362 } 00363 00364 template< typename T > 00365 const Matrix22<T> Matrix22<T>::operator*( const Matrix22<T> &rhs ) const 00366 { 00367 Matrix22<T> ret; 00368 00369 ret.m[0] = m[0]*rhs.m[0] + m[2]*rhs.m[1]; 00370 ret.m[1] = m[1]*rhs.m[0] + m[3]*rhs.m[1]; 00371 00372 ret.m[2] = m[0]*rhs.m[2] + m[2]*rhs.m[3]; 00373 ret.m[3] = m[1]*rhs.m[2] + m[3]*rhs.m[3]; 00374 00375 return ret; 00376 } 00377 00378 template< typename T > 00379 const Matrix22<T> Matrix22<T>::operator+( const Matrix22<T> &rhs ) const 00380 { 00381 Matrix22<T> ret; 00382 for( int i = 0; i < DIM_SQ; ++i ) { 00383 ret.m[i] = m[i] + rhs.m[i]; 00384 } 00385 return ret; 00386 } 00387 00388 template< typename T > 00389 const Matrix22<T> Matrix22<T>::operator-( const Matrix22<T> &rhs ) const 00390 { 00391 Matrix22<T> ret; 00392 for( int i = 0; i < DIM_SQ; ++i ) { 00393 ret.m[i] = m[i] - rhs.m[i]; 00394 } 00395 return ret; 00396 } 00397 00398 template< typename T > 00399 const Vec2<T> Matrix22<T>::operator*( const Vec2<T> &rhs ) const 00400 { 00401 return Vec2<T>( 00402 m[0]*rhs.x + m[2]*rhs.y, 00403 m[1]*rhs.x + m[3]*rhs.y 00404 ); 00405 } 00406 00407 00408 template< typename T > 00409 const Matrix22<T> Matrix22<T>::operator*( T rhs ) const 00410 { 00411 Matrix22<T> ret; 00412 for( int i = 0; i < DIM_SQ; ++i ) { 00413 ret.m[i] = m[i]*rhs; 00414 } 00415 return ret; 00416 } 00417 00418 template< typename T > 00419 const Matrix22<T> Matrix22<T>::operator/( T rhs ) const 00420 { 00421 Matrix22<T> ret; 00422 T s = (T)1/rhs; 00423 for( int i = 0; i < DIM_SQ; ++i ) { 00424 ret.m[i] = m[i]*s; 00425 } 00426 return ret; 00427 } 00428 00429 template< typename T > 00430 const Matrix22<T> Matrix22<T>::operator+( T rhs ) const 00431 { 00432 Matrix22<T> ret; 00433 for( int i = 0; i < DIM_SQ; ++i ) { 00434 ret.m[i] = m[i] + rhs; 00435 } 00436 return ret; 00437 } 00438 00439 template< typename T > 00440 const Matrix22<T> Matrix22<T>::operator-( T rhs ) const 00441 { 00442 Matrix22<T> ret; 00443 for( int i = 0; i < DIM_SQ; ++i ) { 00444 ret.m[i] = m[i] - rhs; 00445 } 00446 return ret; 00447 } 00448 00449 template< typename T > 00450 T& Matrix22<T>::at( int row, int col ) 00451 { 00452 assert(row >= 0 && row < DIM); 00453 assert(col >= 0 && col < DIM); 00454 return m[col*DIM + row]; 00455 } 00456 00457 template< typename T > 00458 const T& Matrix22<T>::at( int row, int col ) const 00459 { 00460 assert(row >= 0 && row < DIM); 00461 assert(col >= 0 && col < DIM); 00462 return m[col*DIM + row]; 00463 } 00464 00465 template< typename T > 00466 void Matrix22<T>::set( const T *dt, bool srcIsRowMajor ) 00467 { 00468 if( srcIsRowMajor ) { 00469 m00 = dt[0]; m01 = dt[2]; 00470 m10 = dt[1]; m11 = dt[3]; 00471 } 00472 else { 00473 std::memcpy( m, dt, MEM_LEN ); 00474 } 00475 } 00476 00477 template< typename T > 00478 void Matrix22<T>::set( T d0, T d1, T d2, T d3, bool srcIsRowMajor ) 00479 { 00480 if( srcIsRowMajor ) { 00481 m[0] = d0; m[2] = d1; 00482 m[1] = d2; m[3] = d3; 00483 } 00484 else { 00485 m[0] = d0; m[2] = d2; 00486 m[1] = d1; m[3] = d3; 00487 } 00488 } 00489 00490 template< typename T > 00491 Vec2<T> Matrix22<T>::getColumn( int col ) const 00492 { 00493 size_t i = col*DIM; 00494 return Vec2<T>( 00495 m[i + 0], 00496 m[i + 1] 00497 ); 00498 } 00499 00500 template< typename T > 00501 void Matrix22<T>::setColumn( int col, const Vec2<T> &v ) 00502 { 00503 size_t i = col*DIM; 00504 m[i + 0] = v.x; 00505 m[i + 1] = v.y; 00506 } 00507 00508 template< typename T > 00509 Vec2<T> Matrix22<T>::getRow( int row ) const 00510 { 00511 return Vec2<T>( 00512 m[row + 0], 00513 m[row + 2] 00514 ); 00515 } 00516 00517 template< typename T > 00518 void Matrix22<T>::setRow( int row, const Vec2<T> &v ) 00519 { 00520 m[row + 0] = v.x; 00521 m[row + 2] = v.y; 00522 } 00523 00524 template< typename T > 00525 void Matrix22<T>::getColumns( Vec2<T> *c0, Vec2<T> *c1 ) const 00526 { 00527 *c0 = getColumn( 0 ); 00528 *c1 = getColumn( 1 ); 00529 } 00530 00531 template< typename T > 00532 void Matrix22<T>::setColumns( const Vec2<T> &c0, const Vec2<T> &c1 ) 00533 { 00534 setColumn( 0, c0 ); 00535 setColumn( 1, c1 ); 00536 } 00537 00538 template< typename T > 00539 void Matrix22<T>::getRows( Vec2<T> *r0, Vec2<T> *r1 ) const 00540 { 00541 *r0 = getRow( 0 ); 00542 *r1 = getRow( 1 ); 00543 } 00544 00545 template< typename T > 00546 void Matrix22<T>::setRows( const Vec2<T> &r0, const Vec2<T> &r1 ) 00547 { 00548 setRow( 0, r0 ); 00549 setRow( 1, r1 ); 00550 } 00551 00552 template< typename T > 00553 void Matrix22<T>::setToNull() 00554 { 00555 std::memset( m, 0, MEM_LEN ); 00556 } 00557 00558 template< typename T > 00559 void Matrix22<T>::setToIdentity() 00560 { 00561 m00 = 1; m01 = 0; 00562 m10 = 0; m11 = 1; 00563 } 00564 00565 template< typename T > 00566 T Matrix22<T>::determinant() const 00567 { 00568 T det = m[0]*m[3] - m[1]*m[2]; 00569 return det; 00570 } 00571 00572 template< typename T > 00573 T Matrix22<T>::trace() const 00574 { 00575 return m00 + m11; 00576 } 00577 00578 template< typename T > 00579 Matrix22<T> Matrix22<T>::diagonal() const 00580 { 00581 Matrix22 ret; 00582 ret.m00 = m00; ret.m01 = 0; 00583 ret.m10 = 0; ret.m11 = m11; 00584 return ret; 00585 } 00586 00587 template< typename T > 00588 Matrix22<T> Matrix22<T>::lowerTriangular() const 00589 { 00590 Matrix22 ret; 00591 ret.m00 = m00; ret.m01 = 0; 00592 ret.m10 = m10; ret.m11 = m11; 00593 return ret; 00594 } 00595 00596 template< typename T > 00597 Matrix22<T> Matrix22<T>::upperTriangular() const 00598 { 00599 Matrix22 ret; 00600 ret.m00 = m00; ret.m01 = m01; 00601 ret.m10 = 0; ret.m11 = m11; 00602 return ret; 00603 } 00604 00605 template< typename T > 00606 void Matrix22<T>::transpose() 00607 { 00608 T t; 00609 t = m01; m01 = m10; m10 = t; 00610 } 00611 00612 template< typename T > 00613 Matrix22<T> Matrix22<T>::transposed() const 00614 { 00615 return Matrix22<T>( 00616 m[ 0], m[ 2], 00617 m[ 1], m[ 3] 00618 ); 00619 } 00620 00621 template< typename T > 00622 Matrix22<T> Matrix22<T>::inverted( T epsilon ) const 00623 { 00624 Matrix22<T> inv( (T)0 ); 00625 00626 T det = m[0]*m[3] - m[1]*m[2]; 00627 00628 if( fabs( det ) > epsilon ) { 00629 T invDet = (T)1/det; 00630 inv.m[0] = m[3]*invDet; 00631 inv.m[1] = -m[1]*invDet; 00632 inv.m[2] = -m[2]*invDet; 00633 inv.m[3] = m[0]*invDet; 00634 } 00635 00636 return inv; 00637 } 00638 00639 template< typename T > 00640 Vec2<T> Matrix22<T>::preMultiply( const Vec2<T> &v ) const 00641 { 00642 return Vec2<T>( 00643 v.x*m00 + v.y*m10, 00644 v.x*m01 + v.y*m11 00645 ); 00646 } 00647 00648 template< typename T > 00649 Vec2<T> Matrix22<T>::postMultiply( const Vec2<T> &v ) const 00650 { 00651 return Vec2<T>( 00652 m00*v.x + m01*v.y, 00653 m10*v.x + m11*v.y 00654 ); 00655 } 00656 00657 template< typename T > 00658 Matrix22<T> Matrix22<T>::invertTransform() const 00659 { 00660 Matrix22<T> ret; 00661 00662 // transpose rotation part 00663 for( int i = 0; i < DIM; i++ ) { 00664 for( int j = 0; j < DIM; j++ ) { 00665 ret.at( j, i ) = at( i, j ); 00666 } 00667 } 00668 00669 return ret; 00670 } 00671 00672 template< typename T > 00673 Matrix22<T> Matrix22<T>::createRotation( T radians ) 00674 { 00675 Matrix22<T> ret; 00676 T ac = cos( radians ); 00677 T as = sin( radians ); 00678 ret.m00 = ac; ret.m01 = as; 00679 ret.m10 = -as; ret.m11 = ac; 00680 return ret; 00681 } 00682 00683 template< typename T > 00684 Matrix22<T> Matrix22<T>::createScale( T s ) 00685 { 00686 Matrix22<T> ret; 00687 ret.m00 = s; ret.m01 = 0; 00688 ret.m10 = 0; ret.m11 = s; 00689 return ret; 00690 } 00691 00692 template< typename T > 00693 Matrix22<T> Matrix22<T>::createScale( const Vec2<T> &v ) 00694 { 00695 Matrix22<T> ret; 00696 ret.m00 = v.x; ret.m01 = 0; 00697 ret.m10 = 0; ret.m11 = v.y; 00698 return ret; 00699 } 00700 00702 // Typedefs 00703 typedef Matrix22<float> Matrix22f; 00704 typedef Matrix22<double> Matrix22d; 00705 00706 } // namespace cinder