mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-12 02:09:03 +08:00
cpp porting: TransformationMatrix class tests (#4906)
* cpp porting: transformation class testing * reword some tests * remove obsolete include * change equality threshold implementation * semicolons help in C++
This commit is contained in:
parent
3ad231a366
commit
e37620fcd4
@ -315,6 +315,7 @@ set(SLIC3R_TEST_SOURCES
|
||||
${TESTDIR}/libslic3r/test_printobject.cpp
|
||||
${TESTDIR}/libslic3r/test_skirt_brim.cpp
|
||||
${TESTDIR}/libslic3r/test_test_data.cpp
|
||||
${TESTDIR}/libslic3r/test_transformationmatrix.cpp
|
||||
${TESTDIR}/libslic3r/test_trianglemesh.cpp
|
||||
${TESTDIR}/libslic3r/test_extrusion_entity.cpp
|
||||
${TESTDIR}/libslic3r/test_3mf.cpp
|
||||
|
217
src/test/libslic3r/test_transformationmatrix.cpp
Normal file
217
src/test/libslic3r/test_transformationmatrix.cpp
Normal file
@ -0,0 +1,217 @@
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "libslic3r.h"
|
||||
#include "TransformationMatrix.hpp"
|
||||
|
||||
using namespace Slic3r;
|
||||
|
||||
constexpr auto THRESHOLD_EQUALITY = 1.0e-3;
|
||||
|
||||
bool check_elements(TransformationMatrix const & matrix,
|
||||
double m00, double m01, double m02, double m03,
|
||||
double m10, double m11, double m12, double m13,
|
||||
double m20, double m21, double m22, double m23);
|
||||
bool check_point(const Pointf3 & point, coordf_t x, coordf_t y, coordf_t z);
|
||||
double degtorad(double value){ return PI / 180.0 * value; }
|
||||
|
||||
SCENARIO("TransformationMatrix: constructors, copytor, comparing, basic operations"){
|
||||
GIVEN("a default constructed Matrix") {
|
||||
auto trafo_default = TransformationMatrix();
|
||||
THEN("comparing to the eye matrix") {
|
||||
REQUIRE(check_elements(trafo_default,
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0));
|
||||
}
|
||||
|
||||
WHEN("copied") {
|
||||
auto trafo_eq_assigned = trafo_default;
|
||||
THEN("comparing the second to the eye matrix") {
|
||||
REQUIRE(check_elements(trafo_eq_assigned,
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0));
|
||||
}
|
||||
THEN("comparing them to each other")
|
||||
{
|
||||
REQUIRE(trafo_default == trafo_eq_assigned);
|
||||
REQUIRE(!(trafo_default != trafo_eq_assigned));
|
||||
}
|
||||
trafo_eq_assigned.m00 = 2.0;
|
||||
THEN("testing uniqueness") {
|
||||
REQUIRE(trafo_default != trafo_eq_assigned);
|
||||
}
|
||||
}
|
||||
}
|
||||
GIVEN("a directly set matrix") {
|
||||
THEN("set via constructor") {
|
||||
auto trafo_set = TransformationMatrix(1,2,3,4,5,6,7,8,9,10,11,12);
|
||||
REQUIRE(check_elements(trafo_set,
|
||||
1,2,3,4,
|
||||
5,6,7,8,
|
||||
9,10,11,12));
|
||||
}
|
||||
THEN("set via vector") {
|
||||
std::vector<double> elements;
|
||||
elements.reserve(12);
|
||||
elements.push_back(1);
|
||||
elements.push_back(2);
|
||||
elements.push_back(3);
|
||||
elements.push_back(4);
|
||||
elements.push_back(5);
|
||||
elements.push_back(6);
|
||||
elements.push_back(7);
|
||||
elements.push_back(8);
|
||||
elements.push_back(9);
|
||||
elements.push_back(10);
|
||||
elements.push_back(11);
|
||||
elements.push_back(12);
|
||||
auto trafo_vec = TransformationMatrix(elements);
|
||||
REQUIRE(check_elements(trafo_vec,
|
||||
1,2,3,4,
|
||||
5,6,7,8,
|
||||
9,10,11,12));
|
||||
}
|
||||
}
|
||||
GIVEN("two separate matrices") {
|
||||
auto mat1 = TransformationMatrix(1,2,3,4,5,6,7,8,9,10,11,12);
|
||||
auto mat2 = TransformationMatrix(1,4,7,10,2,5,8,11,3,6,9,12);
|
||||
THEN("static multiplication") {
|
||||
auto mat3 = TransformationMatrix::multiply(mat1, mat2);
|
||||
REQUIRE(check_elements(mat3,14,32,50,72,38,92,146,208,62,152,242,344));
|
||||
mat3 = TransformationMatrix::multiply(mat2, mat1);
|
||||
REQUIRE(check_elements(mat3,84,96,108,130,99,114,129,155,114,132,150,180));
|
||||
}
|
||||
THEN("direct multiplication") {
|
||||
REQUIRE(check_elements(mat1.multiplyRight(mat2),14,32,50,72,38,92,146,208,62,152,242,344));
|
||||
REQUIRE(check_elements(mat2.multiplyLeft(mat1),14,32,50,72,38,92,146,208,62,152,242,344));
|
||||
}
|
||||
}
|
||||
GIVEN("a random transformation-ish matrix") {
|
||||
auto mat = TransformationMatrix(
|
||||
0.9004,-0.2369,-0.4847,12.9383,
|
||||
-0.9311,0.531,-0.5026,7.7931,
|
||||
-0.1225,0.5904,0.2576,-7.316);
|
||||
THEN("computing the determinante") {
|
||||
REQUIRE(std::abs(mat.determinante() - 0.5539) < THRESHOLD_EQUALITY);
|
||||
}
|
||||
THEN("computing the inverse") {
|
||||
REQUIRE(check_elements(mat.inverse(),
|
||||
0.78273016,-0.40649736,0.67967289,-1.98683622,
|
||||
0.54421957,0.31157368,1.63191055,2.46965668,
|
||||
-0.87508846,-0.90741083,0.46498424,21.79552507));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCENARIO("TransformationMatrix: application") {
|
||||
GIVEN("two vectors to validate geometric transformations") {
|
||||
auto vec1 = Pointf3(1,2,3);
|
||||
auto vec2 = Pointf3(-4,3,-2);
|
||||
THEN("testing general point transformation") {
|
||||
auto mat = TransformationMatrix(1,2,3,4,5,6,7,8,9,10,11,12);
|
||||
REQUIRE(check_point(mat.transform(vec1),18,46,74)); // default arg should be like a point
|
||||
REQUIRE(check_point(mat.transform(vec1,1),18,46,74));
|
||||
REQUIRE(check_point(mat.transform(vec1,0),14,38,62));
|
||||
}
|
||||
WHEN("testing scaling") {
|
||||
THEN("testing universal scaling") {
|
||||
auto mat = TransformationMatrix::mat_scale(3);
|
||||
REQUIRE(check_point(mat.transform(vec1),3,6,9));
|
||||
}
|
||||
THEN("testing vector like scaling") {
|
||||
auto mat = TransformationMatrix::mat_scale(2,3,4);
|
||||
REQUIRE(check_point(mat.transform(vec1),2,6,12));
|
||||
}
|
||||
}
|
||||
WHEN("testing mirroring") {
|
||||
THEN("testing axis aligned mirroring") {
|
||||
auto mat = TransformationMatrix::mat_mirror(Axis::X);
|
||||
REQUIRE(check_point(mat.transform(vec1),-1,2,3));
|
||||
mat = TransformationMatrix::mat_mirror(Axis::Y);
|
||||
REQUIRE(check_point(mat.transform(vec1),1,-2,3));
|
||||
mat = TransformationMatrix::mat_mirror(Axis::Z);
|
||||
REQUIRE(check_point(mat.transform(vec1),1,2,-3));
|
||||
}
|
||||
THEN("testing arbituary axis mirroring") {
|
||||
auto mat = TransformationMatrix::mat_mirror(vec2);
|
||||
REQUIRE(check_point(mat.transform(vec1),-0.1034,2.8276,2.4483));
|
||||
REQUIRE(std::abs(mat.determinante() + 1.0) < THRESHOLD_EQUALITY);
|
||||
}
|
||||
}
|
||||
WHEN("testing translation") {
|
||||
THEN("testing xyz translation") {
|
||||
auto mat = TransformationMatrix::mat_translation(4,2,5);
|
||||
REQUIRE(check_point(mat.transform(vec1),5,4,8));
|
||||
}
|
||||
THEN("testing vector-defined translation") {
|
||||
auto mat = TransformationMatrix::mat_translation(vec2);
|
||||
REQUIRE(check_point(mat.transform(vec1),-3,5,1));
|
||||
}
|
||||
}
|
||||
WHEN("testing rotation") {
|
||||
THEN("testing axis aligned rotation") {
|
||||
auto mat = TransformationMatrix::mat_rotation(degtorad(90), Axis::X);
|
||||
REQUIRE(check_point(mat.transform(vec1),1,-3,2));
|
||||
mat = TransformationMatrix::mat_rotation(degtorad(90), Axis::Y);
|
||||
REQUIRE(check_point(mat.transform(vec1),3,2,-1));
|
||||
mat = TransformationMatrix::mat_rotation(degtorad(90), Axis::Z);
|
||||
REQUIRE(check_point(mat.transform(vec1),-2,1,3));
|
||||
}
|
||||
THEN("testing arbituary axis rotation") {
|
||||
auto mat = TransformationMatrix::mat_rotation(degtorad(80), vec2);
|
||||
REQUIRE(check_point(mat.transform(vec1),3.0069,1.8341,-1.2627));
|
||||
REQUIRE(std::abs(mat.determinante() - 1.0) < THRESHOLD_EQUALITY);
|
||||
}
|
||||
THEN("testing quaternion rotation") {
|
||||
auto mat = TransformationMatrix::mat_rotation(-0.4775,0.3581,-0.2387,0.7660);
|
||||
REQUIRE(check_point(mat.transform(vec1),3.0069,1.8341,-1.2627));
|
||||
REQUIRE(std::abs(mat.determinante() - 1.0) < THRESHOLD_EQUALITY);
|
||||
}
|
||||
THEN("testing vector to vector") {
|
||||
auto mat = TransformationMatrix::mat_rotation(vec1,vec2);
|
||||
REQUIRE(check_point(mat.transform(vec1),-2.7792,2.0844,-1.3896));
|
||||
REQUIRE(std::abs(mat.determinante() - 1.0) < THRESHOLD_EQUALITY);
|
||||
mat = TransformationMatrix::mat_rotation(vec1,vec1.negative());
|
||||
REQUIRE(check_point(mat.transform(vec1),-1,-2,-3)); // colinear, opposite direction
|
||||
mat = TransformationMatrix::mat_rotation(vec1,vec1);
|
||||
REQUIRE(check_elements(mat,
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0)); // colinear, same direction
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool check_elements(const TransformationMatrix & matrix,
|
||||
double m00, double m01, double m02, double m03,
|
||||
double m10, double m11, double m12, double m13,
|
||||
double m20, double m21, double m22, double m23)
|
||||
{
|
||||
bool equal = true;
|
||||
equal &= std::abs(matrix.m00 - m00) < THRESHOLD_EQUALITY;
|
||||
equal &= std::abs(matrix.m01 - m01) < THRESHOLD_EQUALITY;
|
||||
equal &= std::abs(matrix.m02 - m02) < THRESHOLD_EQUALITY;
|
||||
equal &= std::abs(matrix.m03 - m03) < THRESHOLD_EQUALITY;
|
||||
equal &= std::abs(matrix.m10 - m10) < THRESHOLD_EQUALITY;
|
||||
equal &= std::abs(matrix.m11 - m11) < THRESHOLD_EQUALITY;
|
||||
equal &= std::abs(matrix.m12 - m12) < THRESHOLD_EQUALITY;
|
||||
equal &= std::abs(matrix.m13 - m13) < THRESHOLD_EQUALITY;
|
||||
equal &= std::abs(matrix.m20 - m20) < THRESHOLD_EQUALITY;
|
||||
equal &= std::abs(matrix.m21 - m21) < THRESHOLD_EQUALITY;
|
||||
equal &= std::abs(matrix.m22 - m22) < THRESHOLD_EQUALITY;
|
||||
equal &= std::abs(matrix.m23 - m23) < THRESHOLD_EQUALITY;
|
||||
return equal;
|
||||
}
|
||||
|
||||
bool check_point(const Pointf3 & point, coordf_t x, coordf_t y, coordf_t z)
|
||||
{
|
||||
bool equal = true;
|
||||
equal &= std::abs(point.x - x) < THRESHOLD_EQUALITY;
|
||||
equal &= std::abs(point.y - y) < THRESHOLD_EQUALITY;
|
||||
equal &= std::abs(point.z - z) < THRESHOLD_EQUALITY;
|
||||
return equal;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user