CMatrix3d.h
Go to the documentation of this file.
1 //==============================================================================
2 /*
3  Software License Agreement (BSD License)
4  Copyright (c) 2003-2016, CHAI3D.
5  (www.chai3d.org)
6 
7  All rights reserved.
8 
9  Redistribution and use in source and binary forms, with or without
10  modification, are permitted provided that the following conditions
11  are met:
12 
13  * Redistributions of source code must retain the above copyright
14  notice, this list of conditions and the following disclaimer.
15 
16  * Redistributions in binary form must reproduce the above
17  copyright notice, this list of conditions and the following
18  disclaimer in the documentation and/or other materials provided
19  with the distribution.
20 
21  * Neither the name of CHAI3D nor the names of its contributors may
22  be used to endorse or promote products derived from this software
23  without specific prior written permission.
24 
25  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  POSSIBILITY OF SUCH DAMAGE.
37 
38  \author <http://www.chai3d.org>
39  \author Francois Conti
40  \version 3.2.0 $Rev: 1869 $
41 */
42 //==============================================================================
43 
44 //------------------------------------------------------------------------------
45 #ifndef CMatrix3dH
46 #define CMatrix3dH
47 //------------------------------------------------------------------------------
48 #include "math/CConstants.h"
49 #include "math/CVector3d.h"
50 //------------------------------------------------------------------------------
51 
52 //------------------------------------------------------------------------------
53 namespace chai3d {
54 //------------------------------------------------------------------------------
55 
56 //------------------------------------------------------------------------------
58 {
71 };
72 //------------------------------------------------------------------------------
73 
74 //==============================================================================
82 //==============================================================================
83 
84 //==============================================================================
96 //==============================================================================
97 struct cMatrix3d
98 {
99  //--------------------------------------------------------------------------
100  // CONSTRUCTOR & DESTRUCTOR:
101  //--------------------------------------------------------------------------
102 
103 public:
104 
105  //--------------------------------------------------------------------------
109  //--------------------------------------------------------------------------
111 
112 
113 #ifdef C_USE_EIGEN
114  //--------------------------------------------------------------------------
120  //--------------------------------------------------------------------------
121  cMatrix3d(const Eigen::Matrix3d& a_matrix)
122  {
123  (*this)(0,0) = a_matrix(0,0);
124  (*this)(0,1) = a_matrix(0,1);
125  (*this)(0,2) = a_matrix(0,2);
126  (*this)(1,0) = a_matrix(1,0);
127  (*this)(1,1) = a_matrix(1,1);
128  (*this)(1,2) = a_matrix(1,2);
129  (*this)(2,0) = a_matrix(2,0);
130  (*this)(2,1) = a_matrix(2,1);
131  (*this)(2,2) = a_matrix(2,2);
132  }
133 #endif
134 
135  //--------------------------------------------------------------------------
150  //--------------------------------------------------------------------------
151  cMatrix3d(const double& a_m00, const double& a_m01, const double& a_m02,
152  const double& a_m10, const double& a_m11, const double& a_m12,
153  const double& a_m20, const double& a_m21, const double& a_m22)
154  {
155  (*this)(0,0) = a_m00; (*this)(0,1) = a_m01; (*this)(0,2) = a_m02;
156  (*this)(1,0) = a_m10; (*this)(1,1) = a_m11; (*this)(1,2) = a_m12;
157  (*this)(2,0) = a_m20; (*this)(2,1) = a_m21; (*this)(2,2) = a_m22;
158  }
159 
160 
161  //--------------------------------------------------------------------------
170  //--------------------------------------------------------------------------
171  cMatrix3d(const cVector3d& a_colVector0,
172  const cVector3d& a_colVector1,
173  const cVector3d& a_colVector2)
174  {
175  (*this).setCol0(a_colVector0);
176  (*this).setCol1(a_colVector1);
177  (*this).setCol2(a_colVector2);
178  }
179 
180 
181 #ifdef C_USE_EIGEN
182  //--------------------------------------------------------------------------
191  //--------------------------------------------------------------------------
192  cMatrix3d(const Eigen::Vector3d& a_colVector0,
193  const Eigen::Vector3d& a_colVector1,
194  const Eigen::Vector3d& a_colVector2)
195  {
196  (*this)(0,0) = a_colVector0(0); (*this)(0,1) = a_colVector1(0); (*this)(0,2) = a_colVector2(0);
197  (*this)(1,0) = a_colVector0(1); (*this)(1,1) = a_colVector1(1); (*this)(1,2) = a_colVector2(1);
198  (*this)(2,0) = a_colVector0(2); (*this)(2,1) = a_colVector1(2); (*this)(2,2) = a_colVector2(2);
199  }
200 #endif
201 
202  //--------------------------------------------------------------------------
221  //--------------------------------------------------------------------------
222  cMatrix3d(const double& a_angle1,
223  const double& a_angle2,
224  const double& a_angle3,
225  const cEulerOrder a_eulerOrder,
226  const bool a_useIntrinsicEulerModel = true,
227  const bool a_anglesDefinedInDegrees = false)
228  {
229  if (a_anglesDefinedInDegrees)
230  {
231  if (a_useIntrinsicEulerModel)
232  {
233  setIntrinsicEulerRotationDeg(a_angle1, a_angle2, a_angle3, a_eulerOrder);
234  }
235  else
236  {
237  setExtrinsicEulerRotationDeg(a_angle1, a_angle2, a_angle3, a_eulerOrder);
238  }
239  }
240  else
241  {
242  if (a_useIntrinsicEulerModel)
243  {
244  setIntrinsicEulerRotationRad(a_angle1, a_angle2, a_angle3, a_eulerOrder);
245  }
246  else
247  {
248  setExtrinsicEulerRotationRad(a_angle1, a_angle2, a_angle3, a_eulerOrder);
249  }
250  }
251  }
252 
253 
254  //--------------------------------------------------------------------------
263  //--------------------------------------------------------------------------
264  cMatrix3d(const cVector3d& a_axis,
265  const double& a_angleRad)
266  {
267  setAxisAngleRotationRad(a_axis, a_angleRad);
268  }
269 
270 
271  //--------------------------------------------------------------------------
281  //--------------------------------------------------------------------------
282  cMatrix3d(const double& a_axisX,
283  const double& a_axisY,
284  const double& a_axisZ,
285  const double& a_angleRad)
286  {
287  setAxisAngleRotationRad(a_axisX,
288  a_axisY,
289  a_axisZ,
290  a_angleRad);
291  }
292 
293 
294 #ifdef C_USE_EIGEN
295 
297  Eigen::Matrix3d eigen()
298  {
299  Eigen::Matrix3d m;
300  m(0,0) = (*this)(0,0);
301  m(0,1) = (*this)(0,1);
302  m(0,2) = (*this)(0,2);
303  m(1,0) = (*this)(1,0);
304  m(1,1) = (*this)(1,1);
305  m(1,2) = (*this)(1,2);
306  m(2,0) = (*this)(2,0);
307  m(2,1) = (*this)(2,1);
308  m(2,2) = (*this)(2,2);
309  return (m);
310  }
311 
312 #endif
313 
314 
315  //--------------------------------------------------------------------------
324  //--------------------------------------------------------------------------
325  inline void identity()
326  {
327  (*this)(0,0) = 1.0; (*this)(0,1) = 0.0; (*this)(0,2) = 0.0;
328  (*this)(1,0) = 0.0; (*this)(1,1) = 1.0; (*this)(1,2) = 0.0;
329  (*this)(2,0) = 0.0; (*this)(2,1) = 0.0; (*this)(2,2) = 1.0;
330  }
331 
332 
333  //--------------------------------------------------------------------------
344  //--------------------------------------------------------------------------
345  inline void set(const double& a_value)
346  {
347  (*this)(0,0) = a_value; (*this)(0,1) = a_value; (*this)(0,2) = a_value;
348  (*this)(1,0) = a_value; (*this)(1,1) = a_value; (*this)(1,2) = a_value;
349  (*this)(2,0) = a_value; (*this)(2,1) = a_value; (*this)(2,2) = a_value;
350  }
351 
352 
353  //--------------------------------------------------------------------------
364  //--------------------------------------------------------------------------
365  inline void set(const double a_source[3][3])
366  {
367  (*this)(0,0) = a_source[0][0];
368  (*this)(0,1) = a_source[0][1];
369  (*this)(0,2) = a_source[0][2];
370  (*this)(1,0) = a_source[1][0];
371  (*this)(1,1) = a_source[1][1];
372  (*this)(1,2) = a_source[1][2];
373  (*this)(2,0) = a_source[2][0];
374  (*this)(2,1) = a_source[2][1];
375  (*this)(2,2) = a_source[2][2];
376  }
377 
378 
379  //--------------------------------------------------------------------------
399  //--------------------------------------------------------------------------
400  inline void set(const double& a_m00, const double& a_m01, const double& a_m02,
401  const double& a_m10, const double& a_m11, const double& a_m12,
402  const double& a_m20, const double& a_m21, const double& a_m22)
403  {
404  (*this)(0,0) = a_m00; (*this)(0,1) = a_m01; (*this)(0,2) = a_m02;
405  (*this)(1,0) = a_m10; (*this)(1,1) = a_m11; (*this)(1,2) = a_m12;
406  (*this)(2,0) = a_m20; (*this)(2,1) = a_m21; (*this)(2,2) = a_m22;
407  }
408 
409 
410  //--------------------------------------------------------------------------
428  //--------------------------------------------------------------------------
429  inline void setCol(const cVector3d& a_vectCol0,
430  const cVector3d& a_vectCol1,
431  const cVector3d& a_vectCol2)
432  {
433  (*this)(0,0) = a_vectCol0(0); (*this)(0,1) = a_vectCol1(0); (*this)(0,2) = a_vectCol2(0);
434  (*this)(1,0) = a_vectCol0(1); (*this)(1,1) = a_vectCol1(1); (*this)(1,2) = a_vectCol2(1);
435  (*this)(2,0) = a_vectCol0(2); (*this)(2,1) = a_vectCol1(2); (*this)(2,2) = a_vectCol2(2);
436  }
437 
438 
439  //--------------------------------------------------------------------------
450  //--------------------------------------------------------------------------
451  inline void setCol0(const cVector3d& a_vectCol)
452  {
453  (*this)(0,0) = a_vectCol(0);
454  (*this)(1,0) = a_vectCol(1);
455  (*this)(2,0) = a_vectCol(2);
456  }
457 
458 
459  //--------------------------------------------------------------------------
470  //--------------------------------------------------------------------------
471  inline void setCol1(const cVector3d& a_vectCol)
472  {
473  (*this)(0,1) = a_vectCol(0);
474  (*this)(1,1) = a_vectCol(1);
475  (*this)(2,1) = a_vectCol(2);
476  }
477 
478 
479  //--------------------------------------------------------------------------
490  //--------------------------------------------------------------------------
491  inline void setCol2(const cVector3d& a_vectCol)
492  {
493  (*this)(0,2) = a_vectCol(0);
494  (*this)(1,2) = a_vectCol(1);
495  (*this)(2,2) = a_vectCol(2);
496  }
497 
498 
499  //--------------------------------------------------------------------------
510  //--------------------------------------------------------------------------
511  inline void get(double* a_destination[])
512  {
513  *a_destination[0] = (*this)(0,0);
514  *a_destination[1] = (*this)(0,1);
515  *a_destination[2] = (*this)(0,2);
516  *a_destination[3] = (*this)(1,0);
517  *a_destination[4] = (*this)(1,1);
518  *a_destination[5] = (*this)(1,2);
519  *a_destination[6] = (*this)(2,0);
520  *a_destination[7] = (*this)(2,1);
521  *a_destination[8] = (*this)(2,2);
522  }
523 
524 
525  //--------------------------------------------------------------------------
535  //--------------------------------------------------------------------------
536  inline cVector3d getCol0() const
537  {
538  cVector3d result;
539  result(0) = (*this)(0,0);
540  result(1) = (*this)(1,0);
541  result(2) = (*this)(2,0);
542  return (result);
543  }
544 
545 
546  //--------------------------------------------------------------------------
556  //--------------------------------------------------------------------------
557  inline cVector3d getCol1() const
558  {
559  cVector3d result;
560  result(0) = (*this)(0,1);
561  result(1) = (*this)(1,1);
562  result(2) = (*this)(2,1);
563  return (result);
564  }
565 
566 
567  //--------------------------------------------------------------------------
577  //--------------------------------------------------------------------------
578  inline cVector3d getCol2() const
579  {
580  cVector3d result;
581  result(0) = (*this)(0,2);
582  result(1) = (*this)(1,2);
583  result(2) = (*this)(2,2);
584  return (result);
585  }
586 
587 
588  //--------------------------------------------------------------------------
601  //--------------------------------------------------------------------------
602  inline cVector3d getRow(const unsigned int& a_index) const
603  {
604  cVector3d result;
605  result(0) = (*this)(a_index, 0);
606  result(1) = (*this)(a_index, 1);
607  result(2) = (*this)(a_index, 2);
608  return (result);
609  }
610 
611 
612  //--------------------------------------------------------------------------
627  //--------------------------------------------------------------------------
628  inline void copyto(cMatrix3d& a_destination) const
629  {
630  a_destination = (*this);
631  }
632 
633 
634 #ifdef C_USE_EIGEN
635  //--------------------------------------------------------------------------
650  //--------------------------------------------------------------------------
651  inline void copyto(Eigen::Matrix3d& a_destination) const
652  {
653  a_destination(0,0) = (*this)(0,0); a_destination(0,1) = (*this)(0,1); a_destination(0,2) = (*this)(0,2);
654  a_destination(1,0) = (*this)(1,0); a_destination(1,1) = (*this)(1,1); a_destination(1,2) = (*this)(1,2);
655  a_destination(2,0) = (*this)(2,0); a_destination(2,1) = (*this)(2,1); a_destination(2,2) = (*this)(2,2);
656  }
657 #endif
658 
659  //--------------------------------------------------------------------------
674  //--------------------------------------------------------------------------
675  inline void copyfrom(const cMatrix3d& a_source)
676  {
677  (*this) = a_source;
678  }
679 
680 
681 #ifdef C_USE_EIGEN
682  //--------------------------------------------------------------------------
697  //--------------------------------------------------------------------------
698  inline void copyfrom(const Eigen::Matrix3d& a_source)
699  {
700  (*this)(0,0) = a_source(0,0); (*this)(0,1) = a_source(0,1); (*this)(0,2) = a_source(0,2);
701  (*this)(1,0) = a_source(1,0); (*this)(1,1) = a_source(1,1); (*this)(1,2) = a_source(1,2);
702  (*this)(2,0) = a_source(2,0); (*this)(2,1) = a_source(2,1); (*this)(2,2) = a_source(2,2);
703  }
704 #endif
705 
706 
707  //--------------------------------------------------------------------------
721  //--------------------------------------------------------------------------
722  inline bool equals(cMatrix3d& a_matrix) const
723  {
724  for(int i=0; i<3; i++)
725  {
726  for(int j=0; j<3; j++)
727  {
728  if (a_matrix(i,j) != (*this)(i,j)) return (false);
729  }
730  }
731  return (true);
732  }
733 
734 
735  //--------------------------------------------------------------------------
751  //--------------------------------------------------------------------------
752  inline void add(const cMatrix3d& a_matrix)
753  {
754  (*this)(0,0) = (*this)(0,0) + a_matrix(0,0);
755  (*this)(0,1) = (*this)(0,1) + a_matrix(0,1);
756  (*this)(0,2) = (*this)(0,2) + a_matrix(0,2);
757  (*this)(1,0) = (*this)(1,0) + a_matrix(1,0);
758  (*this)(1,1) = (*this)(1,1) + a_matrix(1,1);
759  (*this)(1,2) = (*this)(1,2) + a_matrix(1,2);
760  (*this)(2,0) = (*this)(2,0) + a_matrix(2,0);
761  (*this)(2,1) = (*this)(2,1) + a_matrix(2,1);
762  (*this)(2,2) = (*this)(2,2) + a_matrix(2,2);
763  }
764 
765 
766  //--------------------------------------------------------------------------
784  //--------------------------------------------------------------------------
785  inline void addr(const cMatrix3d& a_matrix,
786  cMatrix3d& a_result) const
787  {
788  a_result(0,0) = (*this)(0,0) + a_matrix(0,0);
789  a_result(0,1) = (*this)(0,1) + a_matrix(0,1);
790  a_result(0,2) = (*this)(0,2) + a_matrix(0,2);
791  a_result(1,0) = (*this)(1,0) + a_matrix(1,0);
792  a_result(1,1) = (*this)(1,1) + a_matrix(1,1);
793  a_result(1,2) = (*this)(1,2) + a_matrix(1,2);
794  a_result(2,0) = (*this)(2,0) + a_matrix(2,0);
795  a_result(2,1) = (*this)(2,1) + a_matrix(2,1);
796  a_result(2,2) = (*this)(2,2) + a_matrix(2,2);
797  }
798 
799 
800  //--------------------------------------------------------------------------
816  //--------------------------------------------------------------------------
817  inline void sub(const cMatrix3d& a_matrix)
818  {
819  (*this)(0,0) = (*this)(0,0) - a_matrix(0,0);
820  (*this)(0,1) = (*this)(0,1) - a_matrix(0,1);
821  (*this)(0,2) = (*this)(0,2) - a_matrix(0,2);
822  (*this)(1,0) = (*this)(1,0) - a_matrix(1,0);
823  (*this)(1,1) = (*this)(1,1) - a_matrix(1,1);
824  (*this)(1,2) = (*this)(1,2) - a_matrix(1,2);
825  (*this)(2,0) = (*this)(2,0) - a_matrix(2,0);
826  (*this)(2,1) = (*this)(2,1) - a_matrix(2,1);
827  (*this)(2,2) = (*this)(2,2) - a_matrix(2,2);
828  }
829 
830 
831  //--------------------------------------------------------------------------
849  //--------------------------------------------------------------------------
850  inline void subr(const cMatrix3d& a_matrix,
851  cMatrix3d& a_result) const
852  {
853  a_result(0,0) = (*this)(0,0) - a_matrix(0,0);
854  a_result(0,1) = (*this)(0,1) - a_matrix(0,1);
855  a_result(0,2) = (*this)(0,2) - a_matrix(0,2);
856  a_result(1,0) = (*this)(1,0) - a_matrix(1,0);
857  a_result(1,1) = (*this)(1,1) - a_matrix(1,1);
858  a_result(1,2) = (*this)(1,2) - a_matrix(1,2);
859  a_result(2,0) = (*this)(2,0) - a_matrix(2,0);
860  a_result(2,1) = (*this)(2,1) - a_matrix(2,1);
861  a_result(2,2) = (*this)(2,2) - a_matrix(2,2);
862  }
863 
864 
865  //--------------------------------------------------------------------------
882  //--------------------------------------------------------------------------
883  inline void mul(const cMatrix3d& a_matrix)
884  {
885  // compute multiplication between both matrices
886  double m00 = (*this)(0,0) * a_matrix(0,0) + (*this)(0,1) * a_matrix(1,0) + (*this)(0,2) * a_matrix(2,0);
887  double m01 = (*this)(0,0) * a_matrix(0,1) + (*this)(0,1) * a_matrix(1,1) + (*this)(0,2) * a_matrix(2,1);
888  double m02 = (*this)(0,0) * a_matrix(0,2) + (*this)(0,1) * a_matrix(1,2) + (*this)(0,2) * a_matrix(2,2);
889  double m10 = (*this)(1,0) * a_matrix(0,0) + (*this)(1,1) * a_matrix(1,0) + (*this)(1,2) * a_matrix(2,0);
890  double m11 = (*this)(1,0) * a_matrix(0,1) + (*this)(1,1) * a_matrix(1,1) + (*this)(1,2) * a_matrix(2,1);
891  double m12 = (*this)(1,0) * a_matrix(0,2) + (*this)(1,1) * a_matrix(1,2) + (*this)(1,2) * a_matrix(2,2);
892  double m20 = (*this)(2,0) * a_matrix(0,0) + (*this)(2,1) * a_matrix(1,0) + (*this)(2,2) * a_matrix(2,0);
893  double m21 = (*this)(2,0) * a_matrix(0,1) + (*this)(2,1) * a_matrix(1,1) + (*this)(2,2) * a_matrix(2,1);
894  double m22 = (*this)(2,0) * a_matrix(0,2) + (*this)(2,1) * a_matrix(1,2) + (*this)(2,2) * a_matrix(2,2);
895 
896  // return values to current matrix
897  (*this)(0,0) = m00; (*this)(0,1) = m01; (*this)(0,2) = m02;
898  (*this)(1,0) = m10; (*this)(1,1) = m11; (*this)(1,2) = m12;
899  (*this)(2,0) = m20; (*this)(2,1) = m21; (*this)(2,2) = m22;
900  }
901 
902 
903  //--------------------------------------------------------------------------
921  //--------------------------------------------------------------------------
922  inline void mulr(const cMatrix3d& a_matrix,
923  cMatrix3d& a_result) const
924  {
925  // compute multiplication between both matrices
926  a_result(0,0) = (*this)(0,0) * a_matrix(0,0) + (*this)(0,1) * a_matrix(1,0) + (*this)(0,2) * a_matrix(2,0);
927  a_result(0,1) = (*this)(0,0) * a_matrix(0,1) + (*this)(0,1) * a_matrix(1,1) + (*this)(0,2) * a_matrix(2,1);
928  a_result(0,2) = (*this)(0,0) * a_matrix(0,2) + (*this)(0,1) * a_matrix(1,2) + (*this)(0,2) * a_matrix(2,2);
929  a_result(1,0) = (*this)(1,0) * a_matrix(0,0) + (*this)(1,1) * a_matrix(1,0) + (*this)(1,2) * a_matrix(2,0);
930  a_result(1,1) = (*this)(1,0) * a_matrix(0,1) + (*this)(1,1) * a_matrix(1,1) + (*this)(1,2) * a_matrix(2,1);
931  a_result(1,2) = (*this)(1,0) * a_matrix(0,2) + (*this)(1,1) * a_matrix(1,2) + (*this)(1,2) * a_matrix(2,2);
932  a_result(2,0) = (*this)(2,0) * a_matrix(0,0) + (*this)(2,1) * a_matrix(1,0) + (*this)(2,2) * a_matrix(2,0);
933  a_result(2,1) = (*this)(2,0) * a_matrix(0,1) + (*this)(2,1) * a_matrix(1,1) + (*this)(2,2) * a_matrix(2,1);
934  a_result(2,2) = (*this)(2,0) * a_matrix(0,2) + (*this)(2,1) * a_matrix(1,2) + (*this)(2,2) * a_matrix(2,2);
935  }
936 
937 
938  //--------------------------------------------------------------------------
955  //--------------------------------------------------------------------------
956  inline void mul(cVector3d& a_vector) const
957  {
958  // compute multiplication
959  double x = (*this)(0,0) * a_vector(0) + (*this)(0,1) * a_vector(1) + (*this)(0,2) * a_vector(2);
960  double y = (*this)(1,0) * a_vector(0) + (*this)(1,1) * a_vector(1) + (*this)(1,2) * a_vector(2);
961  double z = (*this)(2,0) * a_vector(0) + (*this)(2,1) * a_vector(1) + (*this)(2,2) * a_vector(2);
962 
963  // store result
964  a_vector(0) = x;
965  a_vector(1) = y;
966  a_vector(2) = z;
967  }
968 
969 
970  //--------------------------------------------------------------------------
984  //--------------------------------------------------------------------------
985  inline void mulr(const cVector3d& a_vector,
986  cVector3d& a_result) const
987  {
988  a_result(0) = (*this)(0,0) * a_vector(0) + (*this)(0,1) * a_vector(1) + (*this)(0,2) * a_vector(2);
989  a_result(1) = (*this)(1,0) * a_vector(0) + (*this)(1,1) * a_vector(1) + (*this)(1,2) * a_vector(2);
990  a_result(2) = (*this)(2,0) * a_vector(0) + (*this)(2,1) * a_vector(1) + (*this)(2,2) * a_vector(2);
991  }
992 
993 
994  //--------------------------------------------------------------------------
1004  //--------------------------------------------------------------------------
1005  inline double det() const
1006  {
1007  return (+ (*this)(0,0) * (*this)(1,1) * (*this)(2,2)
1008  + (*this)(0,1) * (*this)(1,2) * (*this)(2,0)
1009  + (*this)(0,2) * (*this)(1,0) * (*this)(2,1)
1010  - (*this)(2,0) * (*this)(1,1) * (*this)(0,2)
1011  - (*this)(2,1) * (*this)(1,2) * (*this)(0,0)
1012  - (*this)(2,2) * (*this)(1,0) * (*this)(0,1));
1013  }
1014 
1015 
1016  //--------------------------------------------------------------------------
1026  //--------------------------------------------------------------------------
1027  inline void trans()
1028  {
1029  double t;
1030  t = (*this)(0,1); (*this)(0,1) = (*this)(1,0); (*this)(1,0) = t;
1031  t = (*this)(0,2); (*this)(0,2) = (*this)(2,0); (*this)(2,0) = t;
1032  t = (*this)(1,2); (*this)(1,2) = (*this)(2,1); (*this)(2,1) = t;
1033  }
1034 
1035 
1036  //--------------------------------------------------------------------------
1048  //--------------------------------------------------------------------------
1049  inline void transr(cMatrix3d& a_result) const
1050  {
1051  a_result(0,0) = (*this)(0,0);
1052  a_result(0,1) = (*this)(1,0);
1053  a_result(0,2) = (*this)(2,0);
1054 
1055  a_result(1,0) = (*this)(0,1);
1056  a_result(1,1) = (*this)(1,1);
1057  a_result(1,2) = (*this)(2,1);
1058 
1059  a_result(2,0) = (*this)(0,2);
1060  a_result(2,1) = (*this)(1,2);
1061  a_result(2,2) = (*this)(2,2);
1062  }
1063 
1064 
1065  //--------------------------------------------------------------------------
1076  //--------------------------------------------------------------------------
1077  bool invert()
1078  {
1079  // compute determinant
1080  double d = ( + (*this)(0,0) * (*this)(1,1) * (*this)(2,2)
1081  + (*this)(0,1) * (*this)(1,2) * (*this)(2,0)
1082  + (*this)(0,2) * (*this)(1,0) * (*this)(2,1)
1083  - (*this)(2,0) * (*this)(1,1) * (*this)(0,2)
1084  - (*this)(2,1) * (*this)(1,2) * (*this)(0,0)
1085  - (*this)(2,2) * (*this)(1,0) * (*this)(0,1));
1086 
1087  // check if determinant null
1088  if ((d < C_TINY) && (d > -C_TINY))
1089  {
1090  // determinant null, matrix inversion could not be performed
1091  return (false);
1092  }
1093  else
1094  {
1095  // compute inverted matrix
1096  double m00 = ((*this)(1,1) * (*this)(2,2) - (*this)(2,1)*(*this)(1,2)) / d;
1097  double m01 = -((*this)(0,1) * (*this)(2,2) - (*this)(2,1)*(*this)(0,2)) / d;
1098  double m02 = ((*this)(0,1) * (*this)(1,2) - (*this)(1,1)*(*this)(0,2)) / d;
1099 
1100  double m10 = -((*this)(1,0) * (*this)(2,2) - (*this)(2,0)*(*this)(1,2)) / d;
1101  double m11 = ((*this)(0,0) * (*this)(2,2) - (*this)(2,0)*(*this)(0,2)) / d;
1102  double m12 = -((*this)(0,0) * (*this)(1,2) - (*this)(1,0)*(*this)(0,2)) / d;
1103 
1104  double m20 = ((*this)(1,0) * (*this)(2,1) - (*this)(2,0)*(*this)(1,1)) / d;
1105  double m21 = -((*this)(0,0) * (*this)(2,1) - (*this)(2,0)*(*this)(0,1)) / d;
1106  double m22 = ((*this)(0,0) * (*this)(1,1) - (*this)(1,0)*(*this)(0,1)) / d;
1107 
1108  // return values to current matrix
1109  (*this)(0,0) = m00; (*this)(0,1) = m01; (*this)(0,2) = m02;
1110  (*this)(1,0) = m10; (*this)(1,1) = m11; (*this)(1,2) = m12;
1111  (*this)(2,0) = m20; (*this)(2,1) = m21; (*this)(2,2) = m22;
1112 
1113  // return success
1114  return (true);
1115  }
1116  }
1117 
1118 
1119  //--------------------------------------------------------------------------
1131  //--------------------------------------------------------------------------
1132  bool invertr(cMatrix3d& a_result) const
1133  {
1134  // compute determinant
1135  double d = ( + (*this)(0,0) * (*this)(1,1) * (*this)(2,2)
1136  + (*this)(0,1) * (*this)(1,2) * (*this)(2,0)
1137  + (*this)(0,2) * (*this)(1,0) * (*this)(2,1)
1138  - (*this)(2,0) * (*this)(1,1) * (*this)(0,2)
1139  - (*this)(2,1) * (*this)(1,2) * (*this)(0,0)
1140  - (*this)(2,2) * (*this)(1,0) * (*this)(0,1));
1141 
1142  // check if determinant null.
1143  if ((d < C_TINY) && (d > -C_TINY))
1144  {
1145  // determinant null, matrix inversion can not be performed
1146  return (false);
1147  }
1148  else
1149  {
1150  // compute inverted matrix
1151  a_result(0,0) = ((*this)(1,1) * (*this)(2,2) - (*this)(2,1)*(*this)(1,2)) / d;
1152  a_result(0,1) = -((*this)(0,1) * (*this)(2,2) - (*this)(2,1)*(*this)(0,2)) / d;
1153  a_result(0,2) = ((*this)(0,1) * (*this)(1,2) - (*this)(1,1)*(*this)(0,2)) / d;
1154 
1155  a_result(1,0) = -((*this)(1,0) * (*this)(2,2) - (*this)(2,0)*(*this)(1,2)) / d;
1156  a_result(1,1) = ((*this)(0,0) * (*this)(2,2) - (*this)(2,0)*(*this)(0,2)) / d;
1157  a_result(1,2) = -((*this)(0,0) * (*this)(1,2) - (*this)(1,0)*(*this)(0,2)) / d;
1158 
1159  a_result(2,0) = ((*this)(1,0) * (*this)(2,1) - (*this)(2,0)*(*this)(1,1)) / d;
1160  a_result(2,1) = -((*this)(0,0) * (*this)(2,1) - (*this)(2,0)*(*this)(0,1)) / d;
1161  a_result(2,2) = ((*this)(0,0) * (*this)(1,1) - (*this)(1,0)*(*this)(0,1)) / d;
1162 
1163  // return success
1164  return (true);
1165  }
1166  }
1167 
1168 
1169  //--------------------------------------------------------------------------
1179  //--------------------------------------------------------------------------
1181  {
1182  cVector3d c0 = getCol0();
1183  cVector3d c1 = getCol1();
1184  cVector3d c2;
1185 
1186  c0.crossr(c1, c2);
1187  c2.crossr(c0, c1);
1188 
1189  c0.normalize();
1190  c1.normalize();
1191  c2.normalize();
1192  }
1193 
1194 
1195  //--------------------------------------------------------------------------
1210  //--------------------------------------------------------------------------
1211  inline bool setAxisAngleRotationRad(const cVector3d& a_axis,
1212  const double& a_angleRad)
1213  {
1214  // compute length of axis vector
1215  double length = a_axis.length();
1216 
1217  // check length of axis vector
1218  if (length < C_TINY)
1219  {
1220  // rotation matrix could not be computed because axis vector is not defined
1221  return (false);
1222  }
1223 
1224  // normalize axis vector
1225  double f = 1.0 / length;
1226  double x = f * a_axis(0);
1227  double y = f * a_axis(1);
1228  double z = f * a_axis(2);
1229 
1230  // compute rotation matrix
1231  double c = ::cos(a_angleRad);
1232  double s = ::sin(a_angleRad);
1233  double v = 1-c;
1234 
1235  (*this)(0,0) = x*x*v+c; (*this)(0,1) = x*y*v-z*s; (*this)(0,2) = x*z*v+y*s;
1236  (*this)(1,0) = x*y*v+z*s; (*this)(1,1) = y*y*v+c; (*this)(1,2) = y*z*v-x*s;
1237  (*this)(2,0) = x*z*v-y*s; (*this)(2,1) = y*z*v+x*s; (*this)(2,2) = z*z*v+c;
1238 
1239  // return success
1240  return (true);
1241  }
1242 
1243 
1244  //--------------------------------------------------------------------------
1259  //--------------------------------------------------------------------------
1260  inline bool setAxisAngleRotationDeg(const cVector3d& a_axis,
1261  const double& a_angleDeg)
1262  {
1263  return (setAxisAngleRotationRad(a_axis, C_DEG2RAD * (a_angleDeg)));
1264  }
1265 
1266 
1267  //--------------------------------------------------------------------------
1284  //--------------------------------------------------------------------------
1285  inline bool setAxisAngleRotationRad(const double& a_axisX,
1286  const double& a_axisY,
1287  const double& a_axisZ,
1288  const double& a_angleRad)
1289  {
1290  return (setAxisAngleRotationRad(cVector3d(a_axisX, a_axisY, a_axisZ), a_angleRad));
1291  }
1292 
1293 
1294  //--------------------------------------------------------------------------
1311  //--------------------------------------------------------------------------
1312  inline bool setAxisAngleRotationDeg(const double& a_axisX,
1313  const double& a_axisY,
1314  const double& a_axisZ,
1315  const double& a_angleDeg)
1316  {
1317  return (setAxisAngleRotationRad(cVector3d(a_axisX, a_axisY, a_axisZ), C_DEG2RAD * (a_angleDeg)));
1318  }
1319 
1320 
1321  //--------------------------------------------------------------------------
1336  //--------------------------------------------------------------------------
1337  inline void setExtrinsicEulerRotationRad(const double& a_angle1,
1338  const double& a_angle2,
1339  const double& a_angle3,
1340  const cEulerOrder a_eulerOrder)
1341  {
1342  switch(a_eulerOrder)
1343  {
1344  case(C_EULER_ORDER_XYZ):
1345  setIntrinsicEulerRotationRad(a_angle3, a_angle2, a_angle1, C_EULER_ORDER_ZYX);
1346  break;
1347 
1348  case(C_EULER_ORDER_XYX):
1349  setIntrinsicEulerRotationRad(a_angle3, a_angle2, a_angle1, C_EULER_ORDER_XYX);
1350  break;
1351 
1352  case(C_EULER_ORDER_XZY):
1353  setIntrinsicEulerRotationRad(a_angle3, a_angle2, a_angle1, C_EULER_ORDER_YZX);
1354  break;
1355 
1356  case(C_EULER_ORDER_XZX):
1357  setIntrinsicEulerRotationRad(a_angle3, a_angle2, a_angle1, C_EULER_ORDER_XZX);
1358  break;
1359 
1360  case(C_EULER_ORDER_YZX):
1361  setIntrinsicEulerRotationRad(a_angle3, a_angle2, a_angle1, C_EULER_ORDER_XZY);
1362  break;
1363 
1364  case(C_EULER_ORDER_YZY):
1365  setIntrinsicEulerRotationRad(a_angle3, a_angle2, a_angle1, C_EULER_ORDER_YZY);
1366  break;
1367 
1368  case(C_EULER_ORDER_YXZ):
1369  setIntrinsicEulerRotationRad(a_angle3, a_angle2, a_angle1, C_EULER_ORDER_ZXY);
1370  break;
1371 
1372  case(C_EULER_ORDER_YXY):
1373  setIntrinsicEulerRotationRad(a_angle3, a_angle2, a_angle1, C_EULER_ORDER_YXY);
1374  break;
1375 
1376  case(C_EULER_ORDER_ZXY):
1377  setIntrinsicEulerRotationRad(a_angle3, a_angle2, a_angle1, C_EULER_ORDER_YXZ);
1378  break;
1379 
1380  case(C_EULER_ORDER_ZXZ):
1381  setIntrinsicEulerRotationRad(a_angle3, a_angle2, a_angle1, C_EULER_ORDER_ZXZ);
1382  break;
1383 
1384  case(C_EULER_ORDER_ZYX):
1385  setIntrinsicEulerRotationRad(a_angle3, a_angle2, a_angle1, C_EULER_ORDER_XYZ);
1386  break;
1387 
1388  case(C_EULER_ORDER_ZYZ):
1389  setIntrinsicEulerRotationRad(a_angle3, a_angle2, a_angle1, C_EULER_ORDER_ZYZ);
1390  break;
1391  }
1392  }
1393 
1394 
1395  //--------------------------------------------------------------------------
1410  //--------------------------------------------------------------------------
1411  inline void setExtrinsicEulerRotationDeg(const double& a_angle1,
1412  const double& a_angle2,
1413  const double& a_angle3,
1414  const cEulerOrder a_eulerOrder)
1415  {
1417  C_DEG2RAD * (a_angle2),
1418  C_DEG2RAD * (a_angle3),
1419  a_eulerOrder);
1420  }
1421 
1422 
1423  //--------------------------------------------------------------------------
1438  //--------------------------------------------------------------------------
1439  inline void setIntrinsicEulerRotationRad(const double& a_angle1,
1440  const double& a_angle2,
1441  const double& a_angle3,
1442  const cEulerOrder a_eulerOrder)
1443  {
1444  double c1 = ::cos(a_angle1);
1445  double s1 = ::sin(a_angle1);
1446  double c2 = ::cos(a_angle2);
1447  double s2 = ::sin(a_angle2);
1448  double c3 = ::cos(a_angle3);
1449  double s3 = ::sin(a_angle3);
1450 
1451  switch(a_eulerOrder)
1452  {
1453  case(C_EULER_ORDER_XYZ):
1454  (*this)(0,0) = c2*c3; (*this)(0,1) =-c2*s3; (*this)(0,2) = s2;
1455  (*this)(1,0) = c1*s3+c3*s1*s2; (*this)(1,1) = c1*c3-s1*s2*s3; (*this)(1,2) =-c2*s1;
1456  (*this)(2,0) = s1*s3-c1*c3*s2; (*this)(2,1) = c3*s1+c1*s2*s3; (*this)(2,2) = c1*c2;
1457  break;
1458 
1459  case(C_EULER_ORDER_XYX):
1460  (*this)(0,0) = c2; (*this)(0,1) = s2*s3; (*this)(0,2) = c3*s2;
1461  (*this)(1,0) = s1*s2; (*this)(1,1) = c1*c3-c2*s1*s3; (*this)(1,2) =-c1*s3-c2*c3*s1;
1462  (*this)(2,0) =-c1*s2; (*this)(2,1) = c3*s1+c1*c2*s3; (*this)(2,2) = c1*c2*c3-s1*s3;
1463  break;
1464 
1465  case(C_EULER_ORDER_XZY):
1466  (*this)(0,0) = c2*c3; (*this)(0,1) =-s2; (*this)(0,2) = c2*s3;
1467  (*this)(1,0) = s1*s3+c1*c3*s2; (*this)(1,1) = c1*c2; (*this)(1,2) = c1*s2*s3-c3*s1;
1468  (*this)(2,0) = c3*s1*s2-c1*s3; (*this)(2,1) = c2*s1; (*this)(2,2) = c1*c3+s1*s2*s3;
1469  break;
1470 
1471  case(C_EULER_ORDER_XZX):
1472  (*this)(0,0) = c2; (*this)(0,1) =-c3*s2; (*this)(0,2) = s2*s3;
1473  (*this)(1,0) = c1*s2; (*this)(1,1) = c1*c2*c3-s1*s3; (*this)(1,2) =-c3*s1-c1*c2*s3;
1474  (*this)(2,0) = s1*s2; (*this)(2,1) = c1*s3+c2*c3*s1; (*this)(2,2) = c1*c3-c2*s1*s3;
1475  break;
1476 
1477  case(C_EULER_ORDER_YZX):
1478  (*this)(0,0) = c1*c2; (*this)(0,1) = s1*s3-c1*c3*s2; (*this)(0,2) = c3*s1+c1*s2*s3;
1479  (*this)(1,0) = s2; (*this)(1,1) = c2*c3; (*this)(1,2) =-c2*s3;
1480  (*this)(2,0) =-c2*s1; (*this)(2,1) = c1*s3+c3*s1*s2; (*this)(2,2) = c1*c3-s1*s2*s3;
1481  break;
1482 
1483  case(C_EULER_ORDER_YZY):
1484  (*this)(0,0) = c1*c2*c3-s1*s3; (*this)(0,1) =-c1*s2; (*this)(0,2) = c3*s1+c1*c2*s3;
1485  (*this)(1,0) = c3*s2; (*this)(1,1) = c2; (*this)(1,2) = s2*s3;
1486  (*this)(2,0) =-c1*s3-c2*c3*s1; (*this)(2,1) = s1*s2; (*this)(2,2) = c1*c3-c2*s1*s3;
1487  break;
1488 
1489  case(C_EULER_ORDER_YXZ):
1490  (*this)(0,0) = c1*c3+s1*s2*s3; (*this)(0,1) = c3*s1*s2-c1*s3; (*this)(0,2) = c2*s1;
1491  (*this)(1,0) = c2*s3; (*this)(1,1) = c2*c3; (*this)(1,2) =-s2;
1492  (*this)(2,0) = c1*s2*s3-c3*s1; (*this)(2,1) = s1*s3+c1*c3*s2; (*this)(2,2) = c1*c2;
1493  break;
1494 
1495  case(C_EULER_ORDER_YXY):
1496  (*this)(0,0) = c1*c3-c2*s1*s3; (*this)(0,1) = s1*s2; (*this)(0,2) = c1*s3+c2*c3*s1;
1497  (*this)(1,0) = s2*s3; (*this)(1,1) = c2; (*this)(1,2) =-c3*s2;
1498  (*this)(2,0) =-c3*s1-c1*c2*s3; (*this)(2,1) = c1*s2; (*this)(2,2) = c1*c2*c3-s1*s3;
1499  break;
1500 
1501  case(C_EULER_ORDER_ZXY):
1502  (*this)(0,0) = c1*c3-s1*s2*s3; (*this)(0,1) =-c2*s1; (*this)(0,2) = c1*s3+c3*s1*s2;
1503  (*this)(1,0) = c3*s1+c1*s2*s3; (*this)(1,1) = c1*c2; (*this)(1,2) = s1*s3-c1*c3*s2;
1504  (*this)(2,0) =-c2*s3; (*this)(2,1) = s2; (*this)(2,2) = c2*c3;
1505  break;
1506 
1507  case(C_EULER_ORDER_ZXZ):
1508  (*this)(0,0) = c1*c3-c2*s1*s3; (*this)(0,1) =-c1*s3-c2*c3*s1; (*this)(0,2) = s1*s2;
1509  (*this)(1,0) = c3*s1+c1*c2*s3; (*this)(1,1) = c1*c2*c3-s1*s3; (*this)(1,2) =-c1*s2;
1510  (*this)(2,0) = s2*s3; (*this)(2,1) = c3*s2; (*this)(2,2) = c2;
1511  break;
1512 
1513  case(C_EULER_ORDER_ZYX):
1514  (*this)(0,0) = c1*c2; (*this)(0,1) = c1*s2*s3-c3*s1; (*this)(0,2) = s1*s3+c1*c3*s2;
1515  (*this)(1,0) = c2*s1; (*this)(1,1) = c1*c3+s1*s2*s3; (*this)(1,2) = c3*s1*s2-c1*s3;
1516  (*this)(2,0) =-s2; (*this)(2,1) = c2*s3; (*this)(2,2) = c2*c3;
1517  break;
1518 
1519  case(C_EULER_ORDER_ZYZ):
1520  (*this)(0,0) = c1*c2*c3-s1*s3; (*this)(0,1) =-c3*s1-c1*c2*s3; (*this)(0,2) = c1*s2;
1521  (*this)(1,0) = c1*s3+c2*c3*s1; (*this)(1,1) = c1*c3-c2*s1*s3; (*this)(1,2) = s1*s2;
1522  (*this)(2,0) =-c3*s2; (*this)(2,1) = s2*s3; (*this)(2,2) = c2;
1523  break;
1524  }
1525  }
1526 
1527 
1528  //--------------------------------------------------------------------------
1543  //--------------------------------------------------------------------------
1544  inline void setIntrinsicEulerRotationDeg(const double& a_angle1,
1545  const double& a_angle2,
1546  const double& a_angle3,
1547  const cEulerOrder a_eulerOrder)
1548  {
1550  C_DEG2RAD * (a_angle2),
1551  C_DEG2RAD * (a_angle3),
1552  a_eulerOrder);
1553  }
1554 
1555 
1556  //--------------------------------------------------------------------------
1571  //--------------------------------------------------------------------------
1572  inline bool rotateAboutGlobalAxisRad(const cVector3d& a_axis,
1573  const double& a_angleRad)
1574  {
1575  // compute length of axis vector
1576  double length = a_axis.length();
1577 
1578  // check length of axis vector
1579  if (length < C_TINY)
1580  {
1581  // rotation matrix could not be computed because axis vector is not defined
1582  return (false);
1583  }
1584 
1585  // normalize axis vector
1586  double f = 1.0 / length;
1587  double x = f * a_axis(0);
1588  double y = f * a_axis(1);
1589  double z = f * a_axis(2);
1590 
1591  // compute rotation matrix
1592  double c = ::cos(a_angleRad);
1593  double s = ::sin(a_angleRad);
1594  double v = 1-c;
1595 
1596  cMatrix3d m;
1597  m(0,0) = x*x*v+c; m(0,1) = x*y*v-z*s; m(0,2) = x*z*v+y*s;
1598  m(1,0) = x*y*v+z*s; m(1,1) = y*y*v+c; m(1,2) = y*z*v-x*s;
1599  m(2,0) = x*z*v-y*s; m(2,1) = y*z*v+x*s; m(2,2) = z*z*v+c;
1600 
1601  (*this) = m*(*this);
1602 
1603  // return success
1604  return (true);
1605  }
1606 
1607 
1608  //--------------------------------------------------------------------------
1623  //--------------------------------------------------------------------------
1624  inline bool rotateAboutGlobalAxisDeg(const cVector3d& a_axis,
1625  const double& a_angleDeg)
1626  {
1627  return (rotateAboutGlobalAxisRad(a_axis, C_DEG2RAD * (a_angleDeg)));
1628  }
1629 
1630 
1631  //--------------------------------------------------------------------------
1648  //--------------------------------------------------------------------------
1649  inline bool rotateAboutGlobalAxisRad(const double& a_axisX,
1650  const double& a_axisY,
1651  const double& a_axisZ,
1652  const double& a_angleRad)
1653  {
1654  return(rotateAboutGlobalAxisRad(cVector3d(a_axisX, a_axisY, a_axisZ), a_angleRad));
1655  }
1656 
1657 
1658  //--------------------------------------------------------------------------
1675  //--------------------------------------------------------------------------
1676  inline bool rotateAboutGlobalAxisDeg(const double& a_axisX,
1677  const double& a_axisY,
1678  const double& a_axisZ,
1679  const double& a_angleDeg)
1680  {
1681  return(rotateAboutGlobalAxisRad(cVector3d(a_axisX, a_axisY, a_axisZ), C_DEG2RAD * (a_angleDeg)));
1682  }
1683 
1684 
1685  //--------------------------------------------------------------------------
1700  //--------------------------------------------------------------------------
1701  inline bool rotateAboutLocalAxisRad(const cVector3d& a_axis,
1702  const double& a_angleRad)
1703  {
1704  // compute length of axis vector
1705  double length = a_axis.length();
1706 
1707  // check length of axis vector
1708  if (length < C_TINY)
1709  {
1710  // rotation matrix could not be computed because axis vector is not defined
1711  return (false);
1712  }
1713 
1714  // normalize axis vector
1715  double f = 1.0 / length;
1716  double x = f * a_axis(0);
1717  double y = f * a_axis(1);
1718  double z = f * a_axis(2);
1719 
1720  // compute rotation matrix
1721  double c = ::cos(a_angleRad);
1722  double s = ::sin(a_angleRad);
1723  double v = 1-c;
1724 
1725  cMatrix3d m;
1726  m(0,0) = x*x*v+c; m(0,1) = x*y*v-z*s; m(0,2) = x*z*v+y*s;
1727  m(1,0) = x*y*v+z*s; m(1,1) = y*y*v+c; m(1,2) = y*z*v-x*s;
1728  m(2,0) = x*z*v-y*s; m(2,1) = y*z*v+x*s; m(2,2) = z*z*v+c;
1729 
1730  (*this) = (*this)*m;
1731 
1732  // return success
1733  return (true);
1734  }
1735 
1736 
1737  //--------------------------------------------------------------------------
1752  //--------------------------------------------------------------------------
1753  inline bool rotateAboutLocalAxisDeg(const cVector3d& a_axis,
1754  const double& a_angleDeg)
1755  {
1756  return(rotateAboutLocalAxisRad(a_axis, C_DEG2RAD * (a_angleDeg)));
1757  }
1758 
1759 
1760  //--------------------------------------------------------------------------
1777  //--------------------------------------------------------------------------
1778  inline bool rotateAboutLocalAxisRad(const double& a_axisX,
1779  const double& a_axisY,
1780  const double& a_axisZ,
1781  const double& a_angleRad)
1782  {
1783  return(rotateAboutLocalAxisRad(cVector3d(a_axisX, a_axisY, a_axisZ), a_angleRad));
1784  }
1785 
1786 
1787  //--------------------------------------------------------------------------
1804  //--------------------------------------------------------------------------
1805  inline bool rotateAboutLocalAxisDeg(const double& a_axisX,
1806  const double& a_axisY,
1807  const double& a_axisZ,
1808  const double& a_angleDeg)
1809  {
1810  return(rotateAboutLocalAxisRad(cVector3d(a_axisX, a_axisY, a_axisZ), C_DEG2RAD * (a_angleDeg)));
1811  }
1812 
1813 
1814  //--------------------------------------------------------------------------
1829  //--------------------------------------------------------------------------
1830  bool toAxisAngle(cVector3d& a_axis,
1831  double& a_angle) const
1832  {
1833  double angle,x,y,z; // variables for result
1834  double epsilon1 = 0.01; // margin to allow for rounding errors
1835  double epsilon2 = 0.1; // margin to distinguish between 0 and 180 degrees
1836 
1837  if ((fabs((*this)(0,1) - (*this)(1,0)) < epsilon1) &&
1838  (fabs((*this)(0,2) - (*this)(2,0)) < epsilon1) &&
1839  (fabs((*this)(1,2) - (*this)(2,1)) < epsilon1))
1840  {
1841  // singularity found
1842  // first check for identity matrix which must have +1 for all terms
1843  // in leading diagonal and zero in other terms
1844  if ( (fabs((*this)(0,1) + (*this)(1,0)) < epsilon2) &&
1845  (fabs((*this)(0,2) + (*this)(2,0)) < epsilon2) &&
1846  (fabs((*this)(1,2) + (*this)(2,1)) < epsilon2) &&
1847  (fabs((*this)(0,0) + (*this)(1,1) + (*this)(2,2)-3) < epsilon2))
1848  {
1849  // this singularity is identity matrix so angle = 0
1850  a_axis.set(1,0,0);
1851  a_angle = 0;
1852  return (true);
1853  }
1854 
1855  // otherwise this singularity is angle = 180
1856  angle = C_PI;
1857  double xx = ((*this)(0,0)+1)/2;
1858  double yy = ((*this)(1,1)+1)/2;
1859  double zz = ((*this)(2,2)+1)/2;
1860  double xy = ((*this)(0,1)+(*this)(1,0))/4;
1861  double xz = ((*this)(0,2)+(*this)(2,0))/4;
1862  double yz = ((*this)(1,2)+(*this)(2,1))/4;
1863 
1864  if ((xx > yy) && (xx > zz))
1865  {
1866  // (*this)(0,0) is the largest diagonal term
1867  if (xx < epsilon1)
1868  {
1869  x = 0;
1870  y = 0.7071;
1871  z = 0.7071;
1872  }
1873  else
1874  {
1875  x = sqrt(xx);
1876  y = xy/x;
1877  z = xz/x;
1878  }
1879  }
1880  else if (yy > zz)
1881  {
1882  // (*this)(1,1) is the largest diagonal term
1883  if (yy< epsilon1)
1884  {
1885  x = 0.7071067811865475;
1886  y = 0.0;
1887  z = 0.7071067811865475;
1888  }
1889  else
1890  {
1891  y = sqrt(yy);
1892  x = xy/y;
1893  z = yz/y;
1894  }
1895  }
1896  else
1897  {
1898  // (*this)(2,2) is the largest diagonal term so base result on this
1899  if (zz < epsilon1)
1900  {
1901  x = 0.7071067811865475;
1902  y = 0.7071067811865475;
1903  z = 0.0;
1904  }
1905  else
1906  {
1907  z = sqrt(zz);
1908  x = xz/z;
1909  y = yz/z;
1910  }
1911  }
1912 
1913  a_axis.set(x,y,z);
1914  a_angle = angle;
1915  return (true);
1916  }
1917 
1918  // as we have reached here there are no singularities so we can handle normally
1919  double s = sqrt(((*this)(2,1) - (*this)(1,2))*((*this)(2,1) - (*this)(1,2)) +
1920  ((*this)(0,2) - (*this)(2,0))*((*this)(0,2) - (*this)(2,0)) +
1921  ((*this)(1,0) - (*this)(0,1))*((*this)(1,0) - (*this)(0,1)));
1922 
1923 
1924  // prevent divide by zero, should not happen if matrix is orthogonal and should be
1925  // caught by singularity test above, but I've left it in just in case
1926  if (fabs(s) < 0.001) s=1;
1927 
1928  angle = acos(( (*this)(0,0) + (*this)(1,1) + (*this)(2,2) - 1)/2);
1929  x = ((*this)(2,1) - (*this)(1,2))/s;
1930  y = ((*this)(0,2) - (*this)(2,0))/s;
1931  z = ((*this)(1,0) - (*this)(0,1))/s;
1932 
1933  a_axis.set(x,y,z);
1934  a_angle = angle;
1935 
1936  return (true);
1937  }
1938 
1939 
1940  //--------------------------------------------------------------------------
1955  //--------------------------------------------------------------------------
1956  inline std::string str(const unsigned int a_precision = 2) const
1957  {
1958  std::string result;
1959  result.append("[ ");
1960 
1961  for (int i=0; i<3; i++)
1962  {
1963  result.append("( ");
1964  for (int j=0; j<3; j++)
1965  {
1966  result.append(cStr((*this)(j,i), a_precision));
1967  if (j<2)
1968  {
1969  result.append(", ");
1970  }
1971  }
1972  result.append(" ) ");
1973  }
1974  result.append("]");
1975 
1976  return (result);
1977  }
1978 
1979 
1981  inline void operator*= (const double& a_val)
1982  {
1983  (*this)(0,0) *= a_val; (*this)(0,1) *= a_val; (*this)(0,2) *= a_val;
1984  (*this)(1,0) *= a_val; (*this)(1,1) *= a_val; (*this)(1,2) *= a_val;
1985  (*this)(2,0) *= a_val; (*this)(2,1) *= a_val; (*this)(2,2) *= a_val;
1986  }
1987 
1988 
1990  inline cVector3d operator* (const cVector3d& a_val)
1991  {
1992  cVector3d result;
1993  mulr(a_val, result);
1994  return result;
1995  }
1996 
1997 
1999  inline cMatrix3d operator* (const cMatrix3d& a_val)
2000  {
2001  cMatrix3d result;
2002  mulr(a_val,result);
2003  return result;
2004  }
2005 
2006 
2008  inline void operator*= (const cMatrix3d& a_val)
2009  {
2010  (*this).mul(a_val);
2011  }
2012 
2013 
2015  inline void operator+= (const cMatrix3d& a_input)
2016  {
2017  (*this)(0,0) += a_input(0,0);
2018  (*this)(0,1) += a_input(0,1);
2019  (*this)(0,2) += a_input(0,2);
2020 
2021  (*this)(1,0) += a_input(1,0);
2022  (*this)(1,1) += a_input(1,1);
2023  (*this)(1,2) += a_input(1,2);
2024 
2025  (*this)(2,0) += a_input(2,0);
2026  (*this)(2,1) += a_input(2,1);
2027  (*this)(2,2) += a_input(2,2);
2028  }
2029 
2030 
2032  inline void operator-= (const cMatrix3d& a_input)
2033  {
2034  (*this)(0,0) -= a_input(0,0);
2035  (*this)(0,1) -= a_input(0,1);
2036  (*this)(0,2) -= a_input(0,2);
2037 
2038  (*this)(1,0) -= a_input(1,0);
2039  (*this)(1,1) -= a_input(1,1);
2040  (*this)(1,2) -= a_input(1,2);
2041 
2042  (*this)(2,0) -= a_input(2,0);
2043  (*this)(2,1) -= a_input(2,1);
2044  (*this)(2,2) -= a_input(2,2);
2045  }
2046 
2047 
2049  inline double& operator() (const int a_index0, const int a_index1)
2050  {
2051  return m_data[a_index0][a_index1];
2052  }
2053 
2054 
2056  inline const double& operator() (const int a_index0, const int a_index1) const
2057  {
2058  return m_data[a_index0][a_index1];
2059  }
2060 
2061 
2062  //--------------------------------------------------------------------------
2063  // PRIVATE MEMBERS
2064  //--------------------------------------------------------------------------
2065 
2066 private:
2067 
2069  double m_data[3][3];
2070 };
2071 
2072 
2073 //==============================================================================
2074 // OPERATORS
2075 //==============================================================================
2076 
2078 inline cVector3d operator*(const cMatrix3d& a_matrix,
2079  const cVector3d& a_vector)
2080 {
2081  cVector3d result;
2082  a_matrix.mulr(a_vector, result);
2083  return (result);
2084 }
2085 
2086 
2088 inline cMatrix3d operator*(const cMatrix3d& a_matrix1,
2089  const cMatrix3d& a_matrix2)
2090 {
2091  cMatrix3d result;
2092  a_matrix1.mulr(a_matrix2, result);
2093  return (result);
2094 }
2095 
2096 
2097 //------------------------------------------------------------------------------
2098 } // namespace chai3d
2099 //------------------------------------------------------------------------------
2100 
2101 //------------------------------------------------------------------------------
2102 #endif
2103 //------------------------------------------------------------------------------
This class implements a 3D vector.
Definition: CVector3d.h:88
Definition: CMatrix3d.h:67
void setExtrinsicEulerRotationDeg(const double &a_angle1, const double &a_angle2, const double &a_angle3, const cEulerOrder a_eulerOrder)
This method builds a rotation matrix from an Euler angle representation.
Definition: CMatrix3d.h:1411
bool setAxisAngleRotationRad(const cVector3d &a_axis, const double &a_angleRad)
This method builds a rotation matrix from an axis-angle representation.
Definition: CMatrix3d.h:1211
void sub(const cMatrix3d &a_matrix)
This method computes the subtraction of this matrix with another.
Definition: CMatrix3d.h:817
double det() const
This method computes and returns the determinant of this matrix.
Definition: CMatrix3d.h:1005
Definition: CMatrix3d.h:66
cVector3d getCol0() const
This method returns column vector 0 of matrix.
Definition: CMatrix3d.h:536
cMatrix3d(const double &a_m00, const double &a_m01, const double &a_m02, const double &a_m10, const double &a_m11, const double &a_m12, const double &a_m20, const double &a_m21, const double &a_m22)
Definition: CMatrix3d.h:151
double & operator()(const int a_index0, const int a_index1)
An overloaded () operator.
Definition: CMatrix3d.h:2049
Definition: CMatrix3d.h:69
bool rotateAboutGlobalAxisDeg(const double &a_axisX, const double &a_axisY, const double &a_axisZ, const double &a_angleDeg)
This method rotates this matrix around an axis described in global coordinates.
Definition: CMatrix3d.h:1676
bool setAxisAngleRotationDeg(const cVector3d &a_axis, const double &a_angleDeg)
This method builds a rotation matrix from an axis-angle representation.
Definition: CMatrix3d.h:1260
bool invert()
This method computes the inverse of this matrix.
Definition: CMatrix3d.h:1077
void mulr(const cMatrix3d &a_matrix, cMatrix3d &a_result) const
This function computes the multiplication of this matrix with another.
Definition: CMatrix3d.h:922
Definition: CMatrix3d.h:68
void normalize()
This method normalizes this vector to length 1.
Definition: CVector3d.h:1054
bool rotateAboutLocalAxisDeg(const double &a_axisX, const double &a_axisY, const double &a_axisZ, const double &a_angleDeg)
This method rotates this matrix around an axis described in local coordinates.
Definition: CMatrix3d.h:1805
cVector3d operator*(const cVector3d &a_val)
An overloaded * operator for matrix/vector multiplication.
Definition: CMatrix3d.h:1990
void crossr(const cVector3d &a_vector, cVector3d &a_result) const
This method computes the cross product.
Definition: CVector3d.h:975
void operator+=(const cMatrix3d &a_input)
An overloaded += operator for matrix/matrix addition.
Definition: CMatrix3d.h:2015
void operator-=(const cMatrix3d &a_input)
An overloaded -= operator for matrix/matrix subtraction.
Definition: CMatrix3d.h:2032
Definition: CMatrix3d.h:64
std::string cStr(const bool a_value)
This function converts a boolean into a string.
Definition: CString.cpp:189
Definition: CMatrix3d.h:65
double length() const
This method computes the Euclidean norm of this vector.
Definition: CVector3d.h:1015
Definition: CMatrix3d.h:70
cMatrix3d(const cVector3d &a_colVector0, const cVector3d &a_colVector1, const cVector3d &a_colVector2)
Definition: CMatrix3d.h:171
Definition: CMatrix3d.h:62
bool rotateAboutGlobalAxisDeg(const cVector3d &a_axis, const double &a_angleDeg)
This method rotates this matrix around an axis described in global coordinates.
Definition: CMatrix3d.h:1624
void mul(const cMatrix3d &a_matrix)
This function computes the multiplication of this matrix with another.
Definition: CMatrix3d.h:883
bool rotateAboutLocalAxisDeg(const cVector3d &a_axis, const double &a_angleDeg)
This method rotates this matrix around an axis described in local coordinates.
Definition: CMatrix3d.h:1753
bool rotateAboutLocalAxisRad(const cVector3d &a_axis, const double &a_angleRad)
This method rotates this matrix around an axis described in local coordinates.
Definition: CMatrix3d.h:1701
Implements mathematical constants.
void set(const double &a_x, const double &a_y, const double &a_z)
This method initializes this vector with components x, y, and z passed as arguments.
Definition: CVector3d.h:298
const double C_DEG2RAD
Conversion from degrees to radians.
Definition: CConstants.h:94
void mul(cVector3d &a_vector) const
This function computes the multiplication of this matrix with a vector.
Definition: CMatrix3d.h:956
const double C_PI
PI constant.
Definition: CConstants.h:88
bool setAxisAngleRotationRad(const double &a_axisX, const double &a_axisY, const double &a_axisZ, const double &a_angleRad)
This method builds a rotation matrix from an axis-angle representation.
Definition: CMatrix3d.h:1285
std::string str(const unsigned int a_precision=2) const
This method converts this matrix to a string representation.
Definition: CMatrix3d.h:1956
Definition: CMatrix3d.h:60
This class implements a 3D matrix.
Definition: CMatrix3d.h:97
cMatrix3d(const double &a_axisX, const double &a_axisY, const double &a_axisZ, const double &a_angleRad)
Definition: CMatrix3d.h:282
bool setAxisAngleRotationDeg(const double &a_axisX, const double &a_axisY, const double &a_axisZ, const double &a_angleDeg)
This method builds a rotation matrix from axis-angle representation.
Definition: CMatrix3d.h:1312
Definition: CMatrix3d.h:61
void setCol2(const cVector3d &a_vectCol)
This method initializes column 2 of this matrix.
Definition: CMatrix3d.h:491
void orthogonalize()
This method orthogonalizes this matrix.
Definition: CMatrix3d.h:1180
const double C_TINY
Smallest value near zero for a double.
Definition: CConstants.h:100
Definition: CMatrix3d.h:63
cMatrix3d(const double &a_angle1, const double &a_angle2, const double &a_angle3, const cEulerOrder a_eulerOrder, const bool a_useIntrinsicEulerModel=true, const bool a_anglesDefinedInDegrees=false)
Definition: CMatrix3d.h:222
cEulerOrder
Definition: CMatrix3d.h:57
void operator*=(const double &a_val)
An overloaded *= operator for matrix/scalar multiplication.
Definition: CMatrix3d.h:1981
void setExtrinsicEulerRotationRad(const double &a_angle1, const double &a_angle2, const double &a_angle3, const cEulerOrder a_eulerOrder)
This method builds a rotation matrix from an Euler angle representation.
Definition: CMatrix3d.h:1337
Implements a 3D vector.
bool rotateAboutGlobalAxisRad(const cVector3d &a_axis, const double &a_angleRad)
This method rotates this matrix around an axis described in global coordinates.
Definition: CMatrix3d.h:1572
void trans()
This method computes the transpose of this matrix.
Definition: CMatrix3d.h:1027
void setCol(const cVector3d &a_vectCol0, const cVector3d &a_vectCol1, const cVector3d &a_vectCol2)
This method initialize this matrix with column vectors passed as arguments.
Definition: CMatrix3d.h:429
void setCol1(const cVector3d &a_vectCol)
This method initializes column 1 of this matrix.
Definition: CMatrix3d.h:471
bool invertr(cMatrix3d &a_result) const
This method computes the inverse of this matrix.
Definition: CMatrix3d.h:1132
void setCol0(const cVector3d &a_vectCol)
This method initializes column 0 of this matrix.
Definition: CMatrix3d.h:451
cVector3d getCol1() const
This method returns column vector 1 of matrix.
Definition: CMatrix3d.h:557
Definition: CAudioBuffer.cpp:56
cMatrix3d(const cVector3d &a_axis, const double &a_angleRad)
Definition: CMatrix3d.h:264
bool rotateAboutLocalAxisRad(const double &a_axisX, const double &a_axisY, const double &a_axisZ, const double &a_angleRad)
This method rotates this matrix around an axis described in local coordinates.
Definition: CMatrix3d.h:1778
void identity()
This method builds an identity matrix.
Definition: CMatrix3d.h:325
void copyfrom(const cMatrix3d &a_source)
This method copies all elements from another matrix to this one.
Definition: CMatrix3d.h:675
Definition: CMatrix3d.h:59
bool toAxisAngle(cVector3d &a_axis, double &a_angle) const
This method converts this rotation matrix to an axis-angle representation.
Definition: CMatrix3d.h:1830
void add(const cMatrix3d &a_matrix)
This method computes the addition of this matrix with another.
Definition: CMatrix3d.h:752
cVector3d getCol2() const
This method returns column vector 2 of matrix.
Definition: CMatrix3d.h:578
void mulr(const cVector3d &a_vector, cVector3d &a_result) const
This function computes the multiplication of this matrix with a vector.
Definition: CMatrix3d.h:985
bool rotateAboutGlobalAxisRad(const double &a_axisX, const double &a_axisY, const double &a_axisZ, const double &a_angleRad)
This method rotates this matrix around an axis described in global coordinates.
Definition: CMatrix3d.h:1649
void setIntrinsicEulerRotationRad(const double &a_angle1, const double &a_angle2, const double &a_angle3, const cEulerOrder a_eulerOrder)
This method builds a rotation matrix from an Euler angle representation.
Definition: CMatrix3d.h:1439
bool equals(cMatrix3d &a_matrix) const
This method compares if two matrices are equal.
Definition: CMatrix3d.h:722
void subr(const cMatrix3d &a_matrix, cMatrix3d &a_result) const
This method computes the subtraction of this matrix with another.
Definition: CMatrix3d.h:850
void addr(const cMatrix3d &a_matrix, cMatrix3d &a_result) const
This method computes the addition of this matrix with another.
Definition: CMatrix3d.h:785
void setIntrinsicEulerRotationDeg(const double &a_angle1, const double &a_angle2, const double &a_angle3, const cEulerOrder a_eulerOrder)
This method builds a rotation matrix from an Euler angle representation.
Definition: CMatrix3d.h:1544
cVector3d getRow(const unsigned int &a_index) const
This method returns the i th row of matrix.
Definition: CMatrix3d.h:602
void copyto(cMatrix3d &a_destination) const
This method copies all elements of this matrix to another matrix.
Definition: CMatrix3d.h:628
cMatrix3d()
Definition: CMatrix3d.h:110
void transr(cMatrix3d &a_result) const
This method computes the transpose of this matrix.
Definition: CMatrix3d.h:1049