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     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