40#include <visp3/core/vpException.h>
41#include <visp3/core/vpHomogeneousMatrix.h>
42#include <visp3/core/vpMatrix.h>
43#include <visp3/core/vpPoint.h>
44#include <visp3/core/vpQuaternionVector.h>
47const unsigned int vpHomogeneousMatrix::constr_value_4 = 4;
53 :
vpArray2D<double>(constr_value_4, constr_value_4)
55 const unsigned int index_3 = 3;
57 (*this)[index_3][index_3] = 1.;
81 const unsigned int index_3 = 3;
83 (*this)[index_3][index_3] = 1.;
93 const unsigned int index_3 = 3;
96 (*this)[index_3][index_3] = 1.;
104 const unsigned int index_0 = 0;
105 const unsigned int index_1 = 1;
106 const unsigned int index_2 = 2;
107 const unsigned int index_3 = 3;
108 const unsigned int index_4 = 4;
109 const unsigned int index_5 = 5;
110 buildFrom(p[index_0], p[index_1], p[index_2], p[index_3], p[index_4], p[index_5]);
111 (*this)[index_3][index_3] = 1.;
159 const unsigned int index_3 = 3;
161 (*this)[index_3][index_3] = 1.;
164#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
208 if (list.size() == 12) {
209 std::copy(list.begin(), list.end(), data);
215 else if (list.size() == 16) {
216 std::copy(list.begin(), list.end(), data);
217 for (size_t i = 12; i < 15; ++i) {
218 if (std::fabs(data[i]) > std::numeric_limits<double>::epsilon()) {
219 throw(vpException(vpException::fatalError,
220 "Cannot initialize homogeneous matrix. "
221 "List element %d (%f) should be 0.",
225 if (std::fabs(
data[15] - 1.) > std::numeric_limits<double>::epsilon()) {
227 "Cannot initialize homogeneous matrix. "
228 "List element 15 (%f) should be 1.",
234 "Cannot initialize homogeneous matrix from a list (%d elements) that has not 12 or 16 elements",
238 if (!isAnHomogeneousMatrix()) {
239 if (isAnHomogeneousMatrix(1e-3)) {
241 orthogonalizeRotation();
246 "Homogeneous matrix initialization fails since its elements are not valid (rotation part or last row)"));
297 const unsigned int index_3 = 3;
299 (*this)[index_3][index_3] = 1.;
310 const unsigned int index_3 = 3;
312 (*this)[index_3][index_3] = 1.;
342 const unsigned int index_0 = 0;
343 const unsigned int index_1 = 1;
344 const unsigned int index_2 = 2;
345 const unsigned int index_3 = 3;
346 const unsigned int index_4 = 4;
347 const unsigned int index_5 = 5;
428 const std::size_t val_12 = 12;
429 const std::size_t val_16 = 16;
430 const unsigned int val_12ui = 12, val_16ui = 16;
431 if ((v.size() != val_12) && (v.size() != val_16)) {
435 for (
unsigned int i = 0; i < val_12ui; ++i) {
436 this->
data[i] =
static_cast<double>(v[i]);
439 if (v.size() == val_12) {
446 for (
unsigned int i = val_12ui; i < val_16ui; ++i) {
447 this->
data[i] =
static_cast<double>(v[i]);
459 "Homogeneous matrix initialization failed since its elements are not valid (rotation part or last row)"));
511 const std::size_t val_12 = 12;
512 const std::size_t val_16 = 16;
513 const unsigned int val_12ui = 12, val_16ui = 16;
516 if ((v.size() != val_12) && (v.size() != val_16)) {
520 for (
unsigned int i = 0; i < val_12ui; ++i) {
521 this->
data[i] =
static_cast<double>(v[i]);
524 if (v.size() == val_12) {
531 for (
unsigned int i = val_12ui; i < val_16ui; ++i) {
532 this->
data[i] =
static_cast<double>(v[i]);
544 "Homogeneous matrix initialization fails since its elements are not valid (rotation part or last row)"));
559 for (
int i = 0; i < val_4; ++i) {
560 for (
int j = 0; j < val_4; ++j) {
634 (*this) = (*this) * M;
647 const unsigned int val_4 = 4;
648 if (v.getRows() != val_4) {
650 "Cannot multiply a (4x4) homogeneous matrix by a "
651 "(%dx1) column vector",
658 for (
unsigned int j = 0; j < val_4; ++j) {
659 for (
unsigned int i = 0; i < val_4; ++i) {
684 const unsigned int index_0 = 0;
685 const unsigned int index_1 = 1;
686 const unsigned int index_2 = 2;
687 const unsigned int index_3 = 3;
689 v[index_0] = bP.
get_X();
690 v[index_1] = bP.
get_Y();
691 v[index_2] = bP.
get_Z();
692 v[index_3] = bP.
get_W();
694 v1[index_0] = ((*this)[index_0][index_0] * v[index_0]) + ((*
this)[index_0][index_1] * v[index_1]) + ((*this)[index_0][index_2] * v[index_2]) + ((*
this)[index_0][index_3] * v[index_3]);
695 v1[index_1] = ((*this)[index_1][index_0] * v[index_0]) + ((*
this)[index_1][index_1] * v[index_1]) + ((*this)[index_1][index_2] * v[index_2]) + ((*
this)[index_1][index_3] * v[index_3]);
696 v1[index_2] = ((*this)[index_2][index_0] * v[index_0]) + ((*
this)[index_2][index_1] * v[index_1]) + ((*this)[index_2][index_2] * v[index_2]) + ((*
this)[index_2][index_3] * v[index_3]);
697 v1[index_3] = ((*this)[index_3][index_0] * v[index_0]) + ((*
this)[index_3][index_1] * v[index_1]) + ((*this)[index_3][index_2] * v[index_2]) + ((*
this)[index_3][index_3] * v[index_3]);
702 aP.
set_X(v1[index_0]);
703 aP.
set_Y(v1[index_1]);
704 aP.
set_Z(v1[index_2]);
705 aP.
set_W(v1[index_3]);
728 const unsigned int index_0 = 0;
729 const unsigned int index_1 = 1;
730 const unsigned int index_2 = 2;
731 const unsigned int index_3 = 3;
732 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];
733 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];
734 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];
755 return (
vpHomogeneousMatrix((*this).getTranslationVector(), (*this).getRotationMatrix() * R));
862 "Cannot set homogenous matrix out of bounds. It has only %d elements while you try to initialize "
883 const unsigned int index_0 = 0;
884 const unsigned int index_1 = 1;
885 const unsigned int index_2 = 2;
886 const unsigned int index_3 = 3;
887 const double epsilon = std::numeric_limits<double>::epsilon();
888 bool isLastRowOK =
vpMath::nul((*
this)[index_3][index_0], epsilon) &&
vpMath::nul((*
this)[index_3][index_1], epsilon) &&
890 return R.isARotationMatrix(threshold) && isLastRowOK &&
vpMath::equal((*
this)[index_3][index_3], 1.0, epsilon);
899 unsigned int l_size =
size();
900 for (
unsigned int i = 0; i < l_size; ++i) {
914 const unsigned int val_3 = 3;
915 for (
unsigned int i = 0; i < val_3; ++i) {
916 for (
unsigned int j = 0; j < val_3; ++j) {
917 R[i][j] = (*this)[i][j];
927 const unsigned int index_0 = 0;
928 const unsigned int index_1 = 1;
929 const unsigned int index_2 = 2;
930 const unsigned int index_3 = 3;
931 t[index_0] = (*this)[index_0][index_3];
932 t[index_1] = (*this)[index_1][index_3];
933 t[index_2] = (*this)[index_2][index_3];
960 const unsigned int val_3 = 3;
961 for (
unsigned int i = 0; i < val_3; ++i) {
962 for (
unsigned int j = 0; j < val_3; ++j) {
963 (*this)[i][j] = R[i][j];
985 const unsigned int index_0 = 0;
986 const unsigned int index_1 = 1;
987 const unsigned int index_2 = 2;
988 const unsigned int index_3 = 3;
989 (*this)[index_0][index_3] =
t[index_0];
990 (*this)[index_1][index_3] =
t[index_1];
991 (*this)[index_2][index_3] =
t[index_2];
1039 const unsigned int index_0 = 0;
1040 const unsigned int index_1 = 1;
1041 const unsigned int index_2 = 2;
1042 const unsigned int index_3 = 3;
1043 (*this)[index_0][index_0] = 1;
1044 (*this)[index_1][index_1] = 1;
1045 (*this)[index_2][index_2] = 1;
1046 (*this)[index_3][index_3] = 1;
1048 (*this)[index_0][index_1] = 0;
1049 (*this)[index_0][index_2] = 0;
1050 (*this)[index_0][index_3] = 0;
1051 (*this)[index_1][index_0] = 0;
1052 (*this)[index_1][index_2] = 0;
1053 (*this)[index_1][index_3] = 0;
1054 (*this)[index_2][index_0] = 0;
1055 (*this)[index_2][index_1] = 0;
1056 (*this)[index_2][index_3] = 0;
1057 (*this)[index_3][index_0] = 0;
1058 (*this)[index_3][index_1] = 0;
1059 (*this)[index_3][index_2] = 0;
1091 f.open(filename.c_str());
1099 const unsigned int val_4 = 4;
1100 for (
unsigned int i = 0; i < val_4; ++i) {
1101 for (
unsigned int j = 0; j < val_4; ++j) {
1114 f.open(filename.c_str());
1142 const std::size_t val_12 = 12;
1143 const unsigned int val_12ui = 12;
1145 for (
unsigned int i = 0; i < val_12ui; ++i) {
1146 M[i] =
static_cast<float>(this->
data[i]);
1156 const std::size_t val_12 = 12;
1157 const unsigned int val_12ui = 12;
1159 for (
unsigned int i = 0; i < val_12ui; ++i) {
1160 M[i] = this->
data[i];
1232 unsigned int nb_rows =
getRows();
1234 for (
unsigned int i = 0; i < nb_rows; ++i) {
1235 c[i] = (*this)[i][j];
1248 const double N =
static_cast<double>(p.size());
1252 size_t p_size = p.size();
1253 const unsigned int val_3 = 3;
1254 for (
size_t i = 0; i < p_size; ++i) {
1255 for (
unsigned int j = 0; j < val_3; ++j) {
1256 p_bar[j] += p.at(i).oP[j];
1257 q_bar[j] += q.at(i).oP[j];
1261 for (
unsigned int j = 0; j < val_3; ++j) {
1266 vpMatrix pc(
static_cast<unsigned int>(p.size()), 3);
1267 vpMatrix qc(
static_cast<unsigned int>(q.size()), 3);
1269 for (
unsigned int i = 0; i < static_cast<unsigned int>(p_size); ++i) {
1270 for (
unsigned int j = 0; j < val_3; ++j) {
1271 pc[i][j] = p.at(i).oP[j] - p_bar[j];
1272 qc[i][j] = q.at(i).oP[j] - q_bar[j];
1276 const vpMatrix pct_qc = pc.t() * qc;
1284 const unsigned int index_0 = 0;
1285 const unsigned int index_1 = 1;
1286 const unsigned int index_2 = 2;
1287 Vt[index_2][index_0] *= -1.;
1288 Vt[index_2][index_1] *= -1.;
1289 Vt[index_2][index_2] *= -1.;
1313 const unsigned int index_0 = 0;
1314 const unsigned int index_1 = 1;
1315 const unsigned int index_2 = 2;
1316 size_t vec_m_size = vec_M.size();
1317 for (
size_t i = 0; i < vec_m_size; ++i) {
1318 R = vec_M[i].getRotationMatrix();
1320 meanT +=
static_cast<vpColVector>(vec_M[i].getTranslationVector());
1322 meanR /=
static_cast<double>(vec_M.size());
1323 meanT /=
static_cast<double>(vec_M.size());
1329 double det = sv[index_0] * sv[index_1] * sv[index_2];
1336 D[index_0][index_0] = 1.0;
1337 D[index_1][index_1] = 1.0;
1338 D[index_2][index_2] = -1.;
1339 meanR = U * D * V.
t();
1349#if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
1361#ifdef VISP_HAVE_NLOHMANN_JSON
1363#include <visp3/core/vpJsonParsing.h>
1364void vpHomogeneousMatrix::convert_to_json(nlohmann::json &j)
const
1371void vpHomogeneousMatrix::parse_json(
const nlohmann::json &j)
1373#ifdef ENABLE_VISP_NAMESPACE
1374 using namespace VISP_NAMESPACE_NAME;
1377 if (
j.is_object() &&
j.contains(
"type")) {
1378 const bool converted = convertFromTypeAndBuildFrom<vpHomogeneousMatrix, vpPoseVector>(j, *
this);
1388 throw vpException(
vpException::badValue,
"From JSON, tried to read something that is not a 4x4 matrix");
1391 throw vpException(
vpException::badValue,
"From JSON read a non homogeneous matrix into a vpHomogeneousMatrix");
Implementation of a generic 2D array used as base class for matrices and vectors.
unsigned int getCols() const
unsigned int size() const
vpArray2D< double > t() const
unsigned int getRows() const
Implementation of column vector and the associated operations.
error that can be emitted by ViSP classes.
@ badValue
Used to indicate that a value is not in the allowed range.
@ dimensionError
Bad dimension.
vpThetaUVector getThetaUVector() const
void load(std::ifstream &f)
friend void from_json(const nlohmann::json &j, vpHomogeneousMatrix &T)
VP_DEPRECATED void setIdentity()
void print() const
Print the matrix as a pose vector .
vpRotationMatrix getRotationMatrix() const
bool isAnHomogeneousMatrix(double threshold=1e-6) const
void orthogonalizeRotation()
static vpHomogeneousMatrix compute3d3dTransformation(const std::vector< vpPoint > &p, const std::vector< vpPoint > &q)
vpHomogeneousMatrix & operator*=(const vpHomogeneousMatrix &M)
vpHomogeneousMatrix & buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
vpHomogeneousMatrix inverse() const
static vpHomogeneousMatrix mean(const std::vector< vpHomogeneousMatrix > &vec_M)
vpTranslationVector getTranslationVector() const
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)
static const std::string jsonTypeName
vpHomogeneousMatrix & operator,(double val)
static bool isNaN(double value)
static bool equal(double x, double y, double threshold=0.001)
static bool nul(double x, double threshold=0.001)
Implementation of a matrix and operations on matrices.
void svd(vpColVector &w, vpMatrix &V)
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
void set_W(double cW)
Set the point cW coordinate in the camera frame.
void set_oW(double oW)
Set the point oW coordinate in the object frame.
double get_Y() const
Get the point cY coordinate in the camera frame.
void set_oY(double oY)
Set the point oY coordinate in the object frame.
void set_X(double cX)
Set the point cX coordinate in the camera frame.
double get_W() const
Get the point cW coordinate in the camera frame.
void set_Y(double cY)
Set the point cY coordinate in the camera frame.
double get_Z() const
Get the point cZ coordinate in the camera frame.
void set_oZ(double oZ)
Set the point oZ coordinate in the object frame.
void set_Z(double cZ)
Set the point cZ coordinate in the camera frame.
void set_oX(double oX)
Set the point oX coordinate in the object frame.
double get_X() const
Get the point cX coordinate in the camera frame.
Implementation of a pose vector and operations on poses.
Implementation of a rotation vector as quaternion angle minimal representation.
vpQuaternionVector & buildFrom(const double &qx, const double &qy, const double &qz, const double &qw)
Implementation of a rotation matrix and operations on such kind of matrices.
Implementation of a rotation vector as axis-angle minimal representation.
Class that consider the case of a translation vector.