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>
90 const unsigned int index_3 = 3;
93 (*this)[index_3][index_3] = 1.;
101 const unsigned int index_0 = 0;
102 const unsigned int index_1 = 1;
103 const unsigned int index_2 = 2;
104 const unsigned int index_3 = 3;
105 const unsigned int index_4 = 4;
106 const unsigned int index_5 = 5;
107 buildFrom(p[index_0], p[index_1], p[index_2], p[index_3], p[index_4], p[index_5]);
108 (*this)[index_3][index_3] = 1.;
160 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
204 if (list.size() == 12) {
205 std::copy(list.begin(), list.end(),
data);
211 else if (list.size() == 16) {
212 std::copy(list.begin(), list.end(),
data);
213 for (
size_t i = 12; i < 15; ++i) {
214 if (std::fabs(
data[i]) > std::numeric_limits<double>::epsilon()) {
216 "Cannot initialize homogeneous matrix. "
217 "List element %d (%f) should be 0.",
221 if (std::fabs(
data[15] - 1.) > std::numeric_limits<double>::epsilon()) {
223 "Cannot initialize homogeneous matrix. "
224 "List element 15 (%f) should be 1.",
230 "Cannot initialize homogeneous matrix from a list (%d elements) that has not 12 or 16 elements",
236 const unsigned int index_0 = 0;
237 const unsigned int index_1 = 1;
238 const unsigned int index_2 = 2;
239 const unsigned int index_4 = 4;
240 const unsigned int index_5 = 5;
241 const unsigned int index_6 = 6;
242 const unsigned int index_8 = 8;
243 const unsigned int index_9 = 9;
244 const unsigned int index_10 = 10;
249 data[index_0] = R[index_0][index_0];
250 data[index_1] = R[index_0][index_1];
251 data[index_2] = R[index_0][index_2];
252 data[index_4] = R[index_1][index_0];
253 data[index_5] = R[index_1][index_1];
254 data[index_6] = R[index_1][index_2];
255 data[index_8] = R[index_2][index_0];
256 data[index_9] = R[index_2][index_1];
257 data[index_10] = R[index_2][index_2];
262 "Homogeneous matrix initialization fails since its elements are not valid (rotation part or last row)"));
356 const unsigned int index_0 = 0;
357 const unsigned int index_1 = 1;
358 const unsigned int index_2 = 2;
359 const unsigned int index_3 = 3;
360 const unsigned int index_4 = 4;
361 const unsigned int index_5 = 5;
442 if ((v.size() != 12) && (v.size() != 16)) {
446 for (
unsigned int i = 0; i < 12; ++i) {
447 this->
data[i] =
static_cast<double>(v[i]);
498 if ((v.size() != 12) && (v.size() != 16)) {
502 for (
unsigned int i = 0; i < 12; ++i) {
503 this->
data[i] = v[i];
515 for (
int i = 0; i < 4; ++i) {
516 for (
int j = 0; j < 4; ++j) {
590 (*this) = (*this) * M;
603 const unsigned int val_4 = 4;
606 "Cannot multiply a (4x4) homogeneous matrix by a "
607 "(%dx1) column vector",
614 for (
unsigned int j = 0; j < val_4; ++j) {
615 for (
unsigned int i = 0; i < val_4; ++i) {
640 const unsigned int index_0 = 0;
641 const unsigned int index_1 = 1;
642 const unsigned int index_2 = 2;
643 const unsigned int index_3 = 3;
645 v[index_0] = bP.
get_X();
646 v[index_1] = bP.
get_Y();
647 v[index_2] = bP.
get_Z();
648 v[index_3] = bP.
get_W();
650 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]);
651 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]);
652 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]);
653 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]);
658 aP.
set_X(v1[index_0]);
659 aP.
set_Y(v1[index_1]);
660 aP.
set_Z(v1[index_2]);
661 aP.
set_W(v1[index_3]);
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;
688 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];
689 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];
690 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];
711 return (
vpHomogeneousMatrix((*this).getTranslationVector(), (*this).getRotationMatrix() * R));
818 "Cannot set homogenous matrix out of bounds. It has only %d elements while you try to initialize "
839 const unsigned int index_0 = 0;
840 const unsigned int index_1 = 1;
841 const unsigned int index_2 = 2;
842 const unsigned int index_3 = 3;
843 const double epsilon = std::numeric_limits<double>::epsilon();
844 bool isLastRowOK =
vpMath::nul((*
this)[index_3][index_0], epsilon) &&
vpMath::nul((*
this)[index_3][index_1], epsilon) &&
855 unsigned int l_size =
size();
856 for (
unsigned int i = 0; i < l_size; ++i) {
870 const unsigned int val_3 = 3;
871 for (
unsigned int i = 0; i < val_3; ++i) {
872 for (
unsigned int j = 0; j < val_3; ++j) {
873 R[i][j] = (*this)[i][j];
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 t[index_0] = (*this)[index_0][index_3];
888 t[index_1] = (*this)[index_1][index_3];
889 t[index_2] = (*this)[index_2][index_3];
916 const unsigned int val_3 = 3;
917 for (
unsigned int i = 0; i < val_3; ++i) {
918 for (
unsigned int j = 0; j < val_3; ++j) {
919 (*this)[i][j] = R[i][j];
941 const unsigned int index_0 = 0;
942 const unsigned int index_1 = 1;
943 const unsigned int index_2 = 2;
944 const unsigned int index_3 = 3;
945 (*this)[index_0][index_3] =
t[index_0];
946 (*this)[index_1][index_3] =
t[index_1];
947 (*this)[index_2][index_3] =
t[index_2];
995 const unsigned int index_0 = 0;
996 const unsigned int index_1 = 1;
997 const unsigned int index_2 = 2;
998 const unsigned int index_3 = 3;
999 (*this)[index_0][index_0] = 1;
1000 (*this)[index_1][index_1] = 1;
1001 (*this)[index_2][index_2] = 1;
1002 (*this)[index_3][index_3] = 1;
1004 (*this)[index_0][index_1] = 0;
1005 (*this)[index_0][index_2] = 0;
1006 (*this)[index_0][index_3] = 0;
1007 (*this)[index_1][index_0] = 0;
1008 (*this)[index_1][index_2] = 0;
1009 (*this)[index_1][index_3] = 0;
1010 (*this)[index_2][index_0] = 0;
1011 (*this)[index_2][index_1] = 0;
1012 (*this)[index_2][index_3] = 0;
1013 (*this)[index_3][index_0] = 0;
1014 (*this)[index_3][index_1] = 0;
1015 (*this)[index_3][index_2] = 0;
1047 f.open(filename.c_str());
1055 const unsigned int val_4 = 4;
1056 for (
unsigned int i = 0; i < val_4; ++i) {
1057 for (
unsigned int j = 0; j < val_4; ++j) {
1070 f.open(filename.c_str());
1083 const unsigned int index_0 = 0;
1084 const unsigned int index_1 = 1;
1085 const unsigned int index_2 = 2;
1086 const unsigned int index_4 = 4;
1087 const unsigned int index_5 = 5;
1088 const unsigned int index_6 = 6;
1089 const unsigned int index_8 = 8;
1090 const unsigned int index_9 = 9;
1091 const unsigned int index_10 = 10;
1093 data[index_0] = R[index_0][index_0];
1094 data[index_1] = R[index_0][index_1];
1095 data[index_2] = R[index_0][index_2];
1096 data[index_4] = R[index_1][index_0];
1097 data[index_5] = R[index_1][index_1];
1098 data[index_6] = R[index_1][index_2];
1099 data[index_8] = R[index_2][index_0];
1100 data[index_9] = R[index_2][index_1];
1101 data[index_10] = R[index_2][index_2];
1118 for (
unsigned int i = 0; i < 12; ++i) {
1119 M[i] =
static_cast<float>(this->
data[i]);
1130 for (
unsigned int i = 0; i < 12; ++i) {
1131 M[i] = this->
data[i];
1203 unsigned int nb_rows =
getRows();
1205 for (
unsigned int i = 0; i < nb_rows; ++i) {
1206 c[i] = (*this)[i][j];
1219 const double N =
static_cast<double>(p.size());
1223 size_t p_size = p.size();
1224 const unsigned int val_3 = 3;
1225 for (
size_t i = 0; i < p_size; ++i) {
1226 for (
unsigned int j = 0; j < val_3; ++j) {
1227 p_bar[j] += p.at(i).oP[j];
1228 q_bar[j] += q.at(i).oP[j];
1232 for (
unsigned int j = 0; j < val_3; ++j) {
1237 vpMatrix pc(
static_cast<unsigned int>(p.size()), 3);
1238 vpMatrix qc(
static_cast<unsigned int>(q.size()), 3);
1240 for (
unsigned int i = 0; i < static_cast<unsigned int>(p_size); ++i) {
1241 for (
unsigned int j = 0; j < val_3; ++j) {
1242 pc[i][j] = p.at(i).oP[j] - p_bar[j];
1243 qc[i][j] = q.at(i).oP[j] - q_bar[j];
1255 const unsigned int index_0 = 0;
1256 const unsigned int index_1 = 1;
1257 const unsigned int index_2 = 2;
1258 Vt[index_2][index_0] *= -1.;
1259 Vt[index_2][index_1] *= -1.;
1260 Vt[index_2][index_2] *= -1.;
1284 const unsigned int index_0 = 0;
1285 const unsigned int index_1 = 1;
1286 const unsigned int index_2 = 2;
1287 size_t vec_m_size = vec_M.
size();
1288 for (
size_t i = 0; i < vec_m_size; ++i) {
1289 R = vec_M[i].getRotationMatrix();
1293 meanR /=
static_cast<double>(vec_M.size());
1294 meanT /=
static_cast<double>(vec_M.size());
1300 double det = sv[index_0] * sv[index_1] * sv[index_2];
1307 D[index_0][index_0] = 1.0;
1308 D[index_1][index_1] = 1.0;
1309 D[index_2][index_2] = -1.;
1310 meanR = U * D * V.
t();
1320 #if defined(VISP_BUILD_DEPRECATED_FUNCTIONS)
1328 void vpHomogeneousMatrix::setIdentity() {
eye(); }
1332 #ifdef VISP_HAVE_NLOHMANN_JSON
1334 #include <visp3/core/vpJsonParsing.h>
1335 void vpHomogeneousMatrix::convert_to_json(nlohmann::json &j)
const
1342 void vpHomogeneousMatrix::parse_json(
const nlohmann::json &j)
1344 #ifdef ENABLE_VISP_NAMESPACE
1348 if (j.is_object() && j.contains(
"type")) {
1349 const bool converted = convertFromTypeAndBuildFrom<vpHomogeneousMatrix, vpPoseVector>(j, *
this);
Implementation of a generic 2D array used as base class for matrices and vectors.
unsigned int getCols() const
double * data
Address of the first element of the data array.
double ** rowPtrs
Address of the first element of each rows.
unsigned int rowNum
Number of rows in the array.
unsigned int size() const
Return the number of elements of the 2D array.
vpArray2D< double > t() const
Compute the transpose of the array.
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.
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)
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
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)
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
double det(vpDetMethod method=LU_DECOMPOSITION) 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.
bool isARotationMatrix(double threshold=1e-6) const
vpRotationMatrix t() const
Implementation of a rotation vector as axis-angle minimal representation.
vpThetaUVector & buildFrom(const vpHomogeneousMatrix &M)
Class that consider the case of a translation vector.