Cinder  0.8.6
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Matrix33.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2011, The Cinder Project: http://libcinder.org All rights reserved.
3  This code is intended for use with the Cinder C++ library: http://libcinder.org
4 
5  Redistribution and use in source and binary forms, with or without modification, are permitted provided that
6  the following conditions are met:
7 
8  * Redistributions of source code must retain the above copyright notice, this list of conditions and
9  the following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
11  the following disclaimer in the documentation and/or other materials provided with the distribution.
12 
13  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
14  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
15  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
16  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
17  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
19  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
20  POSSIBILITY OF SUCH DAMAGE.
21 */
22 
23 
24 #pragma once
25 
26 #include "cinder/Cinder.h"
27 #include "cinder/CinderMath.h"
28 #include "cinder/Vector.h"
29 
30 #include <iomanip>
31 
32 namespace cinder {
33 
35 // Matrix33
36 template< typename T >
37 class Matrix33
38 {
39 public:
40  typedef T TYPE;
41  typedef T value_type;
42  //
43  static const size_t DIM = 3;
44  static const size_t DIM_SQ = DIM*DIM;
45  static const size_t MEM_LEN = sizeof(T)*DIM_SQ;
46 
47  //
48  // This class is OpenGL friendly and stores the m as how OpenGL would expect it.
49  // m[i,j]:
50  // | m[0,0] m[0,1] m[0,2] |
51  // | m[1,0] m[1,1] m[1,2] |
52  // | m[2,0] m[2,1] m[2,2] |
53  //
54  // m[idx]
55  // | m[0] m[3] m[6] |
56  // | m[1] m[4] m[7] |
57  // | m[2] m[5] m[8] |
58  //
59  union {
60  T m[9];
61  struct {
62  // This looks like it's transposed from the above, but it's really not.
63  // It just has to be written this way so it follows the right ordering
64  // in the memory layout as well as being mathematically correct.
65  T m00, m10, m20;
66  T m01, m11, m21;
67  T m02, m12, m22;
68  };
69  // [Cols][Rows]
70  T mcols[3][3];
71  };
72 
73  Matrix33();
74 
75  Matrix33( T s );
76 
77  // OpenGL layout - unless srcIsRowMajor is true
78  Matrix33( const T *dt, bool srcIsRowMajor = false );
79 
80  // OpenGL layout: m[0]=d0, m[1]=d1, m[2]=d2 ... m[6]=d6, m[7]=d7, m[8]=d8 - unless srcIsRowMajor is true
81  Matrix33( T d0, T d1, T d2, T d3, T d4, T d5, T d6, T d7, T d8, bool srcIsRowMajor = false );
82 
83  // Creates matrix with column vectors vx, vy and z
84  Matrix33( const Vec3<T> &vx, const Vec3<T> &vy, const Vec3<T> &vz );
85 
86  template< typename FromT >
87  Matrix33( const Matrix33<FromT>& src );
88 
89  Matrix33( const Matrix22<T>& src );
90 
91  Matrix33( const Matrix33<T>& src );
92 
93  operator T*() { return (T*)m; }
94  operator const T*() const { return (const T*)m; }
95 
96  Matrix33<T>& operator=( const Matrix33<T>& rhs );
97  Matrix33<T>& operator=( T rhs );
98 
99  template< typename FromT >
100  Matrix33<T>& operator=( const Matrix33<FromT>& rhs );
101 
102  // remaining columns and rows will be filled with identity values
103  Matrix33<T>& operator=( const Matrix22<T>& rhs );
104 
105  bool equalCompare( const Matrix33<T>& rhs, T epsilon ) const;
106  bool operator==( const Matrix33<T> &rhs ) const { return equalCompare( rhs, (T)EPSILON ); }
107  bool operator!=( const Matrix33<T> &rhs ) const { return ! ( *this == rhs ); }
108 
109  Matrix33<T>& operator*=( const Matrix33<T> &rhs );
110  Matrix33<T>& operator+=( const Matrix33<T> &rhs );
111  Matrix33<T>& operator-=( const Matrix33<T> &rhs );
112 
113  Matrix33<T>& operator*=( T s );
114  Matrix33<T>& operator/=( T s );
115  Matrix33<T>& operator+=( T s );
116  Matrix33<T>& operator-=( T s );
117 
118  const Matrix33<T> operator*( const Matrix33<T> &rhs ) const;
119  const Matrix33<T> operator+( const Matrix33<T> &rhs ) const;
120  const Matrix33<T> operator-( const Matrix33<T> &rhs ) const;
121 
122  // post-multiplies column vector [rhs.x rhs.y rhs.z]
123  const Vec3<T> operator*( const Vec3<T> &rhs ) const;
124 
125  const Matrix33<T> operator*( T rhs ) const;
126  const Matrix33<T> operator/( T rhs ) const;
127  const Matrix33<T> operator+( T rhs ) const;
128  const Matrix33<T> operator-( T rhs ) const;
129 
130  // Accessors
131  T& at( int row, int col );
132  const T& at( int row, int col ) const;
133 
134  // OpenGL layout - unless srcIsRowMajor is true
135  void set( const T *dt, bool srcIsRowMajor = false );
136  // OpenGL layout: m[0]=d0, m[1]=d1, m[2]=d2 ... m[6]=d6, m[7]=d7, m[8]=d8 - unless srcIsRowMajor is true
137  void set( T d0, T d1, T d2, T d3, T d4, T d5, T d6, T d7, T d8, bool srcIsRowMajor = false );
138 
139  Vec3<T> getColumn( int col ) const;
140  void setColumn( int col, const Vec3<T> &v );
141 
142  Vec3<T> getRow( int row ) const;
143  void setRow( int row, const Vec3<T> &v );
144 
145  void getColumns( Vec3<T> *c0, Vec3<T> *c1, Vec3<T> *c2 ) const;
146  void setColumns( const Vec3<T> &c0, const Vec3<T> &c1, const Vec3<T> &c2 );
147 
148  void getRows( Vec3<T> *r0, Vec3<T> *r1, Vec3<T> *r2 ) const;
149  void setRows( const Vec3<T> &r0, const Vec3<T> &r1, const Vec3<T> &r2 );
150 
151  // returns a sub-matrix starting at row, col
152  Matrix22<T> subMatrix22( int row, int col ) const;
153 
154  void setToNull();
155  void setToIdentity();
156 
157  T determinant() const;
158  T trace() const;
159 
160  Matrix33<T> diagonal() const;
161 
164 
165  void transpose();
166  Matrix33<T> transposed() const;
167 
168  void invert (T epsilon = FLT_MIN ) { *this = inverted( epsilon ); }
169  Matrix33<T> inverted( T epsilon = FLT_MIN ) const;
170 
171  // pre-multiplies row vector v - no divide by w
172  Vec3<T> preMultiply( const Vec3<T> &v ) const;
173 
174  // post-multiplies column vector v - no divide by w
175  Vec3<T> postMultiply( const Vec3<T> &v ) const;
176 
177  // post-multiplies column vector [rhs.x rhs.y rhs.z]
178  Vec3<T> transformVec( const Vec3<T> &v ) const { return postMultiply( v ); }
179 
180  // rotate by radians on axis (conceptually, rotate is before 'this')
181  template <template <typename> class VecT>
182  void rotate( const VecT<T> &axis, T radians ) { *this *= Matrix33<T>::createRotation( axis, radians ); }
183  // rotate by eulerRadians - Euler angles in radians (conceptually, rotate is before 'this')
184  template <template <typename> class VecT>
185  void rotate( const VecT<T> &eulerRadians ) { *this *= Matrix33<T>::createRotation( eulerRadians ); }
186  // rotate by matrix derives rotation matrix using from, to, worldUp (conceptually, rotate is before 'this')
187  template <template <typename> class VecT>
188  void rotate( const VecT<T> &from, const VecT<T> &to, const VecT<T> &worldUp ) { *this *= Matrix33<T>::createRotation( from, to, worldUp ); }
189 
190  // transposes rotation sub-matrix and inverts translation
192 
193  // returns an identity matrix
194  static Matrix33<T> identity() { return Matrix33( 1, 0, 0, 0, 1, 0, 0, 0, 1 ); }
195  // returns 1 filled matrix
196  static Matrix33<T> one() { return Matrix33( (T)1 ); }
197  // returns 0 filled matrix
198  static Matrix33<T> zero() { return Matrix33( (T)0 ); }
199 
200  // creates rotation matrix
201  static Matrix33<T> createRotation( const Vec3<T> &axis, T radians );
202  static Matrix33<T> createRotation( const Vec3<T> &from, const Vec3<T> &to, const Vec3<T> &worldUp );
203  // equivalent to rotate( zAxis, z ), then rotate( yAxis, y ) then rotate( xAxis, x )
204  static Matrix33<T> createRotation( const Vec3<T> &eulerRadians );
205 
206  // creates scale matrix
207  static Matrix33<T> createScale( T s );
208  static Matrix33<T> createScale( const Vec2<T> &v );
209  static Matrix33<T> createScale( const Vec3<T> &v );
210 
211  // creates a rotation matrix with z-axis aligned to targetDir
212  static Matrix33<T> alignZAxisWithTarget( Vec3<T> targetDir, Vec3<T> upDir );
213 
214  friend std::ostream& operator<<( std::ostream &lhs, const Matrix33<T> &rhs )
215  {
216  for( int i = 0; i < 3; i++) {
217  lhs << " |";
218  for( int j = 0; j < 3; j++) {
219  lhs << std::setw( 12 ) << std::setprecision( 5 ) << rhs.m[j*3+i];
220  }
221  lhs << "|" << std::endl;
222  }
223 
224  return lhs;
225  }
226 };
227 
228 template< typename T >
230 {
231  setToIdentity();
232 }
233 
234 template< typename T >
236 {
237  for( int i = 0; i < DIM_SQ; ++i ) {
238  m[i] = s;
239  }
240 }
241 
242 template< typename T >
243 Matrix33<T>::Matrix33( const T *dt, bool srcIsRowMajor )
244 {
245  set( dt, srcIsRowMajor );
246 }
247 
248 template< typename T >
249 Matrix33<T>::Matrix33( T d0, T d1, T d2, T d3, T d4, T d5, T d6, T d7, T d8, bool srcIsRowMajor )
250 {
251  set( d0, d1, d2,
252  d3, d4, d5,
253  d6, d7, d8, srcIsRowMajor );
254 }
255 
256 template< typename T >
257 Matrix33<T>::Matrix33( const Vec3<T> &vx, const Vec3<T> &vy, const Vec3<T> &vz )
258 {
259  m00 = vx.x; m01 = vy.x; m02 = vz.x;
260  m10 = vx.y; m11 = vy.y; m12 = vz.y;
261  m20 = vx.z; m21 = vy.z; m22 = vz.z;
262 }
263 
264 template< typename T >
265 template< typename FromT >
267 {
268  for( int i = 0; i < DIM_SQ; ++i ) {
269  m[i] = static_cast<T>( src.m[i] );
270  }
271 }
272 
273 template< typename T >
275 {
276  setToIdentity();
277  m00 = src.m00; m01 = src.m01;
278  m10 = src.m10; m11 = src.m11;
279 }
280 
281 template< typename T >
283 {
284  std::memcpy( m, src.m, MEM_LEN );
285 }
286 
287 template< typename T >
289 {
290  memcpy( m, rhs.m, MEM_LEN );
291  return *this;
292 }
293 
294 template< typename T >
296 {
297  for( int i = 0; i < DIM_SQ; ++i ) {
298  m[i] = rhs;
299  }
300  return *this;
301 }
302 
303 template< typename T >
304 template< typename FromT >
306 {
307  for( int i = 0; i < DIM_SQ; i++ ) {
308  m[i] = static_cast<T>(rhs.m[i]);
309  }
310  return *this;
311 }
312 
313 template< typename T >
315 {
316  setToIdentity();
317  m00 = rhs.m00; m01 = rhs.m01;
318  m10 = rhs.m10; m11 = rhs.m11;
319  return *this;
320 }
321 
322 template< typename T >
323 bool Matrix33<T>::equalCompare( const Matrix33<T>& rhs, T epsilon ) const
324 {
325  for( int i = 0; i < DIM_SQ; ++i ) {
326  if( math<T>::abs(m[i] - rhs.m[i]) >= epsilon )
327  return false;
328  }
329  return true;
330 }
331 
332 template< typename T >
334 {
335  Matrix33<T> mat;
336 
337  mat.m[0] = m[0]*rhs.m[0] + m[3]*rhs.m[1] + m[6]*rhs.m[2];
338  mat.m[1] = m[1]*rhs.m[0] + m[4]*rhs.m[1] + m[7]*rhs.m[2];
339  mat.m[2] = m[2]*rhs.m[0] + m[5]*rhs.m[1] + m[8]*rhs.m[2];
340 
341  mat.m[3] = m[0]*rhs.m[3] + m[3]*rhs.m[4] + m[6]*rhs.m[5];
342  mat.m[4] = m[1]*rhs.m[3] + m[4]*rhs.m[4] + m[7]*rhs.m[5];
343  mat.m[5] = m[2]*rhs.m[3] + m[5]*rhs.m[4] + m[8]*rhs.m[5];
344 
345  mat.m[6] = m[0]*rhs.m[6] + m[3]*rhs.m[7] + m[6]*rhs.m[8];
346  mat.m[7] = m[1]*rhs.m[6] + m[4]*rhs.m[7] + m[7]*rhs.m[8];
347  mat.m[8] = m[2]*rhs.m[6] + m[5]*rhs.m[7] + m[8]*rhs.m[8];
348 
349  *this = mat;
350 
351  return *this;
352 }
353 
354 template< typename T >
356 {
357  for( int i = 0; i < DIM_SQ; ++i ) {
358  m[i] += rhs.m[i];
359  }
360  return *this;
361 }
362 
363 template< typename T >
365 {
366  for( int i = 0; i < DIM_SQ; ++i ) {
367  m[i] -= rhs.m[i];
368  }
369  return *this;
370 }
371 
372 template< typename T >
374 {
375  for( int i = 0; i < DIM_SQ; ++i ) {
376  m[i] *= s;
377  }
378  return *this;
379 }
380 
381 template< typename T >
383 {
384  T invS = (T)1/s;
385  for( int i = 0; i < DIM_SQ; ++i ) {
386  m[i] *= invS;
387  }
388  return *this;
389 }
390 
391 template< typename T >
393 {
394  for( int i = 0; i < DIM_SQ; ++i ) {
395  m[i] += s;
396  }
397  return *this;
398 }
399 
400 template< typename T >
402 {
403  for( int i = 0; i < DIM_SQ; ++i ) {
404  m[i] -= s;
405  }
406  return *this;
407 }
408 
409 template< typename T >
411 {
412  Matrix33<T> ret;
413 
414  ret.m[0] = m[0]*rhs.m[0] + m[3]*rhs.m[1] + m[6]*rhs.m[2];
415  ret.m[1] = m[1]*rhs.m[0] + m[4]*rhs.m[1] + m[7]*rhs.m[2];
416  ret.m[2] = m[2]*rhs.m[0] + m[5]*rhs.m[1] + m[8]*rhs.m[2];
417 
418  ret.m[3] = m[0]*rhs.m[3] + m[3]*rhs.m[4] + m[6]*rhs.m[5];
419  ret.m[4] = m[1]*rhs.m[3] + m[4]*rhs.m[4] + m[7]*rhs.m[5];
420  ret.m[5] = m[2]*rhs.m[3] + m[5]*rhs.m[4] + m[8]*rhs.m[5];
421 
422  ret.m[6] = m[0]*rhs.m[6] + m[3]*rhs.m[7] + m[6]*rhs.m[8];
423  ret.m[7] = m[1]*rhs.m[6] + m[4]*rhs.m[7] + m[7]*rhs.m[8];
424  ret.m[8] = m[2]*rhs.m[6] + m[5]*rhs.m[7] + m[8]*rhs.m[8];
425 
426  return ret;
427 }
428 
429 template< typename T >
431 {
432  Matrix33<T> ret;
433  for( int i = 0; i < DIM_SQ; ++i ) {
434  ret.m[i] = m[i] + rhs.m[i];
435  }
436  return ret;
437 }
438 
439 template< typename T >
441 {
442  Matrix33<T> ret;
443  for( int i = 0; i < DIM_SQ; ++i ) {
444  ret.m[i] = m[i] - rhs.m[i];
445  }
446  return ret;
447 }
448 
449 template< typename T >
450 const Vec3<T> Matrix33<T>::operator*( const Vec3<T> &rhs ) const
451 {
452  return Vec3<T>(
453  m[0]*rhs.x + m[3]*rhs.y + m[6]*rhs.z,
454  m[1]*rhs.x + m[4]*rhs.y + m[7]*rhs.z,
455  m[2]*rhs.x + m[5]*rhs.y + m[8]*rhs.z
456  );
457 }
458 
459 template< typename T >
461 {
462  Matrix33<T> ret;
463  for( int i = 0; i < DIM_SQ; ++i ) {
464  ret.m[i] = m[i]*rhs;
465  }
466  return ret;
467 }
468 
469 template< typename T >
471 {
472  Matrix33<T> ret;
473  T s = (T)1/rhs;
474  for( int i = 0; i < DIM_SQ; ++i ) {
475  ret.m[i] = m[i]*s;
476  }
477  return ret;
478 }
479 
480 template< typename T >
482 {
483  Matrix33<T> ret;
484  for( int i = 0; i < DIM_SQ; ++i ) {
485  ret.m[i] = m[i] + rhs;
486  }
487  return ret;
488 }
489 
490 template< typename T >
492 {
493  Matrix33<T> ret;
494  for( int i = 0; i < DIM_SQ; ++i ) {
495  ret.m[i] = m[i] - rhs;
496  }
497  return ret;
498 }
499 
500 template< typename T >
501 T& Matrix33<T>::at( int row, int col )
502 {
503  assert(row >= 0 && row < DIM);
504  assert(col >= 0 && col < DIM);
505  return m[col*DIM + row];
506 }
507 
508 template< typename T >
509 const T& Matrix33<T>::at( int row, int col ) const
510 {
511  assert(row >= 0 && row < DIM);
512  assert(col >= 0 && col < DIM);
513  return m[col*DIM + row];
514 }
515 
516 template< typename T >
517 void Matrix33<T>::set( const T *dt, bool srcIsRowMajor )
518 {
519  if( srcIsRowMajor ) {
520  m[0] = dt[0]; m[3] = dt[1]; m[6] = dt[2];
521  m[1] = dt[3]; m[4] = dt[4]; m[7] = dt[5];
522  m[2] = dt[6]; m[5] = dt[7]; m[8] = dt[8];
523  }
524  else {
525  std::memcpy( m, dt, MEM_LEN );
526  }
527 }
528 
529 template< typename T >
530 void Matrix33<T>::set( T d0, T d1, T d2, T d3, T d4, T d5, T d6, T d7, T d8, bool srcIsRowMajor )
531 {
532  if( srcIsRowMajor ) {
533  m[0] = d0; m[3] = d1; m[6] = d2;
534  m[1] = d3; m[4] = d4; m[7] = d5;
535  m[2] = d6; m[5] = d7; m[8] = d8;
536  }
537  else {
538  m[0] = d0; m[3] = d3; m[6] = d6;
539  m[1] = d1; m[4] = d4; m[7] = d7;
540  m[2] = d2; m[5] = d5; m[8] = d8;
541  }
542 }
543 
544 template< typename T >
546 {
547  size_t i = col*DIM;
548  return Vec3<T>(
549  m[i + 0],
550  m[i + 1],
551  m[i + 2]
552  );
553 }
554 
555 template< typename T >
556 void Matrix33<T>::setColumn( int col, const Vec3<T> &v )
557 {
558  size_t i = col*DIM;
559  m[i + 0] = v.x;
560  m[i + 1] = v.y;
561  m[i + 2] = v.z;
562 }
563 
564 template< typename T >
566 {
567  return Vec3<T>(
568  m[row + 0],
569  m[row + 3],
570  m[row + 6]
571  );
572 }
573 
574 template< typename T >
575 void Matrix33<T>::setRow( int row, const Vec3<T> &v )
576 {
577  m[row + 0] = v.x;
578  m[row + 3] = v.y;
579  m[row + 6] = v.z;
580 }
581 
582 template< typename T >
583 void Matrix33<T>::getColumns( Vec3<T> *c0, Vec3<T> *c1, Vec3<T> *c2 ) const
584 {
585  *c0 = getColumn( 0 );
586  *c1 = getColumn( 1 );
587  *c2 = getColumn( 2 );
588 }
589 
590 template< typename T >
591 void Matrix33<T>::setColumns( const Vec3<T> &c0, const Vec3<T> &c1, const Vec3<T> &c2 )
592 {
593  setColumn( 0, c0 );
594  setColumn( 1, c1 );
595  setColumn( 2, c2 );
596 }
597 
598 template< typename T >
599 void Matrix33<T>::getRows( Vec3<T> *r0, Vec3<T> *r1, Vec3<T> *r2 ) const
600 {
601  *r0 = getRow( 0 );
602  *r1 = getRow( 1 );
603  *r2 = getRow( 2 );
604 }
605 
606 template< typename T >
607 void Matrix33<T>::setRows( const Vec3<T> &r0, const Vec3<T> &r1, const Vec3<T> &r2 )
608 {
609  setRow( 0, r0 );
610  setRow( 1, r1 );
611  setRow( 2, r2 );
612 }
613 
614 template< typename T >
616 {
617  Matrix22<T> ret;
618  ret.setToNull();
619 
620  for( int i = 0; i < 2; ++i ) {
621  int r = row + i;
622  if( r >= 3 ) {
623  continue;
624  }
625  for( int j = 0; j < 2; ++j ) {
626  int c = col + j;
627  if( c >= 3 ) {
628  continue;
629  }
630  ret.at( i, j ) = at( r, c );
631  }
632  }
633 
634  return ret;
635 }
636 
637 template< typename T >
639 {
640  std::memset( m, 0, MEM_LEN );
641 }
642 
643 template< typename T >
645 {
646  m00 = 1; m01 = 0; m02 = 0;
647  m10 = 0; m11 = 1; m12 = 0;
648  m20 = 0; m21 = 0; m22 = 1;
649 }
650 
651 template< typename T >
653 {
654  T co00 = m[4]*m[8] - m[5]*m[7];
655  T co10 = m[5]*m[6] - m[3]*m[8];
656  T co20 = m[3]*m[7] - m[4]*m[6];
657 
658  T det = m[0]*co00 + m[1]*co10 + m[2]*co20;
659 
660  return det;
661 }
662 
663 template< typename T >
665 {
666  return m00 + m11 + m22;
667 }
668 
669 template< typename T >
671 {
672  Matrix33 ret;
673  ret.m00 = m00; ret.m01 = 0; ret.m02 = 0;
674  ret.m10 = 0; ret.m11 = m11; ret.m12 = 0;
675  ret.m20 = 0; ret.m21 = 0; ret.m22 = m22;
676  return ret;
677 }
678 
679 template< typename T >
681 {
682  Matrix33 ret;
683  ret.m00 = m00; ret.m01 = 0; ret.m02 = 0;
684  ret.m10 = m10; ret.m11 = m11; ret.m12 = 0;
685  ret.m20 = m20; ret.m21 = m21; ret.m22 = m22;
686  return ret;
687 }
688 
689 template< typename T >
691 {
692  Matrix33 ret;
693  ret.m00 = m00; ret.m01 = m01; ret.m02 = m02;
694  ret.m10 = 0; ret.m11 = m11; ret.m12 = m12;
695  ret.m20 = 0; ret.m21 = 0; ret.m22 = m22;
696  return ret;
697 }
698 
699 template< typename T >
701 {
702  T t;
703  t = m01; m01 = m10; m10 = t;
704  t = m02; m02 = m20; m20 = t;
705  t = m12; m12 = m21; m21 = t;
706 }
707 
708 template< typename T >
710 {
711  return Matrix33<T>(
712  m[ 0], m[ 3], m[6],
713  m[ 1], m[ 4], m[7],
714  m[ 2], m[ 5], m[8]
715  );
716 }
717 
718 template< typename T >
720 {
721  Matrix33<T> inv( (T)0 );
722 
723  // Compute the adjoint.
724  inv.m[0] = m[4]*m[8] - m[5]*m[7];
725  inv.m[1] = m[2]*m[7] - m[1]*m[8];
726  inv.m[2] = m[1]*m[5] - m[2]*m[4];
727  inv.m[3] = m[5]*m[6] - m[3]*m[8];
728  inv.m[4] = m[0]*m[8] - m[2]*m[6];
729  inv.m[5] = m[2]*m[3] - m[0]*m[5];
730  inv.m[6] = m[3]*m[7] - m[4]*m[6];
731  inv.m[7] = m[1]*m[6] - m[0]*m[7];
732  inv.m[8] = m[0]*m[4] - m[1]*m[3];
733 
734  T det = m[0]*inv.m[0] + m[1]*inv.m[3] + m[2]*inv.m[6];
735 
736  if( fabs( det ) > epsilon ) {
737  T invDet = (T)1/det;
738  inv.m[0] *= invDet;
739  inv.m[1] *= invDet;
740  inv.m[2] *= invDet;
741  inv.m[3] *= invDet;
742  inv.m[4] *= invDet;
743  inv.m[5] *= invDet;
744  inv.m[6] *= invDet;
745  inv.m[7] *= invDet;
746  inv.m[8] *= invDet;
747  }
748 
749  return inv;
750 }
751 
752 template< typename T >
754 {
755  return Vec3<T>(
756  v.x*m00 + v.y*m10 + v.z*m20,
757  v.x*m01 + v.y*m11 + v.z*m21,
758  v.x*m02 + v.y*m12 + v.z*m22
759  );
760 }
761 
762 template< typename T >
764 {
765  return Vec3<T>(
766  m00*v.x + m01*v.y + m02*v.z,
767  m10*v.x + m11*v.y + m12*v.z,
768  m20*v.x + m21*v.y + m22*v.z
769  );
770 }
771 
772 template< typename T >
774 {
775  Matrix33<T> ret;
776 
777  // transpose rotation part
778  for( int i = 0; i < DIM; i++ ) {
779  for( int j = 0; j < DIM; j++ ) {
780  ret.at( j, i ) = at( i, j );
781  }
782  }
783 
784  return ret;
785 }
786 
787 template<typename T>
788 Matrix33<T> Matrix33<T>::createRotation( const Vec3<T> &from, const Vec3<T> &to, const Vec3<T> &worldUp )
789 {
790  // The goal is to obtain a rotation matrix that takes
791  // "fromDir" to "toDir". We do this in two steps and
792  // compose the resulting rotation matrices;
793  // (a) rotate "fromDir" into the z-axis
794  // (b) rotate the z-axis into "toDir"
795 
796  // The from direction must be non-zero; but we allow zero to and up dirs.
797  if( from.lengthSquared() == 0 ) {
798  return Matrix33<T>();
799  }
800  else {
801  Matrix33<T> zAxis2FromDir = alignZAxisWithTarget( from, Vec3<T>::yAxis() );
802  Matrix33<T> fromDir2zAxis = zAxis2FromDir.transposed();
803  Matrix33<T> zAxis2ToDir = alignZAxisWithTarget( to, worldUp );
804  return fromDir2zAxis * zAxis2ToDir;
805  }
806 }
807 
808 template<typename T>
810 {
811  Vec3<T> unit( axis.normalized() );
812  T sine = math<T>::sin( angle );
813  T cosine = math<T>::cos( angle );
814 
815  Matrix33<T> ret;
816 
817  ret.m[0] = unit.x * unit.x * (1 - cosine) + cosine;
818  ret.m[1] = unit.x * unit.y * (1 - cosine) + unit.z * sine;
819  ret.m[2] = unit.x * unit.z * (1 - cosine) - unit.y * sine;
820 
821  ret.m[3] = unit.x * unit.y * (1 - cosine) - unit.z * sine;
822  ret.m[4] = unit.y * unit.y * (1 - cosine) + cosine;
823  ret.m[5] = unit.y * unit.z * (1 - cosine) + unit.x * sine;
824 
825  ret.m[6] = unit.x * unit.z * (1 - cosine) + unit.y * sine;
826  ret.m[7] = unit.y * unit.z * (1 - cosine) - unit.x * sine;
827  ret.m[8] = unit.z * unit.z * (1 - cosine) + cosine;
828 
829  return ret;
830 }
831 
832 template<typename T>
834 {
835  // The ordering for this is XYZ. In OpenGL, the ordering
836  // is the same, but the operations needs to happen in
837  // reverse:
838  //
839  // glRotatef( eulerRadians.z, 0.0f, 0.0f 1.0f );
840  // glRotatef( eulerRadians.y, 0.0f, 1.0f 0.0f );
841  // glRotatef( eulerRadians.x, 1.0f, 0.0f 0.0f );
842  //
843 
844  Matrix33<T> ret;
845  T cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx;
846 
847  cos_rx = math<T>::cos( eulerRadians.x );
848  cos_ry = math<T>::cos( eulerRadians.y );
849  cos_rz = math<T>::cos( eulerRadians.z );
850 
851  sin_rx = math<T>::sin( eulerRadians.x );
852  sin_ry = math<T>::sin( eulerRadians.y );
853  sin_rz = math<T>::sin( eulerRadians.z );
854 
855  ret.m[0] = cos_rz*cos_ry;
856  ret.m[1] = sin_rz*cos_ry;
857  ret.m[2] = -sin_ry;
858 
859  ret.m[3] = -sin_rz*cos_rx + cos_rz*sin_ry*sin_rx;
860  ret.m[4] = cos_rz*cos_rx + sin_rz*sin_ry*sin_rx;
861  ret.m[5] = cos_ry*sin_rx;
862 
863  ret.m[6] = sin_rz*sin_rx + cos_rz*sin_ry*cos_rx;
864  ret.m[7] = -cos_rz*sin_rx + sin_rz*sin_ry*cos_rx;
865  ret.m[8] = cos_ry*cos_rx;
866 
867  return ret;
868 }
869 
870 template<typename T>
872 {
873  Matrix33<T> ret;
874  ret.setToIdentity();
875  ret.at(0,0) = s;
876  ret.at(1,1) = s;
877  ret.at(2,2) = s;
878  return ret;
879 }
880 
881 template<typename T>
883 {
884  Matrix33<T> ret;
885  ret.setToIdentity();
886  ret.at(0,0) = v.x;
887  ret.at(1,1) = v.y;
888  ret.at(2,2) = 1;
889  return ret;
890 }
891 
892 template<typename T>
894 {
895  Matrix33<T> ret;
896  ret.setToIdentity();
897  ret.at(0,0) = v.x;
898  ret.at(1,1) = v.y;
899  ret.at(2,2) = v.z;
900  return ret;
901 }
902 
903 template<typename T>
905 {
906 
907  // Ensure that the target direction is non-zero.
908  if( targetDir.lengthSquared() < EPSILON ) {
909  // We want to look down the negative z-axis since to match OpenGL.
910  targetDir = -Vec3<T>::zAxis();
911  }
912 
913  // Ensure that the up direction is non-zero.
914  if( upDir.lengthSquared() < EPSILON ) {
915  upDir = Vec3<T>::yAxis();
916  }
917 
918  // Check for degeneracies. If the upDir and targetDir are parallel
919  // or opposite, then compute a new, arbitrary up direction that is
920  // not parallel or opposite to the targetDir.
921  if( upDir.cross( targetDir ).lengthSquared() == 0 ) {
922  upDir = targetDir.cross( Vec3<T>::xAxis() );
923  if( upDir.lengthSquared() == 0 ) {
924  upDir = targetDir.cross( Vec3<T>::zAxis() );
925  }
926  }
927 
928  // Compute the x-, y-, and z-axis vectors of the new coordinate system.
929  Vec3<T> targetPerpDir = targetDir.cross( upDir );
930  Vec3<T> targetUpDir = targetPerpDir.cross( targetDir );
931 
932 
933  // Rotate the x-axis into targetPerpDir (row 0),
934  // rotate the y-axis into targetUpDir (row 1),
935  // rotate the z-axis into targetDir (row 2).
936  Vec3<T> row[3];
937  row[0] = targetPerpDir.normalized();
938  row[1] = targetUpDir.normalized();
939  row[2] = targetDir.normalized();
940 
941  Matrix33<T> mat(
942  row[0].x, row[0].y, row[0].z,
943  row[1].x, row[1].y, row[1].z,
944  row[2].x, row[2].y, row[2].z
945  );
946 
947  return mat;
948 }
949 
951 // Typedefs
954 
955 } // namespace cinder
GLdouble GLdouble GLdouble r
Definition: GLee.h:1474
T mcols[3][3]
Definition: Matrix33.h:70
Vec3< T > transformVec(const Vec3< T > &v) const
Definition: Matrix33.h:178
T m22
Definition: Matrix33.h:67
GLenum GLint GLint y
Definition: GLee.h:987
T lengthSquared() const
Definition: Vector.h:443
Definition: CinderMath.h:40
static T cos(T x)
Definition: CinderMath.h:46
const Matrix33< T > operator-(const Matrix33< T > &rhs) const
Definition: Matrix33.h:440
Vec3< T > preMultiply(const Vec3< T > &v) const
Definition: Matrix33.h:753
static const size_t DIM
Definition: Matrix33.h:43
T trace() const
Definition: Matrix33.h:664
static Matrix33< T > zero()
Definition: Matrix33.h:198
static Matrix33< T > alignZAxisWithTarget(Vec3< T > targetDir, Vec3< T > upDir)
Definition: Matrix33.h:904
void setRow(int row, const Vec3< T > &v)
Definition: Matrix33.h:575
void setToIdentity()
Definition: Matrix33.h:644
static Matrix33< T > identity()
Definition: Matrix33.h:194
static T sin(T x)
Definition: CinderMath.h:47
Matrix33< T > invertTransform() const
Definition: Matrix33.h:773
T & at(int row, int col)
Definition: Matrix33.h:501
T m01
Definition: Matrix22.h:64
void set(const T *dt, bool srcIsRowMajor=false)
Definition: Matrix33.h:517
Matrix33< T > & operator/=(T s)
Definition: Matrix33.h:382
Matrix33< T > lowerTriangular() const
Definition: Matrix33.h:680
#define EPSILON
Definition: CinderMath.h:125
Matrix33< T > & operator=(const Matrix33< T > &rhs)
Definition: Matrix33.h:288
void rotate(const VecT< T > &eulerRadians)
Definition: Matrix33.h:185
T z
Definition: Vector.h:321
T value_type
Definition: Matrix33.h:41
static const size_t DIM_SQ
Definition: Matrix33.h:44
void setToNull()
Definition: Matrix22.h:553
void transpose()
Definition: Matrix33.h:700
GLuint src
Definition: GLee.h:10873
T x
Definition: Vector.h:321
T x
Definition: Vector.h:71
GLfloat angle
Definition: GLee.h:13523
bool equalCompare(const Matrix33< T > &rhs, T epsilon) const
Definition: Matrix33.h:323
T y
Definition: Vector.h:321
static Matrix33< T > createScale(T s)
Definition: Matrix33.h:871
Matrix22< T > subMatrix22(int row, int col) const
Definition: Matrix33.h:615
void rotate(const VecT< T > &from, const VecT< T > &to, const VecT< T > &worldUp)
Definition: Matrix33.h:188
void getColumns(Vec3< T > *c0, Vec3< T > *c1, Vec3< T > *c2) const
Definition: Matrix33.h:583
Matrix33< float > Matrix33f
Definition: Matrix33.h:952
T m[9]
Definition: Matrix33.h:60
T m12
Definition: Matrix33.h:67
void invert(T epsilon=FLT_MIN)
Definition: Matrix33.h:168
Definition: Vector.h:68
T m10
Definition: Matrix22.h:63
T m20
Definition: Matrix33.h:65
Vec3< T > getRow(int row) const
Definition: Matrix33.h:565
GLenum GLenum GLvoid * row
Definition: GLee.h:1089
static Vec3< T > yAxis()
Definition: Vector.h:684
T m11
Definition: Matrix33.h:66
Definition: Vector.h:65
Matrix33< T > diagonal() const
Definition: Matrix33.h:670
T m00
Definition: Matrix33.h:65
const Matrix33< T > operator*(const Matrix33< T > &rhs) const
Definition: Matrix33.h:410
T m21
Definition: Matrix33.h:66
T m10
Definition: Matrix33.h:65
Vec3< T > postMultiply(const Vec3< T > &v) const
Definition: Matrix33.h:763
GLenum GLint x
Definition: GLee.h:987
const Matrix33< T > operator/(T rhs) const
Definition: Matrix33.h:470
T m01
Definition: Matrix33.h:66
Vec3< T > getColumn(int col) const
Definition: Matrix33.h:545
T & at(int row, int col)
Definition: Matrix22.h:450
void getRows(Vec3< T > *r0, Vec3< T > *r1, Vec3< T > *r2) const
Definition: Matrix33.h:599
const GLdouble * v
Definition: GLee.h:1384
GLdouble GLdouble z
Definition: GLee.h:1911
T y
Definition: Vector.h:71
T TYPE
Definition: Matrix33.h:40
Matrix33()
Definition: Matrix33.h:229
const GLubyte * c
Definition: GLee.h:8491
void setColumn(int col, const Vec3< T > &v)
Definition: Matrix33.h:556
Matrix33< double > Matrix33d
Definition: Matrix33.h:953
Matrix33< T > upperTriangular() const
Definition: Matrix33.h:690
Vec3< T > cross(const Vec3< T > &rhs) const
Definition: Vector.h:423
static Matrix33< T > createRotation(const Vec3< T > &axis, T radians)
Definition: Matrix33.h:809
T m00
Definition: Matrix22.h:63
void setToNull()
Definition: Matrix33.h:638
Matrix33< T > & operator*=(const Matrix33< T > &rhs)
Definition: Matrix33.h:333
static Matrix33< T > one()
Definition: Matrix33.h:196
static const size_t MEM_LEN
Definition: Matrix33.h:45
Definition: Matrix22.h:37
bool operator==(const Matrix33< T > &rhs) const
Definition: Matrix33.h:106
void setColumns(const Vec3< T > &c0, const Vec3< T > &c1, const Vec3< T > &c2)
Definition: Matrix33.h:591
T m11
Definition: Matrix22.h:64
void setRows(const Vec3< T > &r0, const Vec3< T > &r1, const Vec3< T > &r2)
Definition: Matrix33.h:607
T m02
Definition: Matrix33.h:67
T determinant() const
Definition: Matrix33.h:652
const GLfloat * m
Definition: GLee.h:13493
bool operator!=(const Matrix33< T > &rhs) const
Definition: Matrix33.h:107
Matrix33< T > transposed() const
Definition: Matrix33.h:709
GLdouble GLdouble t
Definition: GLee.h:1426
GLdouble s
Definition: GLee.h:1378
const Matrix33< T > operator+(const Matrix33< T > &rhs) const
Definition: Matrix33.h:430
Definition: Matrix33.h:37
void rotate(const VecT< T > &axis, T radians)
Definition: Matrix33.h:182
Matrix33< T > inverted(T epsilon=FLT_MIN) const
Definition: Matrix33.h:719
Matrix33< T > & operator+=(const Matrix33< T > &rhs)
Definition: Matrix33.h:355
Vec3< T > normalized() const
Definition: Vector.h:492
Matrix33< T > & operator-=(const Matrix33< T > &rhs)
Definition: Matrix33.h:364
static Vec3< T > zAxis()
Definition: Vector.h:685