ViSP  2.10.0
vpRotationMatrix.cpp
1 /****************************************************************************
2  *
3  * $Id: vpRotationMatrix.cpp 4900 2014-09-11 09:16:21Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Rotation matrix.
36  *
37  * Authors:
38  * Eric Marchand
39  *
40  *****************************************************************************/
41 
49 #include <visp/vpMath.h>
50 #include <visp/vpMatrix.h>
51 
52 // Rotation classes
53 #include <visp/vpRotationMatrix.h>
54 
55 
56 // Exception
57 #include <visp/vpException.h>
58 #include <visp/vpMatrixException.h>
59 
60 // Debug trace
61 #include <visp/vpDebug.h>
62 #include <math.h>
63 const double vpRotationMatrix::threshold = 1e-6;
64 const double vpRotationMatrix::minimum = 0.00001;
65 
66 #define vpDEBUG_LEVEL1 0
67 
68 
72 void
74 {
75  unsigned int i,j ;
76 
77  try {
78  resize(3,3) ;
79  }
80  catch(vpException me)
81  {
82  vpERROR_TRACE("Error caught") ;
83  throw ;
84  }
85  for (i=0 ; i < 3 ; i++)
86  for (j=0 ; j < 3; j++)
87  if (i==j)
88  (*this)[i][j] = 1.0 ;
89  else
90  (*this)[i][j] = 0.0;
91 
92 }
93 
99 void
101 {
102  init() ;
103 }
109 void
111 {
112  init() ;
113 }
114 
122 {
123  for (unsigned int i=0; i<3; i++)
124  {
125  for (unsigned int j=0; j<3; j++)
126  {
127  rowPtrs[i][j] = m.rowPtrs[i][j];
128  }
129  }
130 
131  return *this;
132 }
133 
141 {
142 
143  if ((m.getCols() !=3) &&(m.getRows() !=3))
144  {
145  vpERROR_TRACE("m is not a rotation matrix !!!!! ") ;
147  "m is not a rotation matrix !!!!!"));
148  }
149 
150  for (unsigned int i=0; i<3; i++)
151  {
152  for (unsigned int j=0; j<3; j++)
153  {
154  (*this)[i][j] = m[i][j];
155  }
156  }
157 
158  if (isARotationMatrix() == false)
159  {
160  vpERROR_TRACE("m is not a rotation matrix !!!!! ") ;
162  "m is not a rotation matrix !!!!!"));
163  }
164 
165  return *this;
166 }
167 
171 {
172  vpRotationMatrix p ;
173 
174  for (unsigned int i=0;i<3;i++)
175  for (unsigned int j=0;j<3;j++)
176  {
177  double s =0 ;
178  for (unsigned int k=0;k<3;k++)
179  s +=rowPtrs[i][k] * B.rowPtrs[k][j];
180  p[i][j] = s ;
181  }
182  return p;
183 }
198 vpMatrix
200 {
201  if (B.getRows() != 3 || B.getCols() != 3) {
202  vpERROR_TRACE("The matrix is not a 3 by 3 dimension matrix") ;
204  "The matrix is not a 3 by 3 dimension matrix"));
205  }
206  vpRotationMatrix p ;
207 
208  for (unsigned int i=0;i<3;i++)
209  for (unsigned int j=0;j<3;j++)
210  {
211  double s =0 ;
212  for (unsigned int k=0;k<3;k++)
213  s +=(*this)[i][k] * B[k][j];
214  p[i][j] = s ;
215  }
216  return p;
217 }
218 
250 {
251  if (v.getRows() != 3) {
252  vpERROR_TRACE("The column vector is not a 3 dimension vector") ;
254  "The column vector is not a 3 dimension vector"));
255  }
256  vpColVector c;
257  vpMatrix::multMatrixVector(*this, v, c);
258  return c;
259 }
260 
261 
270 {
271  vpERROR_TRACE("Cannot add two rotation matrices !!!!! ") ;
273  "Cannot add two rotation matrices !!!!!"));
274 }
275 
284 {
285  vpERROR_TRACE("Cannot substract two rotation matrices !!!!! ") ;
287  "Cannot substract two rotation matrices !!!!!"));
288 }
289 
293 {
295 
296  for (unsigned int j=0;j<3;j++)p[j]=0 ;
297 
298  for (unsigned int j=0;j<3;j++) {
299  for (unsigned int i=0;i<3;i++) {
300  p[i]+=rowPtrs[i][j] * mat[j];
301  }
302  }
303 
304  return p;
305 }
306 
307 /*********************************************************************/
308 
313 bool
315 {
316  unsigned int i,j ;
317  bool isRotation = true ;
318 
319  // test R^TR = Id ;
320  vpRotationMatrix RtR = (*this).t()*(*this) ;
321  for (i=0 ; i < 3 ; i++)
322  for (j=0 ; j < 3 ; j++)
323  if (i==j)
324  {
325  if (fabs(RtR[i][j]-1) > threshold) isRotation = false ;
326  }
327  else
328  {
329  if (fabs(RtR[i][j]) > threshold) isRotation = false ;
330  }
331 
332  // test if it is a basis
333  // test || Ci || = 1
334  for (i=0 ; i < 3 ; i++)
335  if ((sqrt(vpMath::sqr(RtR[0][i]) +
336  vpMath::sqr(RtR[1][i]) +
337  vpMath::sqr(RtR[2][i])) - 1) > threshold) isRotation = false ;
338 
339  // test || Ri || = 1
340  for (i=0 ; i < 3 ; i++)
341  if ((sqrt(vpMath::sqr(RtR[i][0]) +
342  vpMath::sqr(RtR[i][1]) +
343  vpMath::sqr(RtR[i][2])) - 1) > threshold) isRotation = false ;
344 
345  // test if the basis is orthogonal
346  return isRotation ;
347 }
348 
349 
354 {
355  init() ;
356 }
357 
358 
363 {
364  init() ;
365  (*this) = M ;
366 }
371 {
372  init() ;
373  buildFrom(M);
374 }
375 
378 {
379  init() ;
380  buildFrom(tu) ;
381 }
384 {
385  init() ;
386  buildFrom(p) ;
387 }
388 
389 
392 {
393  init() ;
394  buildFrom(euler) ;
395 }
396 
397 
398 
401 {
402  init() ;
403  buildFrom(Rxyz) ;
404 }
405 
408 {
409  init() ;
410  buildFrom(Rzyx) ;
411 }
412 
415  const double tuy,
416  const double tuz) : vpMatrix()
417 {
418  init() ;
419  buildFrom(tux, tuy, tuz) ;
420 }
421 
424  init();
425  buildFrom(q);
426 }
427 
428 
435 {
436  vpRotationMatrix Rt ;
437 
438  unsigned int i,j;
439  for (i=0;i<3;i++)
440  for (j=0;j<3;j++)
441  Rt[j][i] = (*this)[i][j];
442 
443  return Rt;
444 
445 }
446 
453 {
454  vpRotationMatrix Ri = (*this).t() ;
455 
456  return Ri ;
457 }
458 
464 void
466 {
467  M = inverse() ;
468 }
469 
470 
472 VISP_EXPORT std::ostream &operator <<(std::ostream &s,const vpRotationMatrix &R)
473 {
474  for (unsigned int i=0; i<3; i++)
475  {
476  for (unsigned int j=0; j<3; j++)
477  std::cout << R[i][j] << " " ;
478  std::cout << std::endl ;
479  }
480 
481  return (s);
482 }
483 
485 void
487 {
488  vpThetaUVector tu(*this) ;
489 
490  for (unsigned int i=0; i<3; i++)
491  std::cout << tu[i] << " " ;
492 
493  std::cout << std::endl ;
494 }
495 
496 
497 /*
498  \relates vpRotationMatrix
499  Transform a vector vpThetaUVector into a rotation matrix.
500 
501  Representation theta u (angle and axes of the rotation) is considered for
502  the rotation vector.
503 
504  The rotation is computed using :
505  \f[
506  R = \cos{ \theta} \; {I}_{3} + (1 - \cos{ \theta}) \; v v^{T} + \sin{ \theta} \; [v]_\times
507  \f]
508 */
511 {
512  unsigned int i,j;
513  double theta, si, co, sinc, mcosc;
515 
516  theta = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
517  si = sin(theta);
518  co = cos(theta);
519  sinc = vpMath::sinc(si,theta);
520  mcosc = vpMath::mcosc(co,theta);
521 
522  R[0][0] = co + mcosc*v[0]*v[0];
523  R[0][1] = -sinc*v[2] + mcosc*v[0]*v[1];
524  R[0][2] = sinc*v[1] + mcosc*v[0]*v[2];
525  R[1][0] = sinc*v[2] + mcosc*v[1]*v[0];
526  R[1][1] = co + mcosc*v[1]*v[1];
527  R[1][2] = -sinc*v[0] + mcosc*v[1]*v[2];
528  R[2][0] = -sinc*v[1] + mcosc*v[2]*v[0];
529  R[2][1] = sinc*v[0] + mcosc*v[2]*v[1];
530  R[2][2] = co + mcosc*v[2]*v[2];
531 
532  for (i=0;i<3;i++) for (j=0;j<3;j++) (*this)[i][j] = R[i][j];
533 
534 #if (vpDEBUG_LEVEL1) // test new version wrt old version
535  {
536  // old version
537  vpRotationMatrix R_old; // has to be replaced by (*this) if good version
538  double sinu,cosi,mcosi,u[3],ang;
539 
540  ang = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
541  if (ang > minimum)
542  {
543  for (i=0;i<3;i++) u[i] = v[i]/ang;
544  sinu = sin(ang);
545  cosi = cos(ang);
546  mcosi = 1-cosi;
547  R_old[0][0] = cosi + mcosi*u[0]*u[0];
548  R_old[0][1] = -sinu*u[2] + mcosi*u[0]*u[1];
549  R_old[0][2] = sinu*u[1] + mcosi*u[0]*u[2];
550  R_old[1][0] = sinu*u[2] + mcosi*u[1]*u[0];
551  R_old[1][1] = cosi + mcosi*u[1]*u[1];
552  R_old[1][2] = -sinu*u[0] + mcosi*u[1]*u[2];
553  R_old[2][0] = -sinu*u[1] + mcosi*u[2]*u[0];
554  R_old[2][1] = sinu*u[0] + mcosi*u[2]*u[1];
555  R_old[2][2] = cosi + mcosi*u[2]*u[2];
556  }
557  else
558  {
559  for (i=0;i<3;i++)
560  {
561  for(j=0;j<3;j++) R_old[i][j] = 0.0;
562  R_old[i][i] = 1.0;
563  }
564  }
565  // end old version
566  // test the new version
567 
568  unsigned int pb = 0;
569  for (i=0;i<3;i++)
570  {
571  for(j=0;j<3;j++)
572  if (fabs(R_old[i][j] - R[i][j]) > 1.e-4) pb = 1;
573  }
574  if (pb == 1)
575  {
576  printf("vpRotationMatrix::buildFrom(const vpThetaUVector &v)\n");
577  std::cout << " theta " << theta << std::endl;
578  std::cout << " R : " << std::endl << R << std::endl;
579  std::cout << " R_old : " << std::endl << R_old << std::endl;
580  }
581 
582  }
583  // end test
584 #endif
585 
586  return *this ;
587 }
588 
594 {
595  for (unsigned int i=0 ; i < 3 ; i++)
596  for (unsigned int j=0 ; j < 3; j++)
597  (*this)[i][j] = M[i][j] ;
598 
599  return *this ;
600 }
601 
602 /*
603  \relates vpRotationMatrix
604  Transform a pose vector into a rotation matrix.
605 
606  \sa buildFrom(const vpThetaUVector &)
607 */
610 {
611  vpThetaUVector tu(p);
612  return buildFrom(tu);
613 }
614 
623 {
624  double c0,c1,c2,s0,s1,s2;
625 
626  c0 = cos(v[0]);
627  c1 = cos(v[1]);
628  c2 = cos(v[2]);
629  s0 = sin(v[0]);
630  s1 = sin(v[1]);
631  s2 = sin(v[2]);
632 
633  (*this)[0][0] = c0*c1*c2 - s0*s2;
634  (*this)[0][1] = -c0*c1*s2 - s0*c2;
635  (*this)[0][2] = c0*s1;
636  (*this)[1][0] = s0*c1*c2+c0*s2 ;
637  (*this)[1][1] = -s0*c1*s2 + c0*c2 ;
638  (*this)[1][2] = s0*s1;
639  (*this)[2][0] = -s1*c2;
640  (*this)[2][1] = s1*s2;
641  (*this)[2][2] = c1;
642 
643  return (*this) ;
644 }
645 
646 
658 {
659  double c0,c1,c2,s0,s1,s2;
660 
661  c0 = cos(v[0]);
662  c1 = cos(v[1]);
663  c2 = cos(v[2]);
664  s0 = sin(v[0]);
665  s1 = sin(v[1]);
666  s2 = sin(v[2]);
667 
668  (*this)[0][0] = c1*c2;
669  (*this)[0][1] = -c1*s2;
670  (*this)[0][2] = s1;
671  (*this)[1][0] = c0*s2+s0*s1*c2;
672  (*this)[1][1] = c0*c2-s0*s1*s2;
673  (*this)[1][2] = -s0*c1;
674  (*this)[2][0] = -c0*s1*c2+s0*s2;
675  (*this)[2][1] = c0*s1*s2+c2*s0;
676  (*this)[2][2] = c0*c1;
677 
678  return (*this) ;
679 }
680 
681 
682 
692 {
693  double c0,c1,c2,s0,s1,s2;
694 
695  c0 = cos(v[0]);
696  c1 = cos(v[1]);
697  c2 = cos(v[2]);
698  s0 = sin(v[0]);
699  s1 = sin(v[1]);
700  s2 = sin(v[2]);
701 
702  (*this)[0][0] = c0*c1 ;
703  (*this)[0][1] = c0*s1*s2 - s0*c2 ;
704  (*this)[0][2] = c0*s1*c2 + s0*s2 ;
705 
706  (*this)[1][0] = s0*c1 ;
707  (*this)[1][1] = s0*s1*s2 + c0*c2 ;
708  (*this)[1][2] = s0*s1*c2 - c0*s2 ;
709 
710  (*this)[2][0] = -s1 ;
711  (*this)[2][1] = c1*s2 ;
712  (*this)[2][2] = c1*c2 ;
713 
714  return (*this) ;
715 }
716 
717 
718 
722  const double tuy,
723  const double tuz)
724 {
725  vpThetaUVector tu(tux, tuy, tuz) ;
726  buildFrom(tu) ;
727  return *this ;
728 }
729 
730 
734  double a = q.w();
735  double b = q.x();
736  double c = q.y();
737  double d = q.z();
738  (*this)[0][0] = a*a+b*b-c*c-d*d;
739  (*this)[0][1] = 2*b*c-2*a*d;
740  (*this)[0][2] = 2*a*c+2*b*d;
741 
742  (*this)[1][0] = 2*a*d+2*b*c;
743  (*this)[1][1] = a*a-b*b+c*c-d*d;
744  (*this)[1][2] = 2*c*d-2*a*b;
745 
746  (*this)[2][0] = 2*b*d-2*a*c;
747  (*this)[2][1] = 2*a*b+2*c*d;
748  (*this)[2][2] = a*a-b*b-c*c+d*d;
749  return *this;
750 }
751 #undef vpDEBUG_LEVEL1
752 
753 /*
754  * Local variables:
755  * c-basic-offset: 2
756  * End:
757  */
Definition of the vpMatrix class.
Definition: vpMatrix.h:98
void resize(const unsigned int nrows, const unsigned int ncols, const bool nullify=true)
Definition: vpMatrix.cpp:199
vpRotationMatrix inverse() const
invert the rotation matrix
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
#define vpERROR_TRACE
Definition: vpDebug.h:395
error that can be emited by ViSP classes.
Definition: vpException.h:76
double y() const
Returns y-component of the quaternion.
vpRotationMatrix t() const
transpose
Class that consider the case of the Euler angle using the z-y-x convention, where are respectively ...
Definition: vpRzyxVector.h:151
void setIdentity()
Basic initialisation (identity)
vpRotationMatrix operator+(const vpRotationMatrix &B) const
overload + operator (to say it forbidden operation, throw exception)
vpRotationMatrix & operator=(const vpRotationMatrix &R)
copy operator from vpRotationMatrix
static double sinc(double x)
Definition: vpMath.h:301
void init()
Basic initialisation (identity)
bool isARotationMatrix() const
test if the matrix is an rotation matrix
The vpRotationMatrix considers the particular case of a rotation matrix.
double w() const
Returns w-component of the quaternion.
double ** rowPtrs
address of the first element of each rows
Definition: vpMatrix.h:121
static void multMatrixVector(const vpMatrix &A, const vpColVector &b, vpColVector &c)
Definition: vpMatrix.cpp:931
static double mcosc(double cosx, double x)
Definition: vpMath.h:331
vpRotationMatrix buildFrom(const vpHomogeneousMatrix &M)
Build a rotation matrix from an homogeneous matrix.
static double sqr(double x)
Definition: vpMath.h:106
double z() const
Returns z-component of the quaternion.
double x() const
Returns x-component of the quaternion.
Defines a quaternion and its basic operations.
void printVector()
Print the matrix as a vector [T thetaU].
vpRotationMatrix()
Default constructor.
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
The pose is a complete representation of every rigid motion in the euclidian space.
Definition: vpPoseVector.h:92
unsigned int getCols() const
Return the number of columns of the matrix.
Definition: vpMatrix.h:163
vpTranslationVector operator*(const vpTranslationVector &mat) const
operation c = A * b (A is unchanged)
error that can be emited by the vpMatrix class and its derivates
Class that consider the case of the Euler angle using the x-y-z convention, where are respectively ...
Definition: vpRxyzVector.h:152
vpMatrix operator-() const
Definition: vpMatrix.cpp:860
Class that consider the case of the Euler angles using the z-y-z convention, where are respectively...
Definition: vpRzyzVector.h:150
unsigned int getRows() const
Return the number of rows of the matrix.
Definition: vpMatrix.h:161
Class that consider the case of a translation vector.
Class that consider the case of the parameterization for the rotation.