Visual Servoing Platform  version 3.1.0
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 modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Rotation matrix.
33  *
34  * Authors:
35  * Eric Marchand
36  *
37  *****************************************************************************/
38 
45 #include <visp3/core/vpMath.h>
46 #include <visp3/core/vpMatrix.h>
47 
48 // Rotation classes
49 #include <visp3/core/vpRotationMatrix.h>
50 
51 // Exception
52 #include <visp3/core/vpException.h>
53 
54 // Debug trace
55 #include <math.h>
56 #include <visp3/core/vpDebug.h>
57 const double vpRotationMatrix::threshold = 1e-6;
58 
65 {
66  for (unsigned int i = 0; i < 3; i++) {
67  for (unsigned int j = 0; j < 3; j++) {
68  if (i == j)
69  (*this)[i][j] = 1.0;
70  else
71  (*this)[i][j] = 0.0;
72  }
73  }
74 }
75 
86 {
87  for (unsigned int i = 0; i < 3; i++) {
88  for (unsigned int j = 0; j < 3; j++) {
89  rowPtrs[i][j] = R.rowPtrs[i][j];
90  }
91  }
92 
93  return *this;
94 }
95 
113 {
114  if ((M.getCols() != 3) && (M.getRows() != 3)) {
115  throw(vpException(vpException::dimensionError, "Cannot set a (3x3) rotation matrix from a (%dx%d) matrix",
116  M.getRows(), M.getCols()));
117  }
118 
119  for (unsigned int i = 0; i < 3; i++) {
120  for (unsigned int j = 0; j < 3; j++) {
121  (*this)[i][j] = M[i][j];
122  }
123  }
124 
125  if (isARotationMatrix() == false) {
126  throw(vpException(vpException::fatalError, "Cannot set a rotation matrix "
127  "from a matrix that is not a "
128  "rotation matrix"));
129  }
130 
131  return *this;
132 }
133 
138 {
140 
141  for (unsigned int i = 0; i < 3; i++) {
142  for (unsigned int j = 0; j < 3; j++) {
143  double s = 0;
144  for (unsigned int k = 0; k < 3; k++)
145  s += rowPtrs[i][k] * R.rowPtrs[k][j];
146  p[i][j] = s;
147  }
148  }
149  return p;
150 }
166 {
167  if (M.getRows() != 3 || M.getCols() != 3) {
168  throw(vpException(vpException::dimensionError, "Cannot set a (3x3) rotation matrix from a (%dx%d) matrix",
169  M.getRows(), M.getCols()));
170  }
171  vpMatrix p(3, 3);
172 
173  for (unsigned int i = 0; i < 3; i++) {
174  for (unsigned int j = 0; j < 3; j++) {
175  double s = 0;
176  for (unsigned int k = 0; k < 3; k++)
177  s += (*this)[i][k] * M[k][j];
178  p[i][j] = s;
179  }
180  }
181  return p;
182 }
183 
214 {
215  if (v.getRows() != 3) {
217  "Cannot multiply a (3x3) rotation matrix by a %d "
218  "dimension column vector",
219  v.getRows()));
220  }
221  vpColVector v_out(3);
222 
223  for (unsigned int j = 0; j < colNum; j++) {
224  double vj = v[j]; // optimization em 5/12/2006
225  for (unsigned int i = 0; i < rowNum; i++) {
226  v_out[i] += rowPtrs[i][j] * vj;
227  }
228  }
229 
230  return v_out;
231 }
232 
238 {
240 
241  for (unsigned int j = 0; j < 3; j++)
242  p[j] = 0;
243 
244  for (unsigned int j = 0; j < 3; j++) {
245  for (unsigned int i = 0; i < 3; i++) {
246  p[i] += rowPtrs[i][j] * tv[j];
247  }
248  }
249 
250  return p;
251 }
252 
258 {
260 
261  for (unsigned int i = 0; i < rowNum; i++)
262  for (unsigned int j = 0; j < colNum; j++)
263  R[i][j] = rowPtrs[i][j] * x;
264 
265  return R;
266 }
267 
273 {
274  for (unsigned int i = 0; i < rowNum; i++)
275  for (unsigned int j = 0; j < colNum; j++)
276  rowPtrs[i][j] *= x;
277 
278  return *this;
279 }
280 
281 /*********************************************************************/
282 
287 {
288  unsigned int i, j;
289  bool isRotation = true;
290 
291  // test R^TR = Id ;
292  vpRotationMatrix RtR = (*this).t() * (*this);
293  for (i = 0; i < 3; i++) {
294  for (j = 0; j < 3; j++) {
295  if (i == j) {
296  if (fabs(RtR[i][j] - 1) > threshold)
297  isRotation = false;
298  } else {
299  if (fabs(RtR[i][j]) > threshold)
300  isRotation = false;
301  }
302  }
303  }
304  // test if it is a basis
305  // test || Ci || = 1
306  for (i = 0; i < 3; i++) {
307  if ((sqrt(vpMath::sqr(RtR[0][i]) + vpMath::sqr(RtR[1][i]) + vpMath::sqr(RtR[2][i])) - 1) > threshold)
308  isRotation = false;
309  }
310 
311  // test || Ri || = 1
312  for (i = 0; i < 3; i++) {
313  if ((sqrt(vpMath::sqr(RtR[i][0]) + vpMath::sqr(RtR[i][1]) + vpMath::sqr(RtR[i][2])) - 1) > threshold)
314  isRotation = false;
315  }
316 
317  // test if the basis is orthogonal
318  return isRotation;
319 }
320 
325 
330 vpRotationMatrix::vpRotationMatrix(const vpRotationMatrix &M) : vpArray2D<double>(3, 3) { (*this) = M; }
335 
341 
346 
351 vpRotationMatrix::vpRotationMatrix(const vpRzyzVector &euler) : vpArray2D<double>(3, 3) { buildFrom(euler); }
352 
358 
364 
369 vpRotationMatrix::vpRotationMatrix(const double tux, const double tuy, const double tuz) : vpArray2D<double>(3, 3)
370 {
371  buildFrom(tux, tuy, tuz);
372 }
373 
378 
386 {
387  vpRotationMatrix Rt;
388 
389  unsigned int i, j;
390  for (i = 0; i < 3; i++)
391  for (j = 0; j < 3; j++)
392  Rt[j][i] = (*this)[i][j];
393 
394  return Rt;
395 }
396 
404 {
405  vpRotationMatrix Ri = (*this).t();
406 
407  return Ri;
408 }
409 
428 
434 {
435  vpThetaUVector tu(*this);
436 
437  for (unsigned int i = 0; i < 3; i++)
438  std::cout << tu[i] << " ";
439 
440  std::cout << std::endl;
441 }
442 
453 {
454  unsigned int i, j;
455  double theta, si, co, sinc, mcosc;
457 
458  theta = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
459  si = sin(theta);
460  co = cos(theta);
461  sinc = vpMath::sinc(si, theta);
462  mcosc = vpMath::mcosc(co, theta);
463 
464  R[0][0] = co + mcosc * v[0] * v[0];
465  R[0][1] = -sinc * v[2] + mcosc * v[0] * v[1];
466  R[0][2] = sinc * v[1] + mcosc * v[0] * v[2];
467  R[1][0] = sinc * v[2] + mcosc * v[1] * v[0];
468  R[1][1] = co + mcosc * v[1] * v[1];
469  R[1][2] = -sinc * v[0] + mcosc * v[1] * v[2];
470  R[2][0] = -sinc * v[1] + mcosc * v[2] * v[0];
471  R[2][1] = sinc * v[0] + mcosc * v[2] * v[1];
472  R[2][2] = co + mcosc * v[2] * v[2];
473 
474  for (i = 0; i < 3; i++)
475  for (j = 0; j < 3; j++)
476  (*this)[i][j] = R[i][j];
477 
478  return *this;
479 }
480 
485 {
486  for (unsigned int i = 0; i < 3; i++)
487  for (unsigned int j = 0; j < 3; j++)
488  (*this)[i][j] = M[i][j];
489 
490  return *this;
491 }
492 
499 {
500  vpThetaUVector tu(p);
501  return buildFrom(tu);
502 }
503 
512 {
513  double c0, c1, c2, s0, s1, s2;
514 
515  c0 = cos(v[0]);
516  c1 = cos(v[1]);
517  c2 = cos(v[2]);
518  s0 = sin(v[0]);
519  s1 = sin(v[1]);
520  s2 = sin(v[2]);
521 
522  (*this)[0][0] = c0 * c1 * c2 - s0 * s2;
523  (*this)[0][1] = -c0 * c1 * s2 - s0 * c2;
524  (*this)[0][2] = c0 * s1;
525  (*this)[1][0] = s0 * c1 * c2 + c0 * s2;
526  (*this)[1][1] = -s0 * c1 * s2 + c0 * c2;
527  (*this)[1][2] = s0 * s1;
528  (*this)[2][0] = -s1 * c2;
529  (*this)[2][1] = s1 * s2;
530  (*this)[2][2] = c1;
531 
532  return (*this);
533 }
534 
544 {
545  double c0, c1, c2, s0, s1, s2;
546 
547  c0 = cos(v[0]);
548  c1 = cos(v[1]);
549  c2 = cos(v[2]);
550  s0 = sin(v[0]);
551  s1 = sin(v[1]);
552  s2 = sin(v[2]);
553 
554  (*this)[0][0] = c1 * c2;
555  (*this)[0][1] = -c1 * s2;
556  (*this)[0][2] = s1;
557  (*this)[1][0] = c0 * s2 + s0 * s1 * c2;
558  (*this)[1][1] = c0 * c2 - s0 * s1 * s2;
559  (*this)[1][2] = -s0 * c1;
560  (*this)[2][0] = -c0 * s1 * c2 + s0 * s2;
561  (*this)[2][1] = c0 * s1 * s2 + c2 * s0;
562  (*this)[2][2] = c0 * c1;
563 
564  return (*this);
565 }
566 
574 {
575  double c0, c1, c2, s0, s1, s2;
576 
577  c0 = cos(v[0]);
578  c1 = cos(v[1]);
579  c2 = cos(v[2]);
580  s0 = sin(v[0]);
581  s1 = sin(v[1]);
582  s2 = sin(v[2]);
583 
584  (*this)[0][0] = c0 * c1;
585  (*this)[0][1] = c0 * s1 * s2 - s0 * c2;
586  (*this)[0][2] = c0 * s1 * c2 + s0 * s2;
587 
588  (*this)[1][0] = s0 * c1;
589  (*this)[1][1] = s0 * s1 * s2 + c0 * c2;
590  (*this)[1][2] = s0 * s1 * c2 - c0 * s2;
591 
592  (*this)[2][0] = -s1;
593  (*this)[2][1] = c1 * s2;
594  (*this)[2][2] = c1 * c2;
595 
596  return (*this);
597 }
598 
603 vpRotationMatrix vpRotationMatrix::buildFrom(const double tux, const double tuy, const double tuz)
604 {
605  vpThetaUVector tu(tux, tuy, tuz);
606  buildFrom(tu);
607  return *this;
608 }
609 
614 {
615  double a = q.w();
616  double b = q.x();
617  double c = q.y();
618  double d = q.z();
619  (*this)[0][0] = a * a + b * b - c * c - d * d;
620  (*this)[0][1] = 2 * b * c - 2 * a * d;
621  (*this)[0][2] = 2 * a * c + 2 * b * d;
622 
623  (*this)[1][0] = 2 * a * d + 2 * b * c;
624  (*this)[1][1] = a * a - b * b + c * c - d * d;
625  (*this)[1][2] = 2 * c * d - 2 * a * b;
626 
627  (*this)[2][0] = 2 * b * d - 2 * a * c;
628  (*this)[2][1] = 2 * a * b + 2 * c * d;
629  (*this)[2][2] = a * a - b * b - c * c + d * d;
630  return *this;
631 }
632 
636 vpRotationMatrix operator*(const double &x, const vpRotationMatrix &R)
637 {
639 
640  unsigned int Rrow = R.getRows();
641  unsigned int Rcol = R.getCols();
642 
643  for (unsigned int i = 0; i < Rrow; i++)
644  for (unsigned int j = 0; j < Rcol; j++)
645  C[i][j] = R[i][j] * x;
646 
647  return C;
648 }
649 
655 {
656  vpThetaUVector tu;
657  tu.buildFrom(*this);
658  return tu;
659 }
660 
688 vpColVector vpRotationMatrix::getCol(const unsigned int j) const
689 {
690  if (j >= getCols())
691  throw(vpException(vpException::dimensionError, "Unable to extract a column vector from the homogeneous matrix"));
692  unsigned int nb_rows = getRows();
693  vpColVector c(nb_rows);
694  for (unsigned int i = 0; i < nb_rows; i++)
695  c[i] = (*this)[i][j];
696  return c;
697 }
698 
699 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
700 
709 
710 #endif //#if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:104
Implementation of an homogeneous matrix and operations on such kind of matrices.
double z() const
Returns z-component of the quaternion.
error that can be emited by ViSP classes.
Definition: vpException.h:71
unsigned int getRows() const
Definition: vpArray2D.h:156
Implementation of a generic 2D array used as vase class of matrices and vectors.
Definition: vpArray2D.h:70
Implementation of a rotation vector as Euler angle minimal representation.
Definition: vpRzyxVector.h:158
vp_deprecated void setIdentity()
vpRotationMatrix inverse() const
vpRotationMatrix & operator=(const vpRotationMatrix &R)
vpThetaUVector buildFrom(const vpHomogeneousMatrix &M)
vpRotationMatrix t() const
static double sinc(double x)
Definition: vpMath.cpp:170
Implementation of a rotation matrix and operations on such kind of matrices.
unsigned int getCols() const
Definition: vpArray2D.h:146
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:135
vpRotationMatrix buildFrom(const vpHomogeneousMatrix &M)
static double sqr(double x)
Definition: vpMath.h:108
vpColVector getCol(const unsigned int j) const
Implementation of a rotation vector as quaternion angle minimal representation.
double y() const
Returns y-component of the quaternion.
unsigned int colNum
Number of columns in the array.
Definition: vpArray2D.h:76
double x() const
Returns x-component of the quaternion.
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
Implementation of a pose vector and operations on poses.
Definition: vpPoseVector.h:92
Implementation of a rotation vector as Euler angle minimal representation.
Definition: vpRxyzVector.h:156
double w() const
Returns w-component of the quaternion.
vpThetaUVector getThetaUVector()
Implementation of a rotation vector as Euler angle minimal representation.
Definition: vpRzyzVector.h:154
Class that consider the case of a translation vector.
Implementation of a rotation vector as axis-angle minimal representation.
bool isARotationMatrix() const
double ** rowPtrs
Address of the first element of each rows.
Definition: vpArray2D.h:78
vpTranslationVector operator*(const vpTranslationVector &tv) const