Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

include/cinder/Matrix22.h

Go to the documentation of this file.
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