From 2f736ded8475fadfbeca0254eff68a5397776eb3 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 12 May 2025 12:12:10 +0200 Subject: [PATCH 1/4] Base: Do not use short int in Matrix4D As discussed in https://forum.freecad.org/viewtopic.php?t=65959 replace short with int. --- src/Base/Matrix.cpp | 36 ++++++++++++++++++------------------ src/Base/Matrix.h | 32 ++++++++++++++++---------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/Base/Matrix.cpp b/src/Base/Matrix.cpp index aa0623b2b7..f6d0936867 100644 --- a/src/Base/Matrix.cpp +++ b/src/Base/Matrix.cpp @@ -277,8 +277,8 @@ void Matrix4D::rotLine(const Vector3d& vec, double fAngle) double fsin {}; // set all entries to "0" - for (short iz = 0; iz < 4; iz++) { - for (short is = 0; is < 4; is++) { + for (int iz = 0; iz < 4; iz++) { + for (int is = 0; is < 4; is++) { clMA.dMtrx4D[iz][is] = 0; clMB.dMtrx4D[iz][is] = 0; clMC.dMtrx4D[iz][is] = 0; @@ -313,8 +313,8 @@ void Matrix4D::rotLine(const Vector3d& vec, double fAngle) clMC.dMtrx4D[2][0] = -fsin * clRotAxis.y; clMC.dMtrx4D[2][1] = fsin * clRotAxis.x; - for (short iz = 0; iz < 3; iz++) { - for (short is = 0; is < 3; is++) { + for (int iz = 0; iz < 3; iz++) { + for (int is = 0; is < 3; is++) { clMRot.dMtrx4D[iz][is] = clMA.dMtrx4D[iz][is] + clMB.dMtrx4D[iz][is] + clMC.dMtrx4D[iz][is]; } @@ -522,14 +522,14 @@ void Matrix4D::inverse() /**** Herausnehmen und Inversion der TranslationsMatrix aus der TransformationMatrix ****/ - for (short iz = 0; iz < 3; iz++) { + for (int iz = 0; iz < 3; iz++) { clInvTrlMat.dMtrx4D[iz][3] = -dMtrx4D[iz][3]; } /**** Herausnehmen und Inversion der RotationsMatrix aus der TransformationMatrix ****/ - for (short iz = 0; iz < 3; iz++) { - for (short is = 0; is < 3; is++) { + for (int iz = 0; iz < 3; iz++) { + for (int is = 0; is < 3; is++) { clInvRotMat.dMtrx4D[iz][is] = dMtrx4D[is][iz]; } } @@ -651,8 +651,8 @@ void Matrix4D::inverseGauss() void Matrix4D::getMatrix(double dMtrx[16]) const { - for (short iz = 0; iz < 4; iz++) { - for (short is = 0; is < 4; is++) { + for (int iz = 0; iz < 4; iz++) { + for (int is = 0; is < 4; is++) { dMtrx[4 * iz + is] = dMtrx4D[iz][is]; } } @@ -660,8 +660,8 @@ void Matrix4D::getMatrix(double dMtrx[16]) const void Matrix4D::setMatrix(const double dMtrx[16]) { - for (short iz = 0; iz < 4; iz++) { - for (short is = 0; is < 4; is++) { + for (int iz = 0; iz < 4; iz++) { + for (int is = 0; is < 4; is++) { dMtrx4D[iz][is] = dMtrx[4 * iz + is]; } } @@ -669,8 +669,8 @@ void Matrix4D::setMatrix(const double dMtrx[16]) void Matrix4D::getGLMatrix(double dMtrx[16]) const { - for (short iz = 0; iz < 4; iz++) { - for (short is = 0; is < 4; is++) { + for (int iz = 0; iz < 4; iz++) { + for (int is = 0; is < 4; is++) { dMtrx[iz + 4 * is] = dMtrx4D[iz][is]; } } @@ -678,8 +678,8 @@ void Matrix4D::getGLMatrix(double dMtrx[16]) const void Matrix4D::setGLMatrix(const double dMtrx[16]) { - for (short iz = 0; iz < 4; iz++) { - for (short is = 0; is < 4; is++) { + for (int iz = 0; iz < 4; iz++) { + for (int is = 0; is < 4; is++) { dMtrx4D[iz][is] = dMtrx[iz + 4 * is]; } } @@ -693,7 +693,7 @@ unsigned long Matrix4D::getMemSpace() void Matrix4D::Print() const { // NOLINTBEGIN - for (short i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { printf("%9.3f %9.3f %9.3f %9.3f\n", dMtrx4D[i][0], dMtrx4D[i][1], @@ -788,8 +788,8 @@ std::string Matrix4D::analyse() const trp.transpose(); trp = trp * sub; bool ortho = true; - for (unsigned short i = 0; i < 4 && ortho; i++) { - for (unsigned short j = 0; j < 4 && ortho; j++) { + for (unsigned int i = 0; i < 4 && ortho; i++) { + for (unsigned int j = 0; j < 4 && ortho; j++) { if (i != j) { if (fabs(trp[i][j]) > eps) { ortho = false; diff --git a/src/Base/Matrix.h b/src/Base/Matrix.h index b177abb0fe..043b9de62e 100644 --- a/src/Base/Matrix.h +++ b/src/Base/Matrix.h @@ -106,13 +106,13 @@ public: /// Comparison inline bool operator==(const Matrix4D& mat) const; /// Index operator - inline double* operator[](unsigned short usNdx); + inline double* operator[](unsigned int usNdx); /// Index operator - inline const double* operator[](unsigned short usNdx) const; + inline const double* operator[](unsigned int usNdx) const; /// Get vector of row - inline Vector3d getRow(unsigned short usNdx) const; + inline Vector3d getRow(unsigned int usNdx) const; /// Get vector of column - inline Vector3d getCol(unsigned short usNdx) const; + inline Vector3d getCol(unsigned int usNdx) const; /// Get vector of diagonal inline Vector3d diagonal() const; /// Get trace of the 3x3 matrix @@ -120,9 +120,9 @@ public: /// Get trace of the 4x4 matrix inline double trace() const; /// Set row to vector - inline void setRow(unsigned short usNdx, const Vector3d& vec); + inline void setRow(unsigned int usNdx, const Vector3d& vec); /// Set column to vector - inline void setCol(unsigned short usNdx, const Vector3d& vec); + inline void setCol(unsigned int usNdx, const Vector3d& vec); /// Set diagonal to vector inline void setDiagonal(const Vector3d& vec); /// Compute the determinant of the matrix @@ -380,8 +380,8 @@ inline void Matrix4D::multVec(const Vector3f& src, Vector3f& dst) const inline Matrix4D Matrix4D::operator*(double scalar) const { Matrix4D matrix; - for (unsigned short i = 0; i < 4; i++) { - for (unsigned short j = 0; j < 4; j++) { + for (unsigned int i = 0; i < 4; i++) { + for (unsigned int j = 0; j < 4; j++) { matrix.dMtrx4D[i][j] = dMtrx4D[i][j] * scalar; } } @@ -392,8 +392,8 @@ inline Matrix4D Matrix4D::operator*(double scalar) const inline Matrix4D& Matrix4D::operator*=(double scalar) { // NOLINTBEGIN - for (unsigned short i = 0; i < 4; i++) { - for (unsigned short j = 0; j < 4; j++) { + for (unsigned int i = 0; i < 4; i++) { + for (unsigned int j = 0; j < 4; j++) { dMtrx4D[i][j] *= scalar; } } @@ -425,22 +425,22 @@ inline Vector3f& operator*=(Vector3f& vec, const Matrix4D& mat) return vec; } -inline double* Matrix4D::operator[](unsigned short usNdx) +inline double* Matrix4D::operator[](unsigned int usNdx) { return dMtrx4D[usNdx]; } -inline const double* Matrix4D::operator[](unsigned short usNdx) const +inline const double* Matrix4D::operator[](unsigned int usNdx) const { return dMtrx4D[usNdx]; } -inline Vector3d Matrix4D::getRow(unsigned short usNdx) const +inline Vector3d Matrix4D::getRow(unsigned int usNdx) const { return Vector3d(dMtrx4D[usNdx][0], dMtrx4D[usNdx][1], dMtrx4D[usNdx][2]); } -inline Vector3d Matrix4D::getCol(unsigned short usNdx) const +inline Vector3d Matrix4D::getCol(unsigned int usNdx) const { return Vector3d(dMtrx4D[0][usNdx], dMtrx4D[1][usNdx], dMtrx4D[2][usNdx]); } @@ -460,14 +460,14 @@ inline double Matrix4D::trace() const return dMtrx4D[0][0] + dMtrx4D[1][1] + dMtrx4D[2][2] + dMtrx4D[3][3]; } -inline void Matrix4D::setRow(unsigned short usNdx, const Vector3d& vec) +inline void Matrix4D::setRow(unsigned int usNdx, const Vector3d& vec) { dMtrx4D[usNdx][0] = vec.x; dMtrx4D[usNdx][1] = vec.y; dMtrx4D[usNdx][2] = vec.z; } -inline void Matrix4D::setCol(unsigned short usNdx, const Vector3d& vec) +inline void Matrix4D::setCol(unsigned int usNdx, const Vector3d& vec) { dMtrx4D[0][usNdx] = vec.x; dMtrx4D[1][usNdx] = vec.y; From 4634e628673e012a415a2289ab896c0415325fca Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 12 May 2025 19:20:55 +0200 Subject: [PATCH 2/4] Base: Use i,j consistently for iterations Matrix4D As discussed in https://forum.freecad.org/viewtopic.php?t=65959 use consistently i,j to iterate over rows and columns --- src/Base/Matrix.cpp | 51 ++++++++++++++++++++--------------------- src/Base/Matrix.h | 56 ++++++++++++++++++++++----------------------- 2 files changed, 53 insertions(+), 54 deletions(-) diff --git a/src/Base/Matrix.cpp b/src/Base/Matrix.cpp index f6d0936867..a619fc7354 100644 --- a/src/Base/Matrix.cpp +++ b/src/Base/Matrix.cpp @@ -277,11 +277,11 @@ void Matrix4D::rotLine(const Vector3d& vec, double fAngle) double fsin {}; // set all entries to "0" - for (int iz = 0; iz < 4; iz++) { - for (int is = 0; is < 4; is++) { - clMA.dMtrx4D[iz][is] = 0; - clMB.dMtrx4D[iz][is] = 0; - clMC.dMtrx4D[iz][is] = 0; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + clMA.dMtrx4D[i][j] = 0; + clMB.dMtrx4D[i][j] = 0; + clMC.dMtrx4D[i][j] = 0; } } @@ -313,10 +313,9 @@ void Matrix4D::rotLine(const Vector3d& vec, double fAngle) clMC.dMtrx4D[2][0] = -fsin * clRotAxis.y; clMC.dMtrx4D[2][1] = fsin * clRotAxis.x; - for (int iz = 0; iz < 3; iz++) { - for (int is = 0; is < 3; is++) { - clMRot.dMtrx4D[iz][is] = - clMA.dMtrx4D[iz][is] + clMB.dMtrx4D[iz][is] + clMC.dMtrx4D[iz][is]; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + clMRot.dMtrx4D[i][j] = clMA.dMtrx4D[i][j] + clMB.dMtrx4D[i][j] + clMC.dMtrx4D[i][j]; } } @@ -522,15 +521,15 @@ void Matrix4D::inverse() /**** Herausnehmen und Inversion der TranslationsMatrix aus der TransformationMatrix ****/ - for (int iz = 0; iz < 3; iz++) { - clInvTrlMat.dMtrx4D[iz][3] = -dMtrx4D[iz][3]; + for (int i = 0; i < 3; i++) { + clInvTrlMat.dMtrx4D[i][3] = -dMtrx4D[i][3]; } /**** Herausnehmen und Inversion der RotationsMatrix aus der TransformationMatrix ****/ - for (int iz = 0; iz < 3; iz++) { - for (int is = 0; is < 3; is++) { - clInvRotMat.dMtrx4D[iz][is] = dMtrx4D[is][iz]; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + clInvRotMat.dMtrx4D[i][j] = dMtrx4D[j][i]; } } @@ -651,36 +650,36 @@ void Matrix4D::inverseGauss() void Matrix4D::getMatrix(double dMtrx[16]) const { - for (int iz = 0; iz < 4; iz++) { - for (int is = 0; is < 4; is++) { - dMtrx[4 * iz + is] = dMtrx4D[iz][is]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + dMtrx[4 * i + j] = dMtrx4D[i][j]; } } } void Matrix4D::setMatrix(const double dMtrx[16]) { - for (int iz = 0; iz < 4; iz++) { - for (int is = 0; is < 4; is++) { - dMtrx4D[iz][is] = dMtrx[4 * iz + is]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + dMtrx4D[i][j] = dMtrx[4 * i + j]; } } } void Matrix4D::getGLMatrix(double dMtrx[16]) const { - for (int iz = 0; iz < 4; iz++) { - for (int is = 0; is < 4; is++) { - dMtrx[iz + 4 * is] = dMtrx4D[iz][is]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + dMtrx[i + 4 * j] = dMtrx4D[i][j]; } } } void Matrix4D::setGLMatrix(const double dMtrx[16]) { - for (int iz = 0; iz < 4; iz++) { - for (int is = 0; is < 4; is++) { - dMtrx4D[iz][is] = dMtrx[iz + 4 * is]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + dMtrx4D[i][j] = dMtrx[i + 4 * j]; } } } diff --git a/src/Base/Matrix.h b/src/Base/Matrix.h index 043b9de62e..41a9d52df2 100644 --- a/src/Base/Matrix.h +++ b/src/Base/Matrix.h @@ -241,9 +241,9 @@ inline Matrix4D Matrix4D::operator+(const Matrix4D& mat) const { Matrix4D clMat; - for (int iz = 0; iz < 4; iz++) { - for (int is = 0; is < 4; is++) { - clMat.dMtrx4D[iz][is] = dMtrx4D[iz][is] + mat[iz][is]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + clMat.dMtrx4D[i][j] = dMtrx4D[i][j] + mat[i][j]; } } @@ -252,9 +252,9 @@ inline Matrix4D Matrix4D::operator+(const Matrix4D& mat) const inline Matrix4D& Matrix4D::operator+=(const Matrix4D& mat) { - for (int iz = 0; iz < 4; iz++) { - for (int is = 0; is < 4; is++) { - dMtrx4D[iz][is] += mat[iz][is]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + dMtrx4D[i][j] += mat[i][j]; } } @@ -265,9 +265,9 @@ inline Matrix4D Matrix4D::operator-(const Matrix4D& mat) const { Matrix4D clMat; - for (int iz = 0; iz < 4; iz++) { - for (int is = 0; is < 4; is++) { - clMat.dMtrx4D[iz][is] = dMtrx4D[iz][is] - mat[iz][is]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + clMat.dMtrx4D[i][j] = dMtrx4D[i][j] - mat[i][j]; } } @@ -276,9 +276,9 @@ inline Matrix4D Matrix4D::operator-(const Matrix4D& mat) const inline Matrix4D& Matrix4D::operator-=(const Matrix4D& mat) { - for (int iz = 0; iz < 4; iz++) { - for (int is = 0; is < 4; is++) { - dMtrx4D[iz][is] -= mat[iz][is]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + dMtrx4D[i][j] -= mat[i][j]; } } @@ -289,11 +289,11 @@ inline Matrix4D& Matrix4D::operator*=(const Matrix4D& mat) { Matrix4D clMat; - for (int iz = 0; iz < 4; iz++) { - for (int is = 0; is < 4; is++) { - clMat.dMtrx4D[iz][is] = 0; - for (int ie = 0; ie < 4; ie++) { - clMat.dMtrx4D[iz][is] += dMtrx4D[iz][ie] * mat.dMtrx4D[ie][is]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + clMat.dMtrx4D[i][j] = 0; + for (int e = 0; e < 4; e++) { + clMat.dMtrx4D[i][j] += dMtrx4D[i][e] * mat.dMtrx4D[e][j]; } } } @@ -307,11 +307,11 @@ inline Matrix4D Matrix4D::operator*(const Matrix4D& mat) const { Matrix4D clMat; - for (int iz = 0; iz < 4; iz++) { - for (int is = 0; is < 4; is++) { - clMat.dMtrx4D[iz][is] = 0; - for (int ie = 0; ie < 4; ie++) { - clMat.dMtrx4D[iz][is] += dMtrx4D[iz][ie] * mat.dMtrx4D[ie][is]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + clMat.dMtrx4D[i][j] = 0; + for (int e = 0; e < 4; e++) { + clMat.dMtrx4D[i][j] += dMtrx4D[i][e] * mat.dMtrx4D[e][j]; } } } @@ -325,9 +325,9 @@ inline Matrix4D& Matrix4D::operator=(const Matrix4D& mat) return *this; } - for (int iz = 0; iz < 4; iz++) { - for (int is = 0; is < 4; is++) { - dMtrx4D[iz][is] = mat.dMtrx4D[iz][is]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + dMtrx4D[i][j] = mat.dMtrx4D[i][j]; } } @@ -403,9 +403,9 @@ inline Matrix4D& Matrix4D::operator*=(double scalar) inline bool Matrix4D::operator==(const Matrix4D& mat) const { - for (int iz = 0; iz < 4; iz++) { - for (int is = 0; is < 4; is++) { - if (fabs(dMtrx4D[iz][is] - mat.dMtrx4D[iz][is]) > traits_type::epsilon()) { + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + if (fabs(dMtrx4D[i][j] - mat.dMtrx4D[i][j]) > traits_type::epsilon()) { return false; } } From 74a22df884f1fc440bf6bde65c91a98f4a4c2020 Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 13 May 2025 13:07:44 +0200 Subject: [PATCH 3/4] Base: Simplify Base::Matrix4D As discussed in https://forum.freecad.org/viewtopic.php?t=65959 reduce code duplications --- src/Base/Matrix.cpp | 12 +-- src/Base/Matrix.h | 67 ++++----------- tests/src/Base/Matrix.cpp | 172 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+), 61 deletions(-) diff --git a/src/Base/Matrix.cpp b/src/Base/Matrix.cpp index a619fc7354..8bd35ec1ab 100644 --- a/src/Base/Matrix.cpp +++ b/src/Base/Matrix.cpp @@ -277,13 +277,9 @@ void Matrix4D::rotLine(const Vector3d& vec, double fAngle) double fsin {}; // set all entries to "0" - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - clMA.dMtrx4D[i][j] = 0; - clMB.dMtrx4D[i][j] = 0; - clMC.dMtrx4D[i][j] = 0; - } - } + clMA.nullify(); + clMB.nullify(); + clMC.nullify(); // ** normalize the rotation axis clRotAxis.Normalize(); @@ -623,7 +619,7 @@ void Matrix4D::inverseOrthogonal() { Base::Vector3d vec(dMtrx4D[0][3], dMtrx4D[1][3], dMtrx4D[2][3]); transpose(); - vec = this->operator*(vec); + multVec(vec, vec); dMtrx4D[0][3] = -vec.x; dMtrx4D[3][0] = 0; dMtrx4D[1][3] = -vec.y; diff --git a/src/Base/Matrix.h b/src/Base/Matrix.h index 41a9d52df2..665c69376a 100644 --- a/src/Base/Matrix.h +++ b/src/Base/Matrix.h @@ -239,15 +239,8 @@ private: inline Matrix4D Matrix4D::operator+(const Matrix4D& mat) const { - Matrix4D clMat; - - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - clMat.dMtrx4D[i][j] = dMtrx4D[i][j] + mat[i][j]; - } - } - - return clMat; + Matrix4D newMat(*this); + return newMat += mat; } inline Matrix4D& Matrix4D::operator+=(const Matrix4D& mat) @@ -263,15 +256,8 @@ inline Matrix4D& Matrix4D::operator+=(const Matrix4D& mat) inline Matrix4D Matrix4D::operator-(const Matrix4D& mat) const { - Matrix4D clMat; - - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - clMat.dMtrx4D[i][j] = dMtrx4D[i][j] - mat[i][j]; - } - } - - return clMat; + Matrix4D newMat(*this); + return newMat -= mat; } inline Matrix4D& Matrix4D::operator-=(const Matrix4D& mat) @@ -287,19 +273,7 @@ inline Matrix4D& Matrix4D::operator-=(const Matrix4D& mat) inline Matrix4D& Matrix4D::operator*=(const Matrix4D& mat) { - Matrix4D clMat; - - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - clMat.dMtrx4D[i][j] = 0; - for (int e = 0; e < 4; e++) { - clMat.dMtrx4D[i][j] += dMtrx4D[i][e] * mat.dMtrx4D[e][j]; - } - } - } - - (*this) = clMat; - + (*this) = (*this) * mat; return *this; } @@ -336,23 +310,16 @@ inline Matrix4D& Matrix4D::operator=(const Matrix4D& mat) inline Vector3f Matrix4D::operator*(const Vector3f& vec) const { - // clang-format off - double sx = static_cast(vec.x); - double sy = static_cast(vec.y); - double sz = static_cast(vec.z); - return Vector3f(static_cast(dMtrx4D[0][0] * sx + dMtrx4D[0][1] * sy + dMtrx4D[0][2] * sz + dMtrx4D[0][3]), - static_cast(dMtrx4D[1][0] * sx + dMtrx4D[1][1] * sy + dMtrx4D[1][2] * sz + dMtrx4D[1][3]), - static_cast(dMtrx4D[2][0] * sx + dMtrx4D[2][1] * sy + dMtrx4D[2][2] * sz + dMtrx4D[2][3])); - // clang-format on + Vector3f dst; + multVec(vec, dst); + return dst; } inline Vector3d Matrix4D::operator*(const Vector3d& vec) const { - // clang-format off - return Vector3d((dMtrx4D[0][0] * vec.x + dMtrx4D[0][1] * vec.y + dMtrx4D[0][2] * vec.z + dMtrx4D[0][3]), - (dMtrx4D[1][0] * vec.x + dMtrx4D[1][1] * vec.y + dMtrx4D[1][2] * vec.z + dMtrx4D[1][3]), - (dMtrx4D[2][0] * vec.x + dMtrx4D[2][1] * vec.y + dMtrx4D[2][2] * vec.z + dMtrx4D[2][3])); - // clang-format on + Vector3d dst; + multVec(vec, dst); + return dst; } inline void Matrix4D::multVec(const Vector3d& src, Vector3d& dst) const @@ -379,14 +346,8 @@ inline void Matrix4D::multVec(const Vector3f& src, Vector3f& dst) const inline Matrix4D Matrix4D::operator*(double scalar) const { - Matrix4D matrix; - for (unsigned int i = 0; i < 4; i++) { - for (unsigned int j = 0; j < 4; j++) { - matrix.dMtrx4D[i][j] = dMtrx4D[i][j] * scalar; - } - } - - return matrix; + Matrix4D newMat(*this); + return newMat *= scalar; } inline Matrix4D& Matrix4D::operator*=(double scalar) @@ -421,7 +382,7 @@ inline bool Matrix4D::operator!=(const Matrix4D& mat) const inline Vector3f& operator*=(Vector3f& vec, const Matrix4D& mat) { - vec = mat * vec; + mat.multVec(vec, vec); return vec; } diff --git a/tests/src/Base/Matrix.cpp b/tests/src/Base/Matrix.cpp index 63b3bb0a01..6d1e280627 100644 --- a/tests/src/Base/Matrix.cpp +++ b/tests/src/Base/Matrix.cpp @@ -1,6 +1,7 @@ #include #include #include +#include // NOLINTBEGIN(cppcoreguidelines-*,readability-magic-numbers) // clang-format off @@ -155,6 +156,18 @@ TEST(Matrix, TestMultVec) Base::Vector3d vec2 {1, 1, 1}; mat.multVec(vec2, vec2); EXPECT_EQ(vec2, Base::Vector3d(6.0, 7.0, 8.0)); + + Base::Vector3f vec3{1.0F,1.0F,3.0F}; + vec3 = mat * vec3; + EXPECT_EQ(vec3, Base::Vector3f(12.0F, 9.0F, 12.0F)); + + Base::Vector3f vec4 {1.0F, 1.0F, 1.0F}; + mat.multVec(vec4, vec4); + EXPECT_EQ(vec4, Base::Vector3f(6.0F, 7.0F, 8.0F)); + + Base::Vector3f vec5 {1.0F, 1.0F, 1.0F}; + vec5 *= mat; + EXPECT_EQ(vec5, Base::Vector3f(6.0F, 7.0F, 8.0F)); } TEST(Matrix, TestMult) @@ -173,6 +186,7 @@ TEST(Matrix, TestMult) 10.0, 13.0, 13.0, 7.0, 0.0, 0.0, 0.0, 1.0}; EXPECT_EQ(mat3, mat4); + EXPECT_NE(mat3, Base::Matrix4D()); } TEST(Matrix, TestMultAssign) @@ -280,6 +294,21 @@ TEST(Matrix, TestHatOperator) EXPECT_EQ(mat1, mat2); } +TEST(Matrix, TestHatOperatorFloat) +{ + Base::Vector3f vec{1.0, 2.0, 3.0}; + + Base::Matrix4D mat1; + mat1.Hat(vec); + + Base::Matrix4D mat2{0.0F, -vec.z, vec.y, 0.0F, + vec.z, 0.0F, -vec.x, 0.0F, + -vec.y, vec.x, 0.0F, 0.0F, + 0.0F, 0.0F, 0.0F, 1.0F}; + + EXPECT_EQ(mat1, mat2); +} + TEST(Matrix, TestDyadic) { Base::Vector3d vec{1.0, 2.0, 3.0}; @@ -295,6 +324,21 @@ TEST(Matrix, TestDyadic) EXPECT_EQ(mat1, mat2); } +TEST(Matrix, TestDyadicFloat) +{ + Base::Vector3f vec{1.0F, 2.0F, 3.0F}; + + Base::Matrix4D mat1; + mat1.Outer(vec, vec); + + Base::Matrix4D mat2{1.0, 2.0, 3.0, 0.0, + 2.0, 4.0, 6.0, 0.0, + 3.0, 6.0, 9.0, 0.0, + 0.0, 0.0, 0.0, 1.0}; + + EXPECT_EQ(mat1, mat2); +} + TEST(Matrix, TestDecomposeScale) { Base::Matrix4D mat; @@ -333,6 +377,18 @@ TEST(Matrix, TestDecomposeMove) EXPECT_EQ(res[3], mat); } +TEST(Matrix, TestDecomposeMoveFloat) +{ + Base::Matrix4D mat; + mat.move(Base::Vector3f(1.0F, 2.0F, 3.0F)); + auto res = mat.decompose(); + + EXPECT_TRUE(res[0].isUnity()); + EXPECT_TRUE(res[1].isUnity()); + EXPECT_TRUE(res[2].isUnity()); + EXPECT_EQ(res[3], mat); +} + TEST(Matrix, TestDecompose) { Base::Matrix4D mat; @@ -401,5 +457,121 @@ TEST(Matrix, TestRotAxisFormula) //NOLINT EXPECT_DOUBLE_EQ(mat1[2][1], mat2[2][1]); EXPECT_DOUBLE_EQ(mat1[2][2], mat2[2][2]); } + +TEST(Matrix, TestTransform) +{ + Base::Matrix4D mat; + mat.rotZ(Base::toRadians(90.0)); + + Base::Matrix4D unity; + unity.transform(Base::Vector3d(10.0, 0.0, 0.0), mat); + + Base::Matrix4D mov{0.0, -1.0, 0.0, 10.0, + 1.0, 0.0, 0.0, -10.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0}; + EXPECT_EQ(unity, mov); +} + +TEST(Matrix, TestTransformFloat) +{ + Base::Matrix4D mat; + mat.rotZ(Base::toRadians(90.0)); + + Base::Matrix4D mat2; + mat2.transform(Base::Vector3f(10.0F, 0.0F, 0.0F), mat); + + Base::Matrix4D mov{0.0, -1.0, 0.0, 10.0, + 1.0, 0.0, 0.0, -10.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0}; + EXPECT_EQ(mat2, mov); +} + +TEST(Matrix, TestInverseOrthogonal) +{ + Base::Matrix4D mat; + mat.rotZ(Base::toRadians(90.0)); + + Base::Matrix4D mat2; + mat2.transform(Base::Vector3d(10.0, 0.0, 0.0), mat); + mat2.inverseOrthogonal(); + + Base::Matrix4D mov{0.0, 1.0, 0.0, 10.0, + -1.0, 0.0, 0.0, 10.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0}; + EXPECT_EQ(mat2, mov); +} + +TEST(Matrix, TestTranspose) +{ + Base::Matrix4D mat{1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 1.0, 2.0, 3.0, + 4.0, 5.0, 6.0, 7.0}; + + Base::Matrix4D trp{1.0, 5.0, 9.0, 4.0, + 2.0, 6.0, 1.0, 5.0, + 3.0, 7.0, 2.0, 6.0, + 4.0, 8.0, 3.0, 7.0}; + + mat.transpose(); + EXPECT_EQ(mat, trp); +} + +TEST(Matrix, TestTrace) +{ + Base::Matrix4D mat{1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 1.0, 2.0, 3.0, + 4.0, 5.0, 6.0, 7.0}; + EXPECT_DOUBLE_EQ(mat.trace(), 16.0); + EXPECT_DOUBLE_EQ(mat.trace3(), 9.0); +} + +TEST(Matrix, TestSetAndGetMatrix) +{ + Base::Matrix4D mat{1.0, 2.0, 3.0, 0.0, + 2.0, 4.0, 6.0, 0.0, + 3.0, 6.0, 9.0, 0.0, + 0.0, 0.0, 0.0, 1.0}; + + std::array values; + mat.getMatrix(values.data()); + Base::Matrix4D inp; + inp.setMatrix(values.data()); + + EXPECT_EQ(mat, inp); +} + +TEST(Matrix, TestSetAndGetGLMatrix) +{ + Base::Matrix4D mat{1.0, 2.0, 3.0, 0.0, + 2.0, 4.0, 6.0, 0.0, + 3.0, 6.0, 9.0, 0.0, + 0.0, 0.0, 0.0, 1.0}; + + std::array values; + mat.getGLMatrix(values.data()); + Base::Matrix4D inp; + inp.setGLMatrix(values.data()); + + EXPECT_EQ(mat, inp); +} + +TEST(Matrix, TestToAndFromString) +{ + Base::Matrix4D mat{1.0, 2.0, 3.0, 0.0, + 2.0, 4.0, 6.0, 0.0, + 3.0, 6.0, 9.0, 0.0, + 0.0, 0.0, 0.0, 1.0}; + + std::string str = mat.toString(); + Base::Matrix4D inp; + inp.fromString(str); + + EXPECT_EQ(mat, inp); +} // clang-format on // NOLINTEND(cppcoreguidelines-*,readability-magic-numbers) From abe64f757607e5e43b597cbdc482a97b5cb83822 Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 13 May 2025 15:56:20 +0200 Subject: [PATCH 4/4] Base: Use nested std::array for Matrix4D class --- src/Base/Matrix.cpp | 39 ++++++++++++++++++--------------------- src/Base/Matrix.h | 11 ++++++----- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/Base/Matrix.cpp b/src/Base/Matrix.cpp index 8bd35ec1ab..8a9f5019c0 100644 --- a/src/Base/Matrix.cpp +++ b/src/Base/Matrix.cpp @@ -35,30 +35,30 @@ using namespace Base; // clang-format off Matrix4D::Matrix4D() - : dMtrx4D {{1., 0., 0., 0.}, - {0., 1., 0., 0.}, - {0., 0., 1., 0.}, - {0., 0., 0., 1.}} + : dMtrx4D {{{1., 0., 0., 0.}, + {0., 1., 0., 0.}, + {0., 0., 1., 0.}, + {0., 0., 0., 1.}}} {} Matrix4D::Matrix4D(float a11, float a12, float a13, float a14, float a21, float a22, float a23, float a24, float a31, float a32, float a33, float a34, float a41, float a42, float a43, float a44) - : dMtrx4D {{a11, a12, a13, a14}, - {a21, a22, a23, a24}, - {a31, a32, a33, a34}, - {a41, a42, a43, a44}} + : dMtrx4D {{{a11, a12, a13, a14}, + {a21, a22, a23, a24}, + {a31, a32, a33, a34}, + {a41, a42, a43, a44}}} {} Matrix4D::Matrix4D(double a11, double a12, double a13, double a14, double a21, double a22, double a23, double a24, double a31, double a32, double a33, double a34, double a41, double a42, double a43, double a44) - : dMtrx4D {{a11, a12, a13, a14}, - {a21, a22, a23, a24}, - {a31, a32, a33, a34}, - {a41, a42, a43, a44}} + : dMtrx4D {{{a11, a12, a13, a14}, + {a21, a22, a23, a24}, + {a31, a32, a33, a34}, + {a41, a42, a43, a44}}} {} // clang-format on @@ -700,15 +700,12 @@ void Matrix4D::Print() const void Matrix4D::transpose() { - double dNew[4][4]; - - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - dNew[j][i] = dMtrx4D[i][j]; - } - } - - memcpy(dMtrx4D, dNew, sizeof(dMtrx4D)); + std::swap(dMtrx4D[0][1], dMtrx4D[1][0]); + std::swap(dMtrx4D[0][2], dMtrx4D[2][0]); + std::swap(dMtrx4D[0][3], dMtrx4D[3][0]); + std::swap(dMtrx4D[1][2], dMtrx4D[2][1]); + std::swap(dMtrx4D[1][3], dMtrx4D[3][1]); + std::swap(dMtrx4D[2][3], dMtrx4D[3][2]); } diff --git a/src/Base/Matrix.h b/src/Base/Matrix.h index 665c69376a..3e0ba98794 100644 --- a/src/Base/Matrix.h +++ b/src/Base/Matrix.h @@ -106,9 +106,9 @@ public: /// Comparison inline bool operator==(const Matrix4D& mat) const; /// Index operator - inline double* operator[](unsigned int usNdx); + inline std::array& operator[](unsigned int usNdx); /// Index operator - inline const double* operator[](unsigned int usNdx) const; + inline const std::array& operator[](unsigned int usNdx) const; /// Get vector of row inline Vector3d getRow(unsigned int usNdx) const; /// Get vector of column @@ -234,7 +234,8 @@ public: void fromString(const std::string& str); private: - double dMtrx4D[4][4]; + using Array2d = std::array, 4>; + Array2d dMtrx4D; }; inline Matrix4D Matrix4D::operator+(const Matrix4D& mat) const @@ -386,12 +387,12 @@ inline Vector3f& operator*=(Vector3f& vec, const Matrix4D& mat) return vec; } -inline double* Matrix4D::operator[](unsigned int usNdx) +inline std::array& Matrix4D::operator[](unsigned int usNdx) { return dMtrx4D[usNdx]; } -inline const double* Matrix4D::operator[](unsigned int usNdx) const +inline const std::array& Matrix4D::operator[](unsigned int usNdx) const { return dMtrx4D[usNdx]; }