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