Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
vpRotationMatrix.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
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 https://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 
40 #include <visp3/core/vpMath.h>
41 #include <visp3/core/vpMatrix.h>
42 
43 // Rotation classes
44 #include <visp3/core/vpRotationMatrix.h>
45 
46 // Exception
47 #include <visp3/core/vpException.h>
48 
49 // Debug trace
50 #include <math.h>
51 
59 {
60  const unsigned int val_3 = 3;
61  for (unsigned int i = 0; i < val_3; ++i) {
62  for (unsigned int j = 0; j < val_3; ++j) {
63  if (i == j) {
64  (*this)[i][j] = 1.0;
65  }
66  else {
67  (*this)[i][j] = 0.0;
68  }
69  }
70  }
71 }
72 
83 {
84  const unsigned int val_3 = 3;
85  for (unsigned int i = 0; i < val_3; ++i) {
86  for (unsigned int j = 0; j < val_3; ++j) {
87  rowPtrs[i][j] = R.rowPtrs[i][j];
88  }
89  }
90 
91  return *this;
92 }
93 
94 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
122 vpRotationMatrix &vpRotationMatrix::operator=(const std::initializer_list<double> &list)
123 {
124  if (dsize != static_cast<unsigned int>(list.size())) {
126  "Cannot set a 3-by-3 rotation matrix from a %d-elements list of doubles."));
127  }
128 
129  std::copy(list.begin(), list.end(), data);
130 
131  if (!isARotationMatrix()) {
132  if (isARotationMatrix(1e-3)) {
133  orthogonalize();
134  }
135  else {
136  throw(vpException(
138  "Rotation matrix initialization fails since its elements do not represent a valid rotation matrix"));
139  }
140  }
141 
142  return *this;
143 }
144 #endif
145 
163 {
164  if ((M.getCols() != 3) && (M.getRows() != 3)) {
165  throw(vpException(vpException::dimensionError, "Cannot set a (3x3) rotation matrix from a (%dx%d) matrix",
166  M.getRows(), M.getCols()));
167  }
168 
169  const unsigned int val_3 = 3;
170  for (unsigned int i = 0; i < val_3; ++i) {
171  for (unsigned int j = 0; j < val_3; ++j) {
172  (*this)[i][j] = M[i][j];
173  }
174  }
175 
176  if (isARotationMatrix() == false) {
177  throw(vpException(vpException::fatalError, "Cannot set a rotation matrix "
178  "from a matrix that is not a "
179  "rotation matrix"));
180  }
181 
182  return *this;
183 }
184 
217 {
218  m_index = 0;
219  data[m_index] = val;
220  return *this;
221 }
222 
255 {
256  ++m_index;
257  if (m_index >= size()) {
259  "Cannot set rotation matrix out of bounds. It has only %d elements while you try to initialize "
260  "with %d elements",
261  size(), m_index + 1));
262  }
263  data[m_index] = val;
264  return *this;
265 }
266 
271 {
273 
274  const unsigned int val_3 = 3;
275  for (unsigned int i = 0; i < val_3; ++i) {
276  for (unsigned int j = 0; j < val_3; ++j) {
277  double s = 0;
278  for (unsigned int k = 0; k < 3; ++k) {
279  s += rowPtrs[i][k] * R.rowPtrs[k][j];
280  }
281  p[i][j] = s;
282  }
283  }
284  return p;
285 }
286 
305 {
306  if ((M.getRows() != 3) || (M.getCols() != 3)) {
307  throw(vpException(vpException::dimensionError, "Cannot set a (3x3) rotation matrix from a (%dx%d) matrix",
308  M.getRows(), M.getCols()));
309  }
310  vpMatrix p(3, 3);
311 
312  const unsigned int val_3 = 3;
313  for (unsigned int i = 0; i < val_3; ++i) {
314  for (unsigned int j = 0; j < val_3; ++j) {
315  double s = 0;
316  for (unsigned int k = 0; k < 3; ++k) {
317  s += (*this)[i][k] * M[k][j];
318  }
319  p[i][j] = s;
320  }
321  }
322  return p;
323 }
324 
340 {
341  return (vpHomogeneousMatrix(*this * M.getTranslationVector(), *this * M.getRotationMatrix()));
342 }
343 
378 {
379  const unsigned int rows_size = 3;
380  if (v.getRows() != rows_size) {
382  "Cannot multiply a (3x3) rotation matrix by a %d "
383  "dimension column vector",
384  v.getRows()));
385  }
386  vpColVector v_out(3);
387 
388  for (unsigned int j = 0; j < colNum; ++j) {
389  double vj = v[j]; // optimization em 5/12/2006
390  for (unsigned int i = 0; i < rowNum; ++i) {
391  v_out[i] += rowPtrs[i][j] * vj;
392  }
393  }
394 
395  return v_out;
396 }
397 
403 {
405  const unsigned int val_3 = 3;
406 
407  for (unsigned int j = 0; j < val_3; ++j) {
408  p[j] = 0;
409  }
410 
411  for (unsigned int j = 0; j < val_3; ++j) {
412  for (unsigned int i = 0; i < val_3; ++i) {
413  p[i] += rowPtrs[i][j] * tv[j];
414  }
415  }
416 
417  return p;
418 }
419 
425 {
427 
428  for (unsigned int i = 0; i < rowNum; ++i) {
429  for (unsigned int j = 0; j < colNum; ++j) {
430  R[i][j] = rowPtrs[i][j] * x;
431  }
432  }
433 
434  return R;
435 }
436 
442 {
443  for (unsigned int i = 0; i < rowNum; ++i) {
444  for (unsigned int j = 0; j < colNum; ++j) {
445  rowPtrs[i][j] *= x;
446  }
447  }
448 
449  return *this;
450 }
451 
452 /*********************************************************************/
453 
460 bool vpRotationMatrix::isARotationMatrix(double threshold) const
461 {
462  bool isRotation = true;
463 
464  if ((getCols() != 3) || (getRows() != 3)) {
465  return false;
466  }
467 
468  // --comment: test R^TR = Id
469  vpRotationMatrix RtR = (*this).t() * (*this);
470  const unsigned int val_3 = 3;
471  for (unsigned int i = 0; i < val_3; ++i) {
472  for (unsigned int j = 0; j < val_3; ++j) {
473  if (i == j) {
474  if (fabs(RtR[i][j] - 1) > threshold) {
475  isRotation = false;
476  }
477  }
478  else {
479  if (fabs(RtR[i][j]) > threshold) {
480  isRotation = false;
481  }
482  }
483  }
484  }
485  // test if it is a basis
486  // test || Ci || = 1
487  const unsigned int index_2 = 2;
488  for (unsigned int i = 0; i < val_3; ++i) {
489  if ((sqrt(vpMath::sqr(RtR[0][i]) + vpMath::sqr(RtR[1][i]) + vpMath::sqr(RtR[index_2][i])) - 1) > threshold) {
490  isRotation = false;
491  }
492  }
493 
494  // test || Ri || = 1
495  for (unsigned int i = 0; i < val_3; ++i) {
496  if ((sqrt(vpMath::sqr(RtR[i][0]) + vpMath::sqr(RtR[i][1]) + vpMath::sqr(RtR[i][index_2])) - 1) > threshold) {
497  isRotation = false;
498  }
499  }
500 
501  // test if the basis is orthogonal
502  return isRotation;
503 }
504 
508 vpRotationMatrix::vpRotationMatrix() : vpArray2D<double>(3, 3), m_index(0) { eye(); }
509 
514 vpRotationMatrix::vpRotationMatrix(const vpRotationMatrix &M) : vpArray2D<double>(3, 3), m_index(0) { (*this) = M; }
515 
519 vpRotationMatrix::vpRotationMatrix(const vpHomogeneousMatrix &M) : vpArray2D<double>(3, 3), m_index(0) { build(M); }
520 
525 vpRotationMatrix::vpRotationMatrix(const vpThetaUVector &tu) : vpArray2D<double>(3, 3), m_index(0) { build(tu); }
526 
530 vpRotationMatrix::vpRotationMatrix(const vpPoseVector &p) : vpArray2D<double>(3, 3), m_index(0) { build(p); }
531 
536 vpRotationMatrix::vpRotationMatrix(const vpRzyzVector &euler) : vpArray2D<double>(3, 3), m_index(0)
537 {
538  build(euler);
539 }
540 
545 vpRotationMatrix::vpRotationMatrix(const vpRxyzVector &Rxyz) : vpArray2D<double>(3, 3), m_index(0) { build(Rxyz); }
546 
551 vpRotationMatrix::vpRotationMatrix(const vpRzyxVector &Rzyx) : vpArray2D<double>(3, 3), m_index(0) { build(Rzyx); }
552 
556 vpRotationMatrix::vpRotationMatrix(const vpMatrix &R) : vpArray2D<double>(3, 3), m_index(0) { *this = R; }
557 
562 vpRotationMatrix::vpRotationMatrix(double tux, double tuy, double tuz) : vpArray2D<double>(3, 3), m_index(0)
563 {
564  build(tux, tuy, tuz);
565 }
566 
570 vpRotationMatrix::vpRotationMatrix(const vpQuaternionVector &q) : vpArray2D<double>(3, 3), m_index(0) { build(q); }
571 
572 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
598 vpRotationMatrix::vpRotationMatrix(const std::initializer_list<double> &list)
599  : vpArray2D<double>(3, 3, list), m_index(0)
600 {
601  if (!isARotationMatrix()) {
602  if (isARotationMatrix(1e-3)) {
603  orthogonalize();
604  }
605  else {
606  throw(vpException(
608  "Rotation matrix initialization fails since its elements do not represent a valid rotation matrix"));
609  }
610  }
611 }
612 #endif
613 
621 {
622  vpRotationMatrix Rt;
623 
624  const unsigned int val_3 = 3;
625  for (unsigned int i = 0; i < val_3; ++i) {
626  for (unsigned int j = 0; j < val_3; ++j) {
627  Rt[j][i] = (*this)[i][j];
628  }
629  }
630 
631  return Rt;
632 }
633 
641 {
642  vpRotationMatrix Ri = (*this).t();
643 
644  return Ri;
645 }
646 
669 
675 {
676  vpThetaUVector tu(*this);
677 
678  const unsigned int val_3 = 3;
679  for (unsigned int i = 0; i < val_3; ++i) {
680  std::cout << tu[i] << " ";
681  }
682 
683  std::cout << std::endl;
684 }
685 
686 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
698 {
699  build(v);
700  return *this;
701 }
702 
708 {
709  build(M);
710  return *this;
711 }
712 
720 {
721  return build(p);
722 }
723 
733 {
734  build(v);
735  return *this;
736 }
737 
747 {
748  build(v);
749  return *this;
750 }
751 
760 {
761  build(v);
762  return *this;
763 }
764 
770 vpRotationMatrix vpRotationMatrix::buildFrom(double tux, double tuy, double tuz)
771 {
772  build(tux, tuy, tuz);
773  return *this;
774 }
775 
781 {
782  build(q);
783  return *this;
784 }
785 #endif
786 
797 {
798  double theta, si, co, sinc, mcosc;
800 
801  const unsigned int index_0 = 0;
802  const unsigned int index_1 = 1;
803  const unsigned int index_2 = 2;
804  theta = sqrt((v[index_0] * v[index_0]) + (v[index_1] * v[index_1]) + (v[index_2] * v[index_2]));
805  si = sin(theta);
806  co = cos(theta);
807  sinc = vpMath::sinc(si, theta);
808  mcosc = vpMath::mcosc(co, theta);
809 
810  R[index_0][index_0] = co + (mcosc * v[index_0] * v[index_0]);
811  R[index_0][index_1] = (-sinc * v[index_2]) + (mcosc * v[index_0] * v[index_1]);
812  R[index_0][index_2] = (sinc * v[index_1]) + (mcosc * v[index_0] * v[index_2]);
813  R[index_1][index_0] = (sinc * v[index_2]) + (mcosc * v[index_1] * v[index_0]);
814  R[index_1][index_1] = co + (mcosc * v[index_1] * v[index_1]);
815  R[index_1][index_2] = (-sinc * v[index_0]) + (mcosc * v[index_1] * v[index_2]);
816  R[index_2][index_0] = (-sinc * v[index_1]) + (mcosc * v[index_2] * v[index_0]);
817  R[index_2][index_1] = (sinc * v[index_0]) + (mcosc * v[index_2] * v[index_1]);
818  R[index_2][index_2] = co + (mcosc * v[index_2] * v[index_2]);
819 
820  const unsigned int val_3 = 3;
821  for (unsigned int i = 0; i < val_3; ++i) {
822  for (unsigned int j = 0; j < val_3; ++j) {
823  (*this)[i][j] = R[i][j];
824  }
825  }
826 
827  return *this;
828 }
829 
834 {
835  const unsigned int val_3 = 3;
836  for (unsigned int i = 0; i < val_3; ++i) {
837  for (unsigned int j = 0; j < val_3; ++j) {
838  (*this)[i][j] = M[i][j];
839  }
840  }
841 
842  return *this;
843 }
844 
851 {
852  vpThetaUVector tu(p);
853  return build(tu);
854 }
855 
864 {
865  double c0, c1, c2, s0, s1, s2;
866  const unsigned int index_0 = 0;
867  const unsigned int index_1 = 1;
868  const unsigned int index_2 = 2;
869 
870  c0 = cos(v[index_0]);
871  c1 = cos(v[index_1]);
872  c2 = cos(v[index_2]);
873  s0 = sin(v[index_0]);
874  s1 = sin(v[index_1]);
875  s2 = sin(v[index_2]);
876 
877  (*this)[index_0][index_0] = (c0 * c1 * c2) - (s0 * s2);
878  (*this)[index_0][index_1] = (-c0 * c1 * s2) - (s0 * c2);
879  (*this)[index_0][index_2] = c0 * s1;
880  (*this)[index_1][index_0] = (s0 * c1 * c2) + (c0 * s2);
881  (*this)[index_1][index_1] = (-s0 * c1 * s2) + (c0 * c2);
882  (*this)[index_1][index_2] = s0 * s1;
883  (*this)[index_2][index_0] = -s1 * c2;
884  (*this)[index_2][index_1] = s1 * s2;
885  (*this)[index_2][index_2] = c1;
886 
887  return *this;
888 }
889 
899 {
900  double c0, c1, c2, s0, s1, s2;
901  const unsigned int index_0 = 0;
902  const unsigned int index_1 = 1;
903  const unsigned int index_2 = 2;
904 
905  c0 = cos(v[index_0]);
906  c1 = cos(v[index_1]);
907  c2 = cos(v[index_2]);
908  s0 = sin(v[index_0]);
909  s1 = sin(v[index_1]);
910  s2 = sin(v[index_2]);
911 
912  (*this)[index_0][index_0] = c1 * c2;
913  (*this)[index_0][index_1] = -c1 * s2;
914  (*this)[index_0][index_2] = s1;
915  (*this)[index_1][index_0] = (c0 * s2) + (s0 * s1 * c2);
916  (*this)[index_1][index_1] = (c0 * c2) - (s0 * s1 * s2);
917  (*this)[index_1][index_2] = -s0 * c1;
918  (*this)[index_2][index_0] = (-c0 * s1 * c2) + (s0 * s2);
919  (*this)[index_2][index_1] = (c0 * s1 * s2) + (c2 * s0);
920  (*this)[index_2][index_2] = c0 * c1;
921 
922  return *this;
923 }
924 
932 {
933  double c0, c1, c2, s0, s1, s2;
934  const unsigned int index_0 = 0;
935  const unsigned int index_1 = 1;
936  const unsigned int index_2 = 2;
937 
938  c0 = cos(v[index_0]);
939  c1 = cos(v[index_1]);
940  c2 = cos(v[index_2]);
941  s0 = sin(v[index_0]);
942  s1 = sin(v[index_1]);
943  s2 = sin(v[index_2]);
944 
945  (*this)[index_0][index_0] = c0 * c1;
946  (*this)[index_0][index_1] = (c0 * s1 * s2) - (s0 * c2);
947  (*this)[index_0][index_2] = (c0 * s1 * c2) + (s0 * s2);
948 
949  (*this)[index_1][index_0] = s0 * c1;
950  (*this)[index_1][index_1] = (s0 * s1 * s2) + (c0 * c2);
951  (*this)[index_1][index_2] = (s0 * s1 * c2) - (c0 * s2);
952 
953  (*this)[index_2][index_0] = -s1;
954  (*this)[index_2][index_1] = c1 * s2;
955  (*this)[index_2][index_2] = c1 * c2;
956 
957  return *this;
958 }
959 
964 vpRotationMatrix &vpRotationMatrix::build(const double &tux, const double &tuy, const double &tuz)
965 {
966  vpThetaUVector tu(tux, tuy, tuz);
967  build(tu);
968  return *this;
969 }
970 
975 {
976  double a = q.w();
977  double b = q.x();
978  double c = q.y();
979  double d = q.z();
980  const unsigned int index_0 = 0;
981  const unsigned int index_1 = 1;
982  const unsigned int index_2 = 2;
983  (*this)[index_0][index_0] = (((a * a) + (b * b)) - (c * c)) - (d * d);
984  (*this)[index_0][index_1] = (2 * b * c) - (2 * a * d);
985  (*this)[index_0][index_2] = (2 * a * c) + (2 * b * d);
986 
987  (*this)[index_1][index_0] = (2 * a * d) + (2 * b * c);
988  (*this)[index_1][index_1] = (((a * a) - (b * b)) + (c * c)) - (d * d);
989  (*this)[index_1][index_2] = (2 * c * d) - (2 * a * b);
990 
991  (*this)[index_2][index_0] = (2 * b * d) - (2 * a * c);
992  (*this)[index_2][index_1] = (2 * a * b) + (2 * c * d);
993  (*this)[index_2][index_2] = ((a * a) - (b * b) - (c * c)) + (d * d);
994  return *this;
995 }
996 
1002 {
1003  vpThetaUVector tu;
1004  tu.build(*this);
1005  return tu;
1006 }
1007 
1040 {
1041  if (j >= getCols()) {
1042  throw(vpException(vpException::dimensionError, "Unable to extract a column vector from the homogeneous matrix"));
1043  }
1044  unsigned int nb_rows = getRows();
1045  vpColVector c(nb_rows);
1046  for (unsigned int i = 0; i < nb_rows; ++i) {
1047  c[i] = (*this)[i][j];
1048  }
1049  return c;
1050 }
1051 
1061 vpRotationMatrix vpRotationMatrix::mean(const std::vector<vpHomogeneousMatrix> &vec_M)
1062 {
1063  vpMatrix meanR(3, 3);
1064  vpRotationMatrix R;
1065  size_t vec_m_size = vec_M.size();
1066  for (size_t i = 0; i < vec_m_size; ++i) {
1067  R = vec_M[i].getRotationMatrix();
1068  meanR += (vpMatrix)R;
1069  }
1070  meanR /= static_cast<double>(vec_M.size());
1071 
1072  // Euclidean mean of the rotation matrix following Moakher's method (SIAM 2002)
1073  vpMatrix M, U, V;
1074  vpColVector sv;
1075  meanR.pseudoInverse(M, sv, 1e-6, U, V);
1076  const unsigned int index_0 = 0;
1077  const unsigned int index_1 = 1;
1078  const unsigned int index_2 = 2;
1079  double det = sv[index_0] * sv[index_1] * sv[index_2];
1080  if (det > 0) {
1081  meanR = U * V.t();
1082  }
1083  else {
1084  vpMatrix D(3, 3);
1085  D = 0.0;
1086  D[index_0][index_0] = 1.0;
1087  D[index_1][index_1] = 1.0;
1088  D[index_2][index_2] = -1;
1089  meanR = U * D * V.t();
1090  }
1091 
1092  R = meanR;
1093  return R;
1094 }
1095 
1104 vpRotationMatrix vpRotationMatrix::mean(const std::vector<vpRotationMatrix> &vec_R)
1105 {
1106  vpMatrix meanR(3, 3);
1107  vpRotationMatrix R;
1108  size_t vec_r_size = vec_R.size();
1109  for (size_t i = 0; i < vec_r_size; ++i) {
1110  meanR += (vpMatrix)vec_R[i];
1111  }
1112  meanR /= static_cast<double>(vec_R.size());
1113 
1114  // Euclidean mean of the rotation matrix following Moakher's method (SIAM 2002)
1115  vpMatrix M, U, V;
1116  vpColVector sv;
1117  meanR.pseudoInverse(M, sv, 1e-6, U, V);
1118  const unsigned int index_0 = 0;
1119  const unsigned int index_1 = 1;
1120  const unsigned int index_2 = 2;
1121  double det = sv[index_0] * sv[index_1] * sv[index_2];
1122  if (det > 0) {
1123  meanR = U * V.t();
1124  }
1125  else {
1126  vpMatrix D(3, 3);
1127  D = 0.0;
1128  D[index_0][index_0] = 1.0;
1129  D[index_1][index_1] = 1.0;
1130  D[index_2][index_2] = -1;
1131  meanR = U * D * V.t();
1132  }
1133 
1134  R = meanR;
1135  return R;
1136 }
1137 
1142 {
1143  vpMatrix U(*this);
1144  vpColVector w;
1145  vpMatrix V;
1146  U.svd(w, V);
1147  vpMatrix Vt = V.t();
1148  vpMatrix R = U * Vt;
1149  const unsigned int index_0 = 0;
1150  const unsigned int index_1 = 1;
1151  const unsigned int index_2 = 2;
1152  const unsigned int index_3 = 3;
1153  const unsigned int index_4 = 4;
1154  const unsigned int index_5 = 5;
1155  const unsigned int index_6 = 6;
1156  const unsigned int index_7 = 7;
1157  const unsigned int index_8 = 8;
1158 
1159  double det = R.det();
1160  if (det < 0) {
1161  Vt[index_2][index_0] *= -1;
1162  Vt[index_2][index_1] *= -1;
1163  Vt[index_2][index_2] *= -1;
1164 
1165  R = U * Vt;
1166  }
1167 
1168  data[index_0] = R[index_0][index_0];
1169  data[index_1] = R[index_0][index_1];
1170  data[index_2] = R[index_0][index_2];
1171  data[index_3] = R[index_1][index_0];
1172  data[index_4] = R[index_1][index_1];
1173  data[index_5] = R[index_1][index_2];
1174  data[index_6] = R[index_2][index_0];
1175  data[index_7] = R[index_2][index_1];
1176  data[index_8] = R[index_2][index_2];
1177 }
1178 
1179 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
1180 
1189 
1190 #endif //#if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
1191 
1195 vpRotationMatrix operator*(const double &x, const vpRotationMatrix &R)
1196 {
1197  vpRotationMatrix C;
1198 
1199  unsigned int Rrow = R.getRows();
1200  unsigned int Rcol = R.getCols();
1201 
1202  for (unsigned int i = 0; i < Rrow; ++i) {
1203  for (unsigned int j = 0; j < Rcol; ++j) {
1204  C[i][j] = R[i][j] * x;
1205  }
1206  }
1207 
1208  return C;
1209 }
1210 END_VISP_NAMESPACE
Implementation of a generic 2D array used as base class for matrices and vectors.
Definition: vpArray2D.h:145
unsigned int getCols() const
Definition: vpArray2D.h:337
double * data
Address of the first element of the data array.
Definition: vpArray2D.h:148
double ** rowPtrs
Address of the first element of each rows.
Definition: vpArray2D.h:1102
unsigned int rowNum
Number of rows in the array.
Definition: vpArray2D.h:1098
unsigned int dsize
Current array size (rowNum * colNum)
Definition: vpArray2D.h:1104
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:349
unsigned int getRows() const
Definition: vpArray2D.h:347
unsigned int colNum
Number of columns in the array.
Definition: vpArray2D.h:1100
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
vpColVector operator*(const double &x, const vpColVector &v)
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ dimensionError
Bad dimension.
Definition: vpException.h:71
@ fatalError
Fatal error.
Definition: vpException.h:72
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpRotationMatrix getRotationMatrix() const
vpTranslationVector getTranslationVector() const
static double sinc(double x)
Definition: vpMath.cpp:268
static double sqr(double x)
Definition: vpMath.h:203
static double mcosc(double cosx, double x)
Definition: vpMath.cpp:233
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:169
void svd(vpColVector &w, vpMatrix &V)
vpMatrix pseudoInverse(double svThreshold=1e-6) const
double det(vpDetMethod method=LU_DECOMPOSITION) const
Definition: vpMatrix.cpp:1641
vpMatrix t() const
Implementation of a pose vector and operations on poses.
Definition: vpPoseVector.h:203
Implementation of a rotation vector as quaternion angle minimal representation.
const double & z() const
Returns the z-component of the quaternion.
const double & x() const
Returns the x-component of the quaternion.
const double & y() const
Returns the y-component of the quaternion.
const double & w() const
Returns the w-component of the quaternion.
Implementation of a rotation matrix and operations on such kind of matrices.
VP_DEPRECATED void setIdentity()
vpRotationMatrix & build(const vpHomogeneousMatrix &M)
vpRotationMatrix & operator*=(double x)
bool isARotationMatrix(double threshold=1e-6) const
vpRotationMatrix & operator,(double val)
unsigned int m_index
vpColVector getCol(unsigned int j) const
vpThetaUVector getThetaUVector()
vpRotationMatrix & operator<<(double val)
vpRotationMatrix t() const
VP_DEPRECATED vpRotationMatrix buildFrom(const vpHomogeneousMatrix &M)
vpRotationMatrix inverse() const
vpTranslationVector operator*(const vpTranslationVector &tv) const
static vpRotationMatrix mean(const std::vector< vpHomogeneousMatrix > &vec_M)
vpRotationMatrix & operator=(const vpRotationMatrix &R)
Implementation of a rotation vector as Euler angle minimal representation.
Definition: vpRxyzVector.h:183
Implementation of a rotation vector as Euler angle minimal representation.
Definition: vpRzyxVector.h:184
Implementation of a rotation vector as Euler angle minimal representation.
Definition: vpRzyzVector.h:182
Implementation of a rotation vector as axis-angle minimal representation.
vpThetaUVector & build(const vpHomogeneousMatrix &M)
Class that consider the case of a translation vector.