Visual Servoing Platform  version 3.0.0
vpRotationMatrix.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Rotation matrix.
32  *
33  * Authors:
34  * Eric Marchand
35  *
36  *****************************************************************************/
37 
45 #include <visp3/core/vpMath.h>
46 #include <visp3/core/vpMatrix.h>
47 
48 // Rotation classes
49 #include <visp3/core/vpRotationMatrix.h>
50 
51 
52 // Exception
53 #include <visp3/core/vpException.h>
54 
55 // Debug trace
56 #include <visp3/core/vpDebug.h>
57 #include <math.h>
58 const double vpRotationMatrix::threshold = 1e-6;
59 
60 
66 void
68 {
69  eye();
70 }
76 void
78 {
79  for (unsigned int i=0 ; i < 3 ; i++) {
80  for (unsigned int j=0 ; j < 3; j++) {
81  if (i==j)
82  (*this)[i][j] = 1.0;
83  else
84  (*this)[i][j] = 0.0;
85  }
86  }
87 }
88 
100 {
101  for (unsigned int i=0; i<3; i++) {
102  for (unsigned int j=0; j<3; j++) {
103  rowPtrs[i][j] = R.rowPtrs[i][j];
104  }
105  }
106 
107  return *this;
108 }
109 
127 {
128  if ((M.getCols() !=3) &&(M.getRows() !=3)) {
130  "Cannot set a (3x3) rotation matrix from a (%dx%d) matrix",
131  M.getRows(), M.getCols()));
132  }
133 
134  for (unsigned int i=0; i<3; i++) {
135  for (unsigned int j=0; j<3; j++) {
136  (*this)[i][j] = M[i][j];
137  }
138  }
139 
140  if (isARotationMatrix() == false) {
142  "Cannot set a rotation matrix from a matrix that is not a rotation matrix"));
143  }
144 
145  return *this;
146 }
147 
153 {
154  vpRotationMatrix p ;
155 
156  for (unsigned int i=0;i<3;i++) {
157  for (unsigned int j=0;j<3;j++) {
158  double s =0 ;
159  for (unsigned int k=0;k<3;k++)
160  s +=rowPtrs[i][k] * R.rowPtrs[k][j];
161  p[i][j] = s ;
162  }
163  }
164  return p;
165 }
180 vpMatrix
182 {
183  if (M.getRows() != 3 || M.getCols() != 3) {
185  "Cannot set a (3x3) rotation matrix from a (%dx%d) matrix",
186  M.getRows(), M.getCols()));
187  }
188  vpMatrix p(3, 3) ;
189 
190  for (unsigned int i=0;i<3;i++) {
191  for (unsigned int j=0;j<3;j++) {
192  double s =0 ;
193  for (unsigned int k=0;k<3;k++)
194  s +=(*this)[i][k] * M[k][j];
195  p[i][j] = s ;
196  }
197  }
198  return p;
199 }
200 
232 {
233  if (v.getRows() != 3) {
235  "Cannot multiply a (3x3) rotation matrix by a %d dimension column vector",
236  v.getRows()));
237  }
238  vpColVector v_out(3);
239 
240  for (unsigned int j=0;j<colNum;j++) {
241  double vj = v[j] ; // optimization em 5/12/2006
242  for (unsigned int i=0;i<rowNum;i++) {
243  v_out[i] += rowPtrs[i][j] * vj;
244  }
245  }
246 
247  return v_out;
248 }
249 
250 
256 {
258 
259  for (unsigned int j=0;j<3;j++)
260  p[j] = 0;
261 
262  for (unsigned int j=0;j<3;j++) {
263  for (unsigned int i=0;i<3;i++) {
264  p[i] += rowPtrs[i][j] * tv[j];
265  }
266  }
267 
268  return p;
269 }
270 
276 {
278 
279  for (unsigned int i=0;i<rowNum;i++)
280  for(unsigned int j=0;j<colNum;j++)
281  R[i][j]= rowPtrs[i][j]*x;
282 
283  return R;
284 }
285 
291 {
292  for (unsigned int i=0;i<rowNum;i++)
293  for(unsigned int j=0;j<colNum;j++)
294  rowPtrs[i][j]*=x;
295 
296  return *this;
297 }
298 
299 /*********************************************************************/
300 
304 bool
306 {
307  unsigned int i,j ;
308  bool isRotation = true ;
309 
310  // test R^TR = Id ;
311  vpRotationMatrix RtR = (*this).t()*(*this) ;
312  for (i=0 ; i < 3 ; i++) {
313  for (j=0 ; j < 3 ; j++) {
314  if (i==j) {
315  if (fabs(RtR[i][j]-1) > threshold) isRotation = false ;
316  }
317  else {
318  if (fabs(RtR[i][j]) > threshold) isRotation = false ;
319  }
320  }
321  }
322  // test if it is a basis
323  // test || Ci || = 1
324  for (i=0 ; i < 3 ; i++) {
325  if ((sqrt(vpMath::sqr(RtR[0][i]) +
326  vpMath::sqr(RtR[1][i]) +
327  vpMath::sqr(RtR[2][i])) - 1) > threshold) isRotation = false ;
328  }
329 
330  // test || Ri || = 1
331  for (i=0 ; i < 3 ; i++) {
332  if ((sqrt(vpMath::sqr(RtR[i][0]) +
333  vpMath::sqr(RtR[i][1]) +
334  vpMath::sqr(RtR[i][2])) - 1) > threshold) isRotation = false ;
335  }
336 
337  // test if the basis is orthogonal
338  return isRotation ;
339 }
340 
341 
346 {
347  eye();
348 }
349 
350 
355 {
356  (*this) = M ;
357 }
362 {
363  buildFrom(M);
364 }
365 
370 {
371  buildFrom(tu) ;
372 }
373 
378 {
379  buildFrom(p) ;
380 }
381 
386 {
387  buildFrom(euler) ;
388 }
389 
394 {
395  buildFrom(Rxyz) ;
396 }
397 
402 {
403  buildFrom(Rzyx) ;
404 }
405 
409 vpRotationMatrix::vpRotationMatrix(const double tux, const double tuy, const double tuz) : vpArray2D<double>(3,3)
410 {
411  buildFrom(tux, tuy, tuz) ;
412 }
413 
418 {
419  buildFrom(q);
420 }
421 
429 {
430  vpRotationMatrix Rt ;
431 
432  unsigned int i,j;
433  for (i=0;i<3;i++)
434  for (j=0;j<3;j++)
435  Rt[j][i] = (*this)[i][j];
436 
437  return Rt;
438 }
439 
446 {
447  vpRotationMatrix Ri = (*this).t() ;
448 
449  return Ri ;
450 }
451 
469 void
471 {
472  R = inverse();
473 }
474 
478 void
480 {
481  vpThetaUVector tu(*this) ;
482 
483  for (unsigned int i=0; i<3; i++)
484  std::cout << tu[i] << " " ;
485 
486  std::cout << std::endl ;
487 }
488 
489 
500 {
501  unsigned int i,j;
502  double theta, si, co, sinc, mcosc;
504 
505  theta = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
506  si = sin(theta);
507  co = cos(theta);
508  sinc = vpMath::sinc(si,theta);
509  mcosc = vpMath::mcosc(co,theta);
510 
511  R[0][0] = co + mcosc*v[0]*v[0];
512  R[0][1] = -sinc*v[2] + mcosc*v[0]*v[1];
513  R[0][2] = sinc*v[1] + mcosc*v[0]*v[2];
514  R[1][0] = sinc*v[2] + mcosc*v[1]*v[0];
515  R[1][1] = co + mcosc*v[1]*v[1];
516  R[1][2] = -sinc*v[0] + mcosc*v[1]*v[2];
517  R[2][0] = -sinc*v[1] + mcosc*v[2]*v[0];
518  R[2][1] = sinc*v[0] + mcosc*v[2]*v[1];
519  R[2][2] = co + mcosc*v[2]*v[2];
520 
521  for (i=0;i<3;i++) for (j=0;j<3;j++) (*this)[i][j] = R[i][j];
522 
523  return *this ;
524 }
525 
531 {
532  for (unsigned int i=0 ; i < 3 ; i++)
533  for (unsigned int j=0 ; j < 3; j++)
534  (*this)[i][j] = M[i][j] ;
535 
536  return *this ;
537 }
538 
546 {
547  vpThetaUVector tu(p);
548  return buildFrom(tu);
549 }
550 
559 {
560  double c0,c1,c2,s0,s1,s2;
561 
562  c0 = cos(v[0]);
563  c1 = cos(v[1]);
564  c2 = cos(v[2]);
565  s0 = sin(v[0]);
566  s1 = sin(v[1]);
567  s2 = sin(v[2]);
568 
569  (*this)[0][0] = c0*c1*c2 - s0*s2;
570  (*this)[0][1] = -c0*c1*s2 - s0*c2;
571  (*this)[0][2] = c0*s1;
572  (*this)[1][0] = s0*c1*c2+c0*s2 ;
573  (*this)[1][1] = -s0*c1*s2 + c0*c2 ;
574  (*this)[1][2] = s0*s1;
575  (*this)[2][0] = -s1*c2;
576  (*this)[2][1] = s1*s2;
577  (*this)[2][2] = c1;
578 
579  return (*this) ;
580 }
581 
582 
593 {
594  double c0,c1,c2,s0,s1,s2;
595 
596  c0 = cos(v[0]);
597  c1 = cos(v[1]);
598  c2 = cos(v[2]);
599  s0 = sin(v[0]);
600  s1 = sin(v[1]);
601  s2 = sin(v[2]);
602 
603  (*this)[0][0] = c1*c2;
604  (*this)[0][1] = -c1*s2;
605  (*this)[0][2] = s1;
606  (*this)[1][0] = c0*s2+s0*s1*c2;
607  (*this)[1][1] = c0*c2-s0*s1*s2;
608  (*this)[1][2] = -s0*c1;
609  (*this)[2][0] = -c0*s1*c2+s0*s2;
610  (*this)[2][1] = c0*s1*s2+c2*s0;
611  (*this)[2][2] = c0*c1;
612 
613  return (*this) ;
614 }
615 
616 
617 
626 {
627  double c0,c1,c2,s0,s1,s2;
628 
629  c0 = cos(v[0]);
630  c1 = cos(v[1]);
631  c2 = cos(v[2]);
632  s0 = sin(v[0]);
633  s1 = sin(v[1]);
634  s2 = sin(v[2]);
635 
636  (*this)[0][0] = c0*c1 ;
637  (*this)[0][1] = c0*s1*s2 - s0*c2 ;
638  (*this)[0][2] = c0*s1*c2 + s0*s2 ;
639 
640  (*this)[1][0] = s0*c1 ;
641  (*this)[1][1] = s0*s1*s2 + c0*c2 ;
642  (*this)[1][2] = s0*s1*c2 - c0*s2 ;
643 
644  (*this)[2][0] = -s1 ;
645  (*this)[2][1] = c1*s2 ;
646  (*this)[2][2] = c1*c2 ;
647 
648  return (*this) ;
649 }
650 
651 
652 
658  const double tuy,
659  const double tuz)
660 {
661  vpThetaUVector tu(tux, tuy, tuz) ;
662  buildFrom(tu) ;
663  return *this ;
664 }
665 
666 
672  double a = q.w();
673  double b = q.x();
674  double c = q.y();
675  double d = q.z();
676  (*this)[0][0] = a*a+b*b-c*c-d*d;
677  (*this)[0][1] = 2*b*c-2*a*d;
678  (*this)[0][2] = 2*a*c+2*b*d;
679 
680  (*this)[1][0] = 2*a*d+2*b*c;
681  (*this)[1][1] = a*a-b*b+c*c-d*d;
682  (*this)[1][2] = 2*c*d-2*a*b;
683 
684  (*this)[2][0] = 2*b*d-2*a*c;
685  (*this)[2][1] = 2*a*b+2*c*d;
686  (*this)[2][2] = a*a-b*b-c*c+d*d;
687  return *this;
688 }
689 
693 vpRotationMatrix operator*(const double &x,const vpRotationMatrix &R)
694 {
696 
697  unsigned int Rrow = R.getRows() ;
698  unsigned int Rcol = R.getCols() ;
699 
700  for (unsigned int i=0;i<Rrow;i++)
701  for(unsigned int j=0;j<Rcol;j++)
702  C[i][j]= R[i][j]*x;
703 
704  return C ;
705 }
706 
711 {
712  vpThetaUVector tu;
713  tu.buildFrom(*this);
714  return tu;
715 }
716 
745 vpRotationMatrix::getCol(const unsigned int j) const
746 {
747  if (j >= getCols())
749  "Unable to extract a column vector from the homogeneous matrix"));
750  unsigned int nb_rows = getRows();
751  vpColVector c(nb_rows);
752  for (unsigned int i=0 ; i < nb_rows ; i++)
753  c[i] = (*this)[i][j];
754  return c;
755 }
756 
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:92
vpRotationMatrix inverse() const
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpColVector operator*(const double &x, const vpColVector &v)
error that can be emited by ViSP classes.
Definition: vpException.h:73
double y() const
Returns y-component of the quaternion.
vpColVector getCol(const unsigned int j) const
vpRotationMatrix t() const
Implementation of a generic 2D array used as vase class of matrices and vectors.
Definition: vpArray2D.h:70
unsigned int getCols() const
Return the number of columns of the 2D array.
Definition: vpArray2D.h:154
Implementation of a rotation vector as Euler angle minimal representation.
Definition: vpRzyxVector.h:152
vp_deprecated void setIdentity()
vpRotationMatrix & operator=(const vpRotationMatrix &R)
vpThetaUVector buildFrom(const vpHomogeneousMatrix &M)
static double sinc(double x)
Definition: vpMath.cpp:168
bool isARotationMatrix() const
Implementation of a rotation matrix and operations on such kind of matrices.
double w() const
Returns w-component of the quaternion.
unsigned int rowNum
Number of rows in the array.
Definition: vpArray2D.h:74
vpRotationMatrix & operator*=(const double x)
static double mcosc(double cosx, double x)
Definition: vpMath.cpp:137
vpRotationMatrix buildFrom(const vpHomogeneousMatrix &M)
static double sqr(double x)
Definition: vpMath.h:110
double z() const
Returns z-component of the quaternion.
double x() const
Returns x-component of the quaternion.
Implementation of a rotation vector as quaternion angle minimal representation.
unsigned int getRows() const
Return the number of rows of the 2D array.
Definition: vpArray2D.h:152
unsigned int colNum
Number of columns in the array.
Definition: vpArray2D.h:76
vpTranslationVector operator*(const vpTranslationVector &tv) const
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
Implementation of a pose vector and operations on poses.
Definition: vpPoseVector.h:93
Implementation of a rotation vector as Euler angle minimal representation.
Definition: vpRxyzVector.h:154
vpThetaUVector getThetaUVector()
Implementation of a rotation vector as Euler angle minimal representation.
Definition: vpRzyzVector.h:151
Class that consider the case of a translation vector.
Implementation of a rotation vector as axis-angle minimal representation.
double ** rowPtrs
Address of the first element of each rows.
Definition: vpArray2D.h:78