Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
vpHomogeneousMatrix.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  * Homogeneous matrix.
32  *
33 *****************************************************************************/
34 
41 #include <visp3/core/vpException.h>
42 #include <visp3/core/vpHomogeneousMatrix.h>
43 #include <visp3/core/vpMatrix.h>
44 #include <visp3/core/vpPoint.h>
45 #include <visp3/core/vpQuaternionVector.h>
46 
53  : vpArray2D<double>(4, 4)
54 {
55  build(t, q);
56  (*this)[3][3] = 1.;
57 }
58 
62 vpHomogeneousMatrix::vpHomogeneousMatrix() : vpArray2D<double>(4, 4), m_index(0) { eye(); }
63 
69 {
70  *this = M;
71 }
72 
78  : vpArray2D<double>(4, 4), m_index(0)
79 {
80  build(t, tu);
81  (*this)[3][3] = 1.;
82 }
83 
89  : vpArray2D<double>(4, 4), m_index(0)
90 {
91  const unsigned int index_3 = 3;
92  insert(R);
93  insert(t);
94  (*this)[index_3][index_3] = 1.;
95 }
96 
101 {
102  const unsigned int index_0 = 0;
103  const unsigned int index_1 = 1;
104  const unsigned int index_2 = 2;
105  const unsigned int index_3 = 3;
106  const unsigned int index_4 = 4;
107  const unsigned int index_5 = 5;
108  build(p[index_0], p[index_1], p[index_2], p[index_3], p[index_4], p[index_5]);
109  (*this)[index_3][index_3] = 1.;
110 }
111 
155 vpHomogeneousMatrix::vpHomogeneousMatrix(const std::vector<float> &v) : vpArray2D<double>(4, 4), m_index(0)
156 {
157  build(v);
158  (*this)[3][3] = 1.;
159 }
160 
161 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
202 vpHomogeneousMatrix::vpHomogeneousMatrix(const std::initializer_list<double> &list)
203  : vpArray2D<double>(4, 4), m_index(0)
204 {
205  if (list.size() == 12) {
206  std::copy(list.begin(), list.end(), data);
207  data[12] = 0.;
208  data[13] = 0.;
209  data[14] = 0.;
210  data[15] = 1.;
211  }
212  else if (list.size() == 16) {
213  std::copy(list.begin(), list.end(), data);
214  for (size_t i = 12; i < 15; ++i) {
215  if (std::fabs(data[i]) > std::numeric_limits<double>::epsilon()) {
217  "Cannot initialize homogeneous matrix. "
218  "List element %d (%f) should be 0.",
219  i, data[i]));
220  }
221  }
222  if (std::fabs(data[15] - 1.) > std::numeric_limits<double>::epsilon()) {
224  "Cannot initialize homogeneous matrix. "
225  "List element 15 (%f) should be 1.",
226  data[15]));
227  }
228  }
229  else {
231  "Cannot initialize homogeneous matrix from a list (%d elements) that has not 12 or 16 elements",
232  list.size()));
233  }
234 
235  if (!isAnHomogeneousMatrix()) {
236  if (isAnHomogeneousMatrix(1e-3)) {
237  const unsigned int index_0 = 0;
238  const unsigned int index_1 = 1;
239  const unsigned int index_2 = 2;
240  const unsigned int index_4 = 4;
241  const unsigned int index_5 = 5;
242  const unsigned int index_6 = 6;
243  const unsigned int index_8 = 8;
244  const unsigned int index_9 = 9;
245  const unsigned int index_10 = 10;
246  // re-orthogonalize rotation matrix since the input is close to a valid rotation matrix
247  vpRotationMatrix R(*this);
248  R.orthogonalize();
249 
250  data[index_0] = R[index_0][index_0];
251  data[index_1] = R[index_0][index_1];
252  data[index_2] = R[index_0][index_2];
253  data[index_4] = R[index_1][index_0];
254  data[index_5] = R[index_1][index_1];
255  data[index_6] = R[index_1][index_2];
256  data[index_8] = R[index_2][index_0];
257  data[index_9] = R[index_2][index_1];
258  data[index_10] = R[index_2][index_2];
259  }
260  else {
261  throw(vpException(
263  "Homogeneous matrix initialization fails since its elements are not valid (rotation part or last row)"));
264  }
265  }
266 }
267 #endif
268 
312 vpHomogeneousMatrix::vpHomogeneousMatrix(const std::vector<double> &v) : vpArray2D<double>(4, 4), m_index(0)
313 {
314  build(v);
315  (*this)[3][3] = 1.;
316 }
317 
323 vpHomogeneousMatrix::vpHomogeneousMatrix(double tx, double ty, double tz, double tux, double tuy, double tuz)
324  : vpArray2D<double>(4, 4), m_index(0)
325 {
326  build(tx, ty, tz, tux, tuy, tuz);
327  (*this)[3][3] = 1.;
328 }
329 
330 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
337 {
338  build(t, tu);
339 }
340 
347 {
348  build(t, R);
349 }
350 
356 {
357  build(p);
358 }
359 
366 {
367  build(t, q);
368 }
369 
376 void vpHomogeneousMatrix::buildFrom(double tx, double ty, double tz, double tux, double tuy, double tuz)
377 {
378  build(tx, ty, tz, tux, tuy, tuz);
379 }
380 
427 void vpHomogeneousMatrix::buildFrom(const std::vector<float> &v)
428 {
429  build(v);
430 }
431 
477 void vpHomogeneousMatrix::buildFrom(const std::vector<double> &v)
478 {
479  build(v);
480 }
481 #endif
482 
488 {
489  insert(tu);
490  insert(t);
491  return *this;
492 }
493 
499 {
500  insert(R);
501  insert(t);
502  return *this;
503 }
504 
509 {
510  const unsigned int index_0 = 0;
511  const unsigned int index_1 = 1;
512  const unsigned int index_2 = 2;
513  const unsigned int index_3 = 3;
514  const unsigned int index_4 = 4;
515  const unsigned int index_5 = 5;
516  vpTranslationVector tv(p[index_0], p[index_1], p[index_2]);
517  vpThetaUVector tu(p[index_3], p[index_4], p[index_5]);
518 
519  insert(tu);
520  insert(tv);
521  return *this;
522 }
523 
529 {
530  insert(t);
531  insert(q);
532  return *this;
533 }
534 
540 vpHomogeneousMatrix &vpHomogeneousMatrix::build(const double &tx, const double &ty, const double &tz, const double &tux, const double &tuy, const double &tuz)
541 {
542  vpRotationMatrix R(tux, tuy, tuz);
543  vpTranslationVector t(tx, ty, tz);
544 
545  insert(R);
546  insert(t);
547  return *this;
548 }
549 
594 vpHomogeneousMatrix &vpHomogeneousMatrix::build(const std::vector<float> &v)
595 {
596  if ((v.size() != 12) && (v.size() != 16)) {
597  throw(vpException(vpException::dimensionError, "Cannot convert std::vector<float> to vpHomogeneousMatrix"));
598  }
599 
600  for (unsigned int i = 0; i < 12; ++i) {
601  this->data[i] = static_cast<double>(v[i]);
602  }
603  return *this;
604 }
605 
650 vpHomogeneousMatrix &vpHomogeneousMatrix::build(const std::vector<double> &v)
651 {
652  if ((v.size() != 12) && (v.size() != 16)) {
653  throw(vpException(vpException::dimensionError, "Cannot convert std::vector<double> to vpHomogeneousMatrix"));
654  }
655 
656  for (unsigned int i = 0; i < 12; ++i) {
657  this->data[i] = v[i];
658  }
659  return *this;
660 }
661 
668 {
669  for (int i = 0; i < 4; ++i) {
670  for (int j = 0; j < 4; ++j) {
671  rowPtrs[i][j] = M.rowPtrs[i][j];
672  }
673  }
674  return *this;
675 }
676 
699 {
701 
702  vpRotationMatrix R1, R2, R;
703  vpTranslationVector T1, T2, T;
704 
705  extract(T1);
706  M.extract(T2);
707 
708  extract(R1);
709  M.extract(R2);
710 
711  R = R1 * R2;
712 
713  T = (R1 * T2) + T1;
714 
715  p.insert(T);
716  p.insert(R);
717 
718  return p;
719 }
720 
743 {
744  (*this) = (*this) * M;
745  return (*this);
746 }
747 
756 {
757  const unsigned int val_4 = 4;
758  if (v.getRows() != val_4) {
760  "Cannot multiply a (4x4) homogeneous matrix by a "
761  "(%dx1) column vector",
762  v.getRows()));
763  }
764  vpColVector p(rowNum);
765 
766  p = 0.0;
767 
768  for (unsigned int j = 0; j < val_4; ++j) {
769  for (unsigned int i = 0; i < val_4; ++i) {
770  p[i] += rowPtrs[i][j] * v[j];
771  }
772  }
773 
774  return p;
775 }
776 
789 {
790  vpPoint aP;
791 
792  vpColVector v(4), v1(4);
793 
794  const unsigned int index_0 = 0;
795  const unsigned int index_1 = 1;
796  const unsigned int index_2 = 2;
797  const unsigned int index_3 = 3;
798 
799  v[index_0] = bP.get_X();
800  v[index_1] = bP.get_Y();
801  v[index_2] = bP.get_Z();
802  v[index_3] = bP.get_W();
803 
804  v1[index_0] = ((*this)[index_0][0] * v[0]) + ((*this)[index_0][1] * v[1]) + ((*this)[index_0][index_2] * v[index_2]) + ((*this)[index_0][index_3] * v[index_3]);
805  v1[index_1] = ((*this)[index_1][0] * v[0]) + ((*this)[index_1][1] * v[1]) + ((*this)[index_1][index_2] * v[index_2]) + ((*this)[index_1][index_3] * v[index_3]);
806  v1[index_2] = ((*this)[index_2][0] * v[0]) + ((*this)[index_2][1] * v[1]) + ((*this)[index_2][index_2] * v[index_2]) + ((*this)[index_2][index_3] * v[index_3]);
807  v1[index_3] = ((*this)[index_3][0] * v[0]) + ((*this)[index_3][1] * v[1]) + ((*this)[index_3][index_2] * v[index_2]) + ((*this)[index_3][index_3] * v[index_3]);
808 
809  v1 /= v1[3];
810 
811  // --comment: v1 equals M multiplied by v
812  aP.set_X(v1[index_0]);
813  aP.set_Y(v1[index_1]);
814  aP.set_Z(v1[index_2]);
815  aP.set_W(v1[index_3]);
816 
817  aP.set_oX(v1[index_0]);
818  aP.set_oY(v1[index_1]);
819  aP.set_oZ(v1[index_2]);
820  aP.set_oW(v1[index_3]);
821 
822  return aP;
823 }
824 
836 {
837  vpTranslationVector t_out;
838  const unsigned int index_0 = 0;
839  const unsigned int index_1 = 1;
840  const unsigned int index_2 = 2;
841  const unsigned int index_3 = 3;
842  t_out[index_0] = (((*this)[index_0][0] * t[0]) + ((*this)[index_0][1] * t[1]) + ((*this)[index_0][index_2] * t[index_2])) + (*this)[index_0][index_3];
843  t_out[index_1] = (((*this)[index_1][0] * t[0]) + ((*this)[index_1][1] * t[1]) + ((*this)[index_1][index_2] * t[index_2])) + (*this)[index_1][index_3];
844  t_out[index_2] = (((*this)[index_2][0] * t[0]) + ((*this)[index_2][1] * t[1]) + ((*this)[index_2][index_2] * t[index_2])) + (*this)[index_2][index_3];
845 
846  return t_out;
847 }
848 
864 {
865  return (vpHomogeneousMatrix((*this).getTranslationVector(), (*this).getRotationMatrix() * R));
866 }
867 
915 {
916  m_index = 0;
917  data[m_index] = val;
918  return *this;
919 }
920 
968 {
969  ++m_index;
970  if (m_index >= size()) {
972  "Cannot set homogenous matrix out of bounds. It has only %d elements while you try to initialize "
973  "with %d elements",
974  size(), m_index + 1));
975  }
976  data[m_index] = val;
977  return *this;
978 }
979 
980 /*********************************************************************/
981 
988 bool vpHomogeneousMatrix::isAnHomogeneousMatrix(double threshold) const
989 {
991  extract(R);
992 
993  const unsigned int index_0 = 0;
994  const unsigned int index_1 = 1;
995  const unsigned int index_2 = 2;
996  const unsigned int index_3 = 3;
997  const double epsilon = std::numeric_limits<double>::epsilon();
998  bool isLastRowOK = vpMath::nul((*this)[index_3][index_0], epsilon) && vpMath::nul((*this)[index_3][index_1], epsilon) &&
999  vpMath::nul((*this)[index_3][index_2], epsilon);
1000  return R.isARotationMatrix(threshold) && isLastRowOK && vpMath::equal((*this)[index_3][index_3], 1.0, epsilon);
1001 }
1002 
1008 {
1009  unsigned int l_size = size();
1010  for (unsigned int i = 0; i < l_size; ++i) {
1011  if (vpMath::isNaN(data[i])) {
1012  return false;
1013  }
1014  }
1015  return true;
1016 }
1017 
1023 {
1024  const unsigned int val_3 = 3;
1025  for (unsigned int i = 0; i < val_3; ++i) {
1026  for (unsigned int j = 0; j < val_3; ++j) {
1027  R[i][j] = (*this)[i][j];
1028  }
1029  }
1030 }
1031 
1036 {
1037  const unsigned int index_0 = 0;
1038  const unsigned int index_1 = 1;
1039  const unsigned int index_2 = 2;
1040  const unsigned int index_3 = 3;
1041  t[index_0] = (*this)[index_0][index_3];
1042  t[index_1] = (*this)[index_1][index_3];
1043  t[index_2] = (*this)[index_2][index_3];
1044 }
1049 {
1050  vpRotationMatrix R;
1051  (*this).extract(R);
1052  tu.build(R);
1053 }
1054 
1059 {
1060  vpRotationMatrix R;
1061  (*this).extract(R);
1062  q.build(R);
1063 }
1064 
1069 {
1070  const unsigned int val_3 = 3;
1071  for (unsigned int i = 0; i < val_3; ++i) {
1072  for (unsigned int j = 0; j < val_3; ++j) {
1073  (*this)[i][j] = R[i][j];
1074  }
1075  }
1076 }
1077 
1085 {
1086  vpRotationMatrix R(tu);
1087  insert(R);
1088 }
1089 
1094 {
1095  const unsigned int index_0 = 0;
1096  const unsigned int index_1 = 1;
1097  const unsigned int index_2 = 2;
1098  const unsigned int index_3 = 3;
1099  (*this)[index_0][index_3] = t[index_0];
1100  (*this)[index_1][index_3] = t[index_1];
1101  (*this)[index_2][index_3] = t[index_2];
1102 }
1103 
1111 
1127 {
1129 
1130  vpRotationMatrix R;
1131  extract(R);
1133  extract(T);
1134 
1135  vpTranslationVector RtT;
1136  RtT = -(R.t() * T);
1137 
1138  Mi.insert(R.t());
1139  Mi.insert(RtT);
1140 
1141  return Mi;
1142 }
1143 
1148 {
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  (*this)[index_0][index_0] = 1;
1154  (*this)[index_1][index_1] = 1;
1155  (*this)[index_2][index_2] = 1;
1156  (*this)[index_3][index_3] = 1;
1157 
1158  (*this)[index_0][index_1] = 0;
1159  (*this)[index_0][index_2] = 0;
1160  (*this)[index_0][index_3] = 0;
1161  (*this)[index_1][index_0] = 0;
1162  (*this)[index_1][index_2] = 0;
1163  (*this)[index_1][index_3] = 0;
1164  (*this)[index_2][index_0] = 0;
1165  (*this)[index_2][index_1] = 0;
1166  (*this)[index_2][index_3] = 0;
1167  (*this)[index_3][index_0] = 0;
1168  (*this)[index_3][index_1] = 0;
1169  (*this)[index_3][index_2] = 0;
1170 }
1171 
1187 
1188 void vpHomogeneousMatrix::save(std::ofstream &f) const
1189 {
1190  if (!f.fail()) {
1191  f << *this;
1192  }
1193  else {
1194  throw(vpException(vpException::ioError, "Cannot save homogeneous matrix: ostream not open"));
1195  }
1196 }
1197 
1198 void vpHomogeneousMatrix::save(const std::string &filename) const
1199 {
1200  std::ofstream f;
1201  f.open(filename.c_str());
1202  save(f);
1203  f.close();
1204 }
1205 
1206 void vpHomogeneousMatrix::load(std::ifstream &f)
1207 {
1208  if (!f.fail()) {
1209  const unsigned int val_4 = 4;
1210  for (unsigned int i = 0; i < val_4; ++i) {
1211  for (unsigned int j = 0; j < val_4; ++j) {
1212  f >> (*this)[i][j];
1213  }
1214  }
1215  }
1216  else {
1217  throw(vpException(vpException::ioError, "Cannot load homogeneous matrix: ifstream not open"));
1218  }
1219 }
1220 
1221 void vpHomogeneousMatrix::load(const std::string &filename)
1222 {
1223  std::ifstream f;
1224  f.open(filename.c_str());
1225  load(f);
1226  f.close();
1227 }
1228 
1233 {
1234  vpRotationMatrix R(*this);
1235  R.orthogonalize();
1236 
1237  const unsigned int index_0 = 0;
1238  const unsigned int index_1 = 1;
1239  const unsigned int index_2 = 2;
1240  const unsigned int index_4 = 4;
1241  const unsigned int index_5 = 5;
1242  const unsigned int index_6 = 6;
1243  const unsigned int index_8 = 8;
1244  const unsigned int index_9 = 9;
1245  const unsigned int index_10 = 10;
1246 
1247  data[index_0] = R[index_0][index_0];
1248  data[index_1] = R[index_0][index_1];
1249  data[index_2] = R[index_0][index_2];
1250  data[index_4] = R[index_1][index_0];
1251  data[index_5] = R[index_1][index_1];
1252  data[index_6] = R[index_1][index_2];
1253  data[index_8] = R[index_2][index_0];
1254  data[index_9] = R[index_2][index_1];
1255  data[index_10] = R[index_2][index_2];
1256 }
1257 
1260 {
1261  vpPoseVector r(*this);
1262  std::cout << r.t();
1263 }
1264 
1269 void vpHomogeneousMatrix::convert(std::vector<float> &M)
1270 {
1271  M.resize(12);
1272  for (unsigned int i = 0; i < 12; ++i) {
1273  M[i] = static_cast<float>(this->data[i]);
1274  }
1275 }
1276 
1281 void vpHomogeneousMatrix::convert(std::vector<double> &M)
1282 {
1283  M.resize(12);
1284  for (unsigned int i = 0; i < 12; ++i) {
1285  M[i] = this->data[i];
1286  }
1287 }
1288 
1293 {
1295  this->extract(tr);
1296  return tr;
1297 }
1298 
1303 {
1304  vpRotationMatrix R;
1305  this->extract(R);
1306  return R;
1307 }
1308 
1314 {
1315  vpThetaUVector tu;
1316  this->extract(tu);
1317  return tu;
1318 }
1319 
1353 {
1354  if (j >= getCols()) {
1355  throw(vpException(vpException::dimensionError, "Unable to extract a column vector from the homogeneous matrix"));
1356  }
1357  unsigned int nb_rows = getRows();
1358  vpColVector c(nb_rows);
1359  for (unsigned int i = 0; i < nb_rows; ++i) {
1360  c[i] = (*this)[i][j];
1361  }
1362  return c;
1363 }
1364 
1371 vpHomogeneousMatrix vpHomogeneousMatrix::compute3d3dTransformation(const std::vector<vpPoint> &p, const std::vector<vpPoint> &q)
1372 {
1373  const double N = static_cast<double>(p.size());
1374 
1375  vpColVector p_bar(3, 0.0);
1376  vpColVector q_bar(3, 0.0);
1377  size_t p_size = p.size();
1378  const unsigned int val_3 = 3;
1379  for (size_t i = 0; i < p_size; ++i) {
1380  for (unsigned int j = 0; j < val_3; ++j) {
1381  p_bar[j] += p.at(i).oP[j];
1382  q_bar[j] += q.at(i).oP[j];
1383  }
1384  }
1385 
1386  for (unsigned int j = 0; j < val_3; ++j) {
1387  p_bar[j] /= N;
1388  q_bar[j] /= N;
1389  }
1390 
1391  vpMatrix pc(static_cast<unsigned int>(p.size()), 3);
1392  vpMatrix qc(static_cast<unsigned int>(q.size()), 3);
1393 
1394  for (unsigned int i = 0; i < static_cast<unsigned int>(p_size); ++i) {
1395  for (unsigned int j = 0; j < val_3; ++j) {
1396  pc[i][j] = p.at(i).oP[j] - p_bar[j];
1397  qc[i][j] = q.at(i).oP[j] - q_bar[j];
1398  }
1399  }
1400 
1401  const vpMatrix pct_qc = pc.t() * qc;
1402  vpMatrix U = pct_qc, V;
1403  vpColVector W;
1404  U.svd(W, V);
1405 
1406  vpMatrix Vt = V.t();
1407  vpMatrix R = U * Vt;
1408  if (R.det() < 0) {
1409  const unsigned int index_0 = 0;
1410  const unsigned int index_1 = 1;
1411  const unsigned int index_2 = 2;
1412  Vt[index_2][index_0] *= -1.;
1413  Vt[index_2][index_1] *= -1.;
1414  Vt[index_2][index_2] *= -1.;
1415 
1416  R = U * Vt;
1417  }
1418 
1419  const vpColVector t = p_bar - (R * q_bar);
1420 
1422 }
1423 
1433 vpHomogeneousMatrix vpHomogeneousMatrix::mean(const std::vector<vpHomogeneousMatrix> &vec_M)
1434 {
1435  vpMatrix meanR(3, 3);
1436  vpColVector meanT(3);
1437  vpRotationMatrix R;
1438  const unsigned int index_0 = 0;
1439  const unsigned int index_1 = 1;
1440  const unsigned int index_2 = 2;
1441  size_t vec_m_size = vec_M.size();
1442  for (size_t i = 0; i < vec_m_size; ++i) {
1443  R = vec_M[i].getRotationMatrix();
1444  meanR += (vpMatrix)R;
1445  meanT += (vpColVector)vec_M[i].getTranslationVector();
1446  }
1447  meanR /= static_cast<double>(vec_M.size());
1448  meanT /= static_cast<double>(vec_M.size());
1449 
1450  // Euclidean mean of the rotation matrix following Moakher's method (SIAM 2002)
1451  vpMatrix M, U, V;
1452  vpColVector sv;
1453  meanR.pseudoInverse(M, sv, 1e-6, U, V);
1454  double det = sv[index_0] * sv[index_1] * sv[index_2];
1455  if (det > 0) {
1456  meanR = U * V.t();
1457  }
1458  else {
1459  vpMatrix D(3, 3);
1460  D = 0.0;
1461  D[index_0][index_0] = 1.0;
1462  D[index_1][index_1] = 1.0;
1463  D[index_2][index_2] = -1.;
1464  meanR = U * D * V.t();
1465  }
1466 
1467  R = meanR;
1468 
1469  vpTranslationVector t(meanT);
1471  return mean;
1472 }
1473 
1474 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
1475 
1483 
1484 #endif //#if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
1485 
1486 #ifdef VISP_HAVE_NLOHMANN_JSON
1487 const std::string vpHomogeneousMatrix::jsonTypeName = "vpHomogeneousMatrix";
1488 #include <visp3/core/vpJsonParsing.h>
1489 void vpHomogeneousMatrix::convert_to_json(nlohmann::json &j) const
1490 {
1491  const vpArray2D<double> *asArray = (vpArray2D<double>*) this;
1492  to_json(j, *asArray);
1494 }
1495 
1496 void vpHomogeneousMatrix::parse_json(const nlohmann::json &j)
1497 {
1498 #ifdef ENABLE_VISP_NAMESPACE
1499  using namespace VISP_NAMESPACE_NAME;
1500 #endif
1501  vpArray2D<double> *asArray = (vpArray2D<double>*) this;
1502  if (j.is_object() && j.contains("type")) { // Specific conversions
1503  const bool converted = convertFromTypeAndBuildFrom<vpHomogeneousMatrix, vpPoseVector>(j, *this);
1504  if (!converted) {
1505  from_json(j, *asArray);
1506  }
1507  }
1508  else { // Generic 2D array conversion
1509  from_json(j, *asArray);
1510  }
1511 
1512  if ((getCols() != 4) && (getRows() != 4)) {
1513  throw vpException(vpException::badValue, "From JSON, tried to read something that is not a 4x4 matrix");
1514  }
1515  if (!isAnHomogeneousMatrix()) {
1516  throw vpException(vpException::badValue, "From JSON read a non homogeneous matrix into a vpHomogeneousMatrix");
1517  }
1518 }
1519 #endif
1520 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 size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:349
vpArray2D< double > t() const
Compute the transpose of the array.
Definition: vpArray2D.h:1163
unsigned int getRows() const
Definition: vpArray2D.h:347
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ ioError
I/O error.
Definition: vpException.h:67
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:73
@ 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.
vpThetaUVector getThetaUVector() const
void load(std::ifstream &f)
friend void from_json(const nlohmann::json &j, vpHomogeneousMatrix &T)
VP_DEPRECATED void setIdentity()
static const std::string jsonTypeName
void print() const
Print the matrix as a pose vector .
vpRotationMatrix getRotationMatrix() const
bool isAnHomogeneousMatrix(double threshold=1e-6) const
static vpHomogeneousMatrix compute3d3dTransformation(const std::vector< vpPoint > &p, const std::vector< vpPoint > &q)
vpHomogeneousMatrix & operator*=(const vpHomogeneousMatrix &M)
vpHomogeneousMatrix & build(const vpTranslationVector &t, const vpRotationMatrix &R)
vpHomogeneousMatrix inverse() const
static vpHomogeneousMatrix mean(const std::vector< vpHomogeneousMatrix > &vec_M)
vpTranslationVector getTranslationVector() const
VP_DEPRECATED void buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
void convert(std::vector< float > &M)
void extract(vpRotationMatrix &R) const
vpColVector getCol(unsigned int j) const
vpHomogeneousMatrix & operator<<(double val)
void insert(const vpRotationMatrix &R)
vpHomogeneousMatrix operator*(const vpHomogeneousMatrix &M) const
void save(std::ofstream &f) const
vpHomogeneousMatrix & operator=(const vpHomogeneousMatrix &M)
friend void to_json(nlohmann::json &j, const vpHomogeneousMatrix &T)
vpHomogeneousMatrix & operator,(double val)
static bool isNaN(double value)
Definition: vpMath.cpp:92
static bool equal(double x, double y, double threshold=0.001)
Definition: vpMath.h:458
static bool nul(double x, double threshold=0.001)
Definition: vpMath.h:449
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
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition: vpPoint.h:79
void set_W(double cW)
Set the point cW coordinate in the camera frame.
Definition: vpPoint.cpp:452
void set_oW(double oW)
Set the point oW coordinate in the object frame.
Definition: vpPoint.cpp:461
double get_Y() const
Get the point cY coordinate in the camera frame.
Definition: vpPoint.cpp:404
void set_oY(double oY)
Set the point oY coordinate in the object frame.
Definition: vpPoint.cpp:457
void set_X(double cX)
Set the point cX coordinate in the camera frame.
Definition: vpPoint.cpp:446
double get_W() const
Get the point cW coordinate in the camera frame.
Definition: vpPoint.cpp:408
void set_Y(double cY)
Set the point cY coordinate in the camera frame.
Definition: vpPoint.cpp:448
double get_Z() const
Get the point cZ coordinate in the camera frame.
Definition: vpPoint.cpp:406
void set_oZ(double oZ)
Set the point oZ coordinate in the object frame.
Definition: vpPoint.cpp:459
void set_Z(double cZ)
Set the point cZ coordinate in the camera frame.
Definition: vpPoint.cpp:450
void set_oX(double oX)
Set the point oX coordinate in the object frame.
Definition: vpPoint.cpp:455
double get_X() const
Get the point cX coordinate in the camera frame.
Definition: vpPoint.cpp:402
Implementation of a pose vector and operations on poses.
Definition: vpPoseVector.h:203
vpRowVector t() const
Implementation of a rotation vector as quaternion angle minimal representation.
vpQuaternionVector & build(const double &qx, const double &qy, const double &qz, const double &qw)
Implementation of a rotation matrix and operations on such kind of matrices.
bool isARotationMatrix(double threshold=1e-6) const
vpRotationMatrix t() const
Implementation of a rotation vector as axis-angle minimal representation.
vpThetaUVector & build(const vpHomogeneousMatrix &M)
Class that consider the case of a translation vector.