Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpRotationMatrix.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 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 
65 void
67 {
68  for (unsigned int i=0 ; i < 3 ; i++) {
69  for (unsigned int j=0 ; j < 3; j++) {
70  if (i==j)
71  (*this)[i][j] = 1.0;
72  else
73  (*this)[i][j] = 0.0;
74  }
75  }
76 }
77 
89 {
90  for (unsigned int i=0; i<3; i++) {
91  for (unsigned int j=0; j<3; j++) {
92  rowPtrs[i][j] = R.rowPtrs[i][j];
93  }
94  }
95 
96  return *this;
97 }
98 
116 {
117  if ((M.getCols() !=3) &&(M.getRows() !=3)) {
119  "Cannot set a (3x3) rotation matrix from a (%dx%d) matrix",
120  M.getRows(), M.getCols()));
121  }
122 
123  for (unsigned int i=0; i<3; i++) {
124  for (unsigned int j=0; j<3; j++) {
125  (*this)[i][j] = M[i][j];
126  }
127  }
128 
129  if (isARotationMatrix() == false) {
131  "Cannot set a rotation matrix from a matrix that is not a rotation matrix"));
132  }
133 
134  return *this;
135 }
136 
142 {
143  vpRotationMatrix p ;
144 
145  for (unsigned int i=0;i<3;i++) {
146  for (unsigned int j=0;j<3;j++) {
147  double s =0 ;
148  for (unsigned int k=0;k<3;k++)
149  s +=rowPtrs[i][k] * R.rowPtrs[k][j];
150  p[i][j] = s ;
151  }
152  }
153  return p;
154 }
169 vpMatrix
171 {
172  if (M.getRows() != 3 || M.getCols() != 3) {
174  "Cannot set a (3x3) rotation matrix from a (%dx%d) matrix",
175  M.getRows(), M.getCols()));
176  }
177  vpMatrix p(3, 3) ;
178 
179  for (unsigned int i=0;i<3;i++) {
180  for (unsigned int j=0;j<3;j++) {
181  double s =0 ;
182  for (unsigned int k=0;k<3;k++)
183  s +=(*this)[i][k] * M[k][j];
184  p[i][j] = s ;
185  }
186  }
187  return p;
188 }
189 
221 {
222  if (v.getRows() != 3) {
224  "Cannot multiply a (3x3) rotation matrix by a %d dimension column vector",
225  v.getRows()));
226  }
227  vpColVector v_out(3);
228 
229  for (unsigned int j=0;j<colNum;j++) {
230  double vj = v[j] ; // optimization em 5/12/2006
231  for (unsigned int i=0;i<rowNum;i++) {
232  v_out[i] += rowPtrs[i][j] * vj;
233  }
234  }
235 
236  return v_out;
237 }
238 
239 
245 {
247 
248  for (unsigned int j=0;j<3;j++)
249  p[j] = 0;
250 
251  for (unsigned int j=0;j<3;j++) {
252  for (unsigned int i=0;i<3;i++) {
253  p[i] += rowPtrs[i][j] * tv[j];
254  }
255  }
256 
257  return p;
258 }
259 
265 {
267 
268  for (unsigned int i=0;i<rowNum;i++)
269  for(unsigned int j=0;j<colNum;j++)
270  R[i][j]= rowPtrs[i][j]*x;
271 
272  return R;
273 }
274 
280 {
281  for (unsigned int i=0;i<rowNum;i++)
282  for(unsigned int j=0;j<colNum;j++)
283  rowPtrs[i][j]*=x;
284 
285  return *this;
286 }
287 
288 /*********************************************************************/
289 
293 bool
295 {
296  unsigned int i,j ;
297  bool isRotation = true ;
298 
299  // test R^TR = Id ;
300  vpRotationMatrix RtR = (*this).t()*(*this) ;
301  for (i=0 ; i < 3 ; i++) {
302  for (j=0 ; j < 3 ; j++) {
303  if (i==j) {
304  if (fabs(RtR[i][j]-1) > threshold) isRotation = false ;
305  }
306  else {
307  if (fabs(RtR[i][j]) > threshold) isRotation = false ;
308  }
309  }
310  }
311  // test if it is a basis
312  // test || Ci || = 1
313  for (i=0 ; i < 3 ; i++) {
314  if ((sqrt(vpMath::sqr(RtR[0][i]) +
315  vpMath::sqr(RtR[1][i]) +
316  vpMath::sqr(RtR[2][i])) - 1) > threshold) isRotation = false ;
317  }
318 
319  // test || Ri || = 1
320  for (i=0 ; i < 3 ; i++) {
321  if ((sqrt(vpMath::sqr(RtR[i][0]) +
322  vpMath::sqr(RtR[i][1]) +
323  vpMath::sqr(RtR[i][2])) - 1) > threshold) isRotation = false ;
324  }
325 
326  // test if the basis is orthogonal
327  return isRotation ;
328 }
329 
330 
335 {
336  eye();
337 }
338 
339 
344 {
345  (*this) = M ;
346 }
351 {
352  buildFrom(M);
353 }
354 
359 {
360  buildFrom(tu) ;
361 }
362 
367 {
368  buildFrom(p) ;
369 }
370 
375 {
376  buildFrom(euler) ;
377 }
378 
383 {
384  buildFrom(Rxyz) ;
385 }
386 
391 {
392  buildFrom(Rzyx) ;
393 }
394 
398 vpRotationMatrix::vpRotationMatrix(const double tux, const double tuy, const double tuz) : vpArray2D<double>(3,3)
399 {
400  buildFrom(tux, tuy, tuz) ;
401 }
402 
407 {
408  buildFrom(q);
409 }
410 
418 {
419  vpRotationMatrix Rt ;
420 
421  unsigned int i,j;
422  for (i=0;i<3;i++)
423  for (j=0;j<3;j++)
424  Rt[j][i] = (*this)[i][j];
425 
426  return Rt;
427 }
428 
435 {
436  vpRotationMatrix Ri = (*this).t() ;
437 
438  return Ri ;
439 }
440 
458 void
460 {
461  R = inverse();
462 }
463 
467 void
469 {
470  vpThetaUVector tu(*this) ;
471 
472  for (unsigned int i=0; i<3; i++)
473  std::cout << tu[i] << " " ;
474 
475  std::cout << std::endl ;
476 }
477 
478 
489 {
490  unsigned int i,j;
491  double theta, si, co, sinc, mcosc;
493 
494  theta = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
495  si = sin(theta);
496  co = cos(theta);
497  sinc = vpMath::sinc(si,theta);
498  mcosc = vpMath::mcosc(co,theta);
499 
500  R[0][0] = co + mcosc*v[0]*v[0];
501  R[0][1] = -sinc*v[2] + mcosc*v[0]*v[1];
502  R[0][2] = sinc*v[1] + mcosc*v[0]*v[2];
503  R[1][0] = sinc*v[2] + mcosc*v[1]*v[0];
504  R[1][1] = co + mcosc*v[1]*v[1];
505  R[1][2] = -sinc*v[0] + mcosc*v[1]*v[2];
506  R[2][0] = -sinc*v[1] + mcosc*v[2]*v[0];
507  R[2][1] = sinc*v[0] + mcosc*v[2]*v[1];
508  R[2][2] = co + mcosc*v[2]*v[2];
509 
510  for (i=0;i<3;i++) for (j=0;j<3;j++) (*this)[i][j] = R[i][j];
511 
512  return *this ;
513 }
514 
520 {
521  for (unsigned int i=0 ; i < 3 ; i++)
522  for (unsigned int j=0 ; j < 3; j++)
523  (*this)[i][j] = M[i][j] ;
524 
525  return *this ;
526 }
527 
535 {
536  vpThetaUVector tu(p);
537  return buildFrom(tu);
538 }
539 
548 {
549  double c0,c1,c2,s0,s1,s2;
550 
551  c0 = cos(v[0]);
552  c1 = cos(v[1]);
553  c2 = cos(v[2]);
554  s0 = sin(v[0]);
555  s1 = sin(v[1]);
556  s2 = sin(v[2]);
557 
558  (*this)[0][0] = c0*c1*c2 - s0*s2;
559  (*this)[0][1] = -c0*c1*s2 - s0*c2;
560  (*this)[0][2] = c0*s1;
561  (*this)[1][0] = s0*c1*c2+c0*s2 ;
562  (*this)[1][1] = -s0*c1*s2 + c0*c2 ;
563  (*this)[1][2] = s0*s1;
564  (*this)[2][0] = -s1*c2;
565  (*this)[2][1] = s1*s2;
566  (*this)[2][2] = c1;
567 
568  return (*this) ;
569 }
570 
571 
582 {
583  double c0,c1,c2,s0,s1,s2;
584 
585  c0 = cos(v[0]);
586  c1 = cos(v[1]);
587  c2 = cos(v[2]);
588  s0 = sin(v[0]);
589  s1 = sin(v[1]);
590  s2 = sin(v[2]);
591 
592  (*this)[0][0] = c1*c2;
593  (*this)[0][1] = -c1*s2;
594  (*this)[0][2] = s1;
595  (*this)[1][0] = c0*s2+s0*s1*c2;
596  (*this)[1][1] = c0*c2-s0*s1*s2;
597  (*this)[1][2] = -s0*c1;
598  (*this)[2][0] = -c0*s1*c2+s0*s2;
599  (*this)[2][1] = c0*s1*s2+c2*s0;
600  (*this)[2][2] = c0*c1;
601 
602  return (*this) ;
603 }
604 
605 
606 
615 {
616  double c0,c1,c2,s0,s1,s2;
617 
618  c0 = cos(v[0]);
619  c1 = cos(v[1]);
620  c2 = cos(v[2]);
621  s0 = sin(v[0]);
622  s1 = sin(v[1]);
623  s2 = sin(v[2]);
624 
625  (*this)[0][0] = c0*c1 ;
626  (*this)[0][1] = c0*s1*s2 - s0*c2 ;
627  (*this)[0][2] = c0*s1*c2 + s0*s2 ;
628 
629  (*this)[1][0] = s0*c1 ;
630  (*this)[1][1] = s0*s1*s2 + c0*c2 ;
631  (*this)[1][2] = s0*s1*c2 - c0*s2 ;
632 
633  (*this)[2][0] = -s1 ;
634  (*this)[2][1] = c1*s2 ;
635  (*this)[2][2] = c1*c2 ;
636 
637  return (*this) ;
638 }
639 
640 
641 
647  const double tuy,
648  const double tuz)
649 {
650  vpThetaUVector tu(tux, tuy, tuz) ;
651  buildFrom(tu) ;
652  return *this ;
653 }
654 
655 
661  double a = q.w();
662  double b = q.x();
663  double c = q.y();
664  double d = q.z();
665  (*this)[0][0] = a*a+b*b-c*c-d*d;
666  (*this)[0][1] = 2*b*c-2*a*d;
667  (*this)[0][2] = 2*a*c+2*b*d;
668 
669  (*this)[1][0] = 2*a*d+2*b*c;
670  (*this)[1][1] = a*a-b*b+c*c-d*d;
671  (*this)[1][2] = 2*c*d-2*a*b;
672 
673  (*this)[2][0] = 2*b*d-2*a*c;
674  (*this)[2][1] = 2*a*b+2*c*d;
675  (*this)[2][2] = a*a-b*b-c*c+d*d;
676  return *this;
677 }
678 
682 vpRotationMatrix operator*(const double &x,const vpRotationMatrix &R)
683 {
685 
686  unsigned int Rrow = R.getRows() ;
687  unsigned int Rcol = R.getCols() ;
688 
689  for (unsigned int i=0;i<Rrow;i++)
690  for(unsigned int j=0;j<Rcol;j++)
691  C[i][j]= R[i][j]*x;
692 
693  return C ;
694 }
695 
700 {
701  vpThetaUVector tu;
702  tu.buildFrom(*this);
703  return tu;
704 }
705 
734 vpRotationMatrix::getCol(const unsigned int j) const
735 {
736  if (j >= getCols())
738  "Unable to extract a column vector from the homogeneous matrix"));
739  unsigned int nb_rows = getRows();
740  vpColVector c(nb_rows);
741  for (unsigned int i=0 ; i < nb_rows ; i++)
742  c[i] = (*this)[i][j];
743  return c;
744 }
745 
746 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
747 
755 void
757 {
758  eye();
759 }
760 
761 #endif //#if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:97
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:169
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:138
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