From 617051fbf51ba77ae81801f38c08fb77c955eb35 Mon Sep 17 00:00:00 2001 From: Konstantinos Katrioplas Date: Fri, 27 Apr 2018 13:50:53 +0200 Subject: [PATCH] tests --- .../Optimal_bounding_box/fitness_function.h | 1 - .../include/CGAL/Optimal_bounding_box/obb.h | 13 +- .../data/long_tetrahedron.off | 11 ++ .../data/random_unit_tetra.off | 11 ++ .../{tetra3.off => reference_tetrahedron.off} | 0 .../test_optimization_algorithms.cpp | 151 +++++++++++------- 6 files changed, 130 insertions(+), 57 deletions(-) create mode 100644 Optimal_bounding_box/test/Optimal_bounding_box/data/long_tetrahedron.off create mode 100644 Optimal_bounding_box/test/Optimal_bounding_box/data/random_unit_tetra.off rename Optimal_bounding_box/test/Optimal_bounding_box/data/{tetra3.off => reference_tetrahedron.off} (100%) diff --git a/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/fitness_function.h b/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/fitness_function.h index 6b2cd7b5bb5..40ceb55e45f 100644 --- a/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/fitness_function.h +++ b/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/fitness_function.h @@ -94,7 +94,6 @@ struct Fitness_map // -> a free function simplex_id = i; vertex_id = j; best_fitness = fitness; - std::cout << "best fitness = " << best_fitness << std::endl; } } diff --git a/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/obb.h b/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/obb.h index cd90c110f12..bff18be74f7 100644 --- a/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/obb.h +++ b/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/obb.h @@ -39,9 +39,15 @@ namespace Optimal_bounding_box { template -void evolution(Matrix& R, Matrix& points) +void evolution(Matrix& R, Matrix& points, std::size_t generations) { - std::size_t generations = 7; + + CGAL_assertion(points.rows() >= 3); + CGAL_assertion(points.cols() = 3); + CGAL_assertion(R.rows() = 3); + CGAL_assertion(R.cols() = 3); + + std::size_t nelder_mead_iterations = 20; Population pop(50); @@ -71,9 +77,12 @@ void evolution(Matrix& R, Matrix& points) // debugging + /* Fitness_map fitness_map(pop, points); Matrix R_now = fitness_map.get_best(); std::cout << "det= " << R_now.determinant() << std::endl; + */ + } diff --git a/Optimal_bounding_box/test/Optimal_bounding_box/data/long_tetrahedron.off b/Optimal_bounding_box/test/Optimal_bounding_box/data/long_tetrahedron.off new file mode 100644 index 00000000000..ad966ac795e --- /dev/null +++ b/Optimal_bounding_box/test/Optimal_bounding_box/data/long_tetrahedron.off @@ -0,0 +1,11 @@ +OFF +4 4 0 + +-1 -0.1 0 +-1 0.1 0 +1 0 -0.1 +1 0 0.1 +3 0 1 2 +3 2 3 0 +3 1 3 2 +3 0 3 1 \ No newline at end of file diff --git a/Optimal_bounding_box/test/Optimal_bounding_box/data/random_unit_tetra.off b/Optimal_bounding_box/test/Optimal_bounding_box/data/random_unit_tetra.off new file mode 100644 index 00000000000..270289e2c6e --- /dev/null +++ b/Optimal_bounding_box/test/Optimal_bounding_box/data/random_unit_tetra.off @@ -0,0 +1,11 @@ +OFF +4 4 0 + +0.866802 0.740808 0.895304 +0.912651 0.761565 0.160330 +0.093661 0.892578 0.737412 +0.166461 0.149912 0.364944 +3 0 1 2 +3 2 3 0 +3 1 3 2 +3 0 3 1 \ No newline at end of file diff --git a/Optimal_bounding_box/test/Optimal_bounding_box/data/tetra3.off b/Optimal_bounding_box/test/Optimal_bounding_box/data/reference_tetrahedron.off similarity index 100% rename from Optimal_bounding_box/test/Optimal_bounding_box/data/tetra3.off rename to Optimal_bounding_box/test/Optimal_bounding_box/data/reference_tetrahedron.off diff --git a/Optimal_bounding_box/test/Optimal_bounding_box/test_optimization_algorithms.cpp b/Optimal_bounding_box/test/Optimal_bounding_box/test_optimization_algorithms.cpp index a29b7c092eb..0f3fca91a30 100644 --- a/Optimal_bounding_box/test/Optimal_bounding_box/test_optimization_algorithms.cpp +++ b/Optimal_bounding_box/test/Optimal_bounding_box/test_optimization_algorithms.cpp @@ -21,6 +21,25 @@ bool assert_doubles(double d1, double d2, double epsilon) return (d1 < d2 + epsilon && d1 > d2 - epsilon) ? true : false; } +template +void sm_to_matrix(SurfaceMesh& sm, Matrix& mat) +{ + typedef typename boost::property_map::const_type Vpm; + typedef typename boost::property_traits::reference Point_ref; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + Vpm vpm = get(boost::vertex_point, sm); + + mat.resize(vertices(sm).size(), 3); + std::size_t i = 0; + for(vertex_descriptor v : vertices(sm)) + { + Point_ref p = get(vpm, v); + mat(i, 0) = p.x(); + mat(i, 1) = p.y(); + mat(i, 2) = p.z(); + ++i; + } +} void test_population() { @@ -34,7 +53,6 @@ void test_population() void test_nelder_mead() { - MatrixXf data_points(4, 3); data_points << 0.866802, 0.740808, 0.895304, 0.912651, 0.761565, 0.160330, @@ -122,7 +140,6 @@ void test_nelder_mead() void test_genetic_algorithm() { - MatrixXf data_points(4, 3); data_points << 0.866802, 0.740808, 0.895304, 0.912651, 0.761565, 0.160330, @@ -134,65 +151,53 @@ void test_genetic_algorithm() CGAL_assertion(pop.size() == 5); } - - - -void find_obb() +void test_random_unit_tetra() { - - MatrixXf data_points(4, 3); // there are on the convex hull + MatrixXf data_points(4, 3); // points on their convex hull data_points << 0.866802, 0.740808, 0.895304, 0.912651, 0.761565, 0.160330, 0.093661, 0.892578, 0.737412, 0.166461, 0.149912, 0.364944; + typedef CGAL::Simple_cartesian K; + typedef K::Point_3 Point; + typedef CGAL::Surface_mesh Mesh; - CGAL::Optimal_bounding_box::visualize_obb(data_points, "/tmp/original.off"); + // make a mesh and export it + Mesh mesh; + Point p1(0.866802, 0.740808, 0.895304); + Point p2(0.912651, 0.761565, 0.160330); + Point p3(0.093661, 0.892578, 0.737412); + Point p4(0.166461, 0.149912, 0.364944); + CGAL::make_tetrahedron(p1, p2, p3, p4, mesh); + std::ofstream out("data/random_unit_tetra.off"); + out << mesh; + out.close(); + MatrixXf R(3, 3); + std::size_t generations = 10; + CGAL::Optimal_bounding_box::evolution(R, data_points, generations); - MatrixXf rotation(3, 3); - CGAL::Optimal_bounding_box::evolution(rotation, data_points); - - // rotate - MatrixXf rotated_points(4, 3); - rotated_points = data_points * rotation.transpose(); - - CGAL_assertion(rotated_points.cols() == data_points.cols()); - CGAL_assertion(rotated_points.rows() == data_points.rows()); - - std::cout << "rotation matrix= \n" << rotation << std::endl << std::endl; - std::cout << "rotated_points= \n" << rotated_points << std::endl; - - CGAL::Optimal_bounding_box::visualize_obb(rotated_points, "/tmp/rotated.off"); + std::cout << R << std::endl; + double epsilon = 1e-5; + CGAL_assertion(assert_doubles(R.determinant(), 1, epsilon)); + CGAL_assertion(assert_doubles(R(0,0), -0.25791, epsilon)); + CGAL_assertion(assert_doubles(R(0,1), 0.796512, epsilon)); + CGAL_assertion(assert_doubles(R(0,2), -0.546855, epsilon)); + CGAL_assertion(assert_doubles(R(1,0), -0.947128, epsilon)); + CGAL_assertion(assert_doubles(R(1,1), -0.320242, epsilon)); + CGAL_assertion(assert_doubles(R(1,2), -0.0197553, epsilon)); + CGAL_assertion(assert_doubles(R(2,0), -0.190861, epsilon)); + CGAL_assertion(assert_doubles(R(2,1), 0.512847, epsilon)); + CGAL_assertion(assert_doubles(R(2,2), 0.836992, epsilon)); + MatrixXf obb(8, 3); + CGAL::Optimal_bounding_box::post_processing(data_points, R, obb); + CGAL::Optimal_bounding_box::matrix_to_mesh_and_draw(obb, "data/random_unit_tetra_result.off"); } - - - -template -void sm_to_matrix(SurfaceMesh& sm, Matrix& mat) -{ - typedef typename boost::property_map::const_type Vpm; - typedef typename boost::property_traits::reference Point_ref; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - Vpm vpm = get(boost::vertex_point, sm); - - mat.resize(vertices(sm).size(), 3); - std::size_t i = 0; - for(vertex_descriptor v : vertices(sm)) - { - Point_ref p = get(vpm, v); - mat(i, 0) = p.x(); - mat(i, 1) = p.y(); - mat(i, 2) = p.z(); - ++i; - } -} - - -void test_tetrahedron(const char* fname) +void test_reference_tetrahedron(const char* fname) { std::ifstream input(fname); CGAL::Surface_mesh mesh; @@ -206,18 +211,55 @@ void test_tetrahedron(const char* fname) sm_to_matrix(mesh, points); MatrixXf R(3, 3); - CGAL::Optimal_bounding_box::evolution(R, points); - std:: cout << "R= " << R << std::endl; - std:: cout << "det(evolution)= " << R.determinant() << std::endl; + std::size_t generations = 10; + CGAL::Optimal_bounding_box::evolution(R, points, generations); + double epsilon = 1e-5; + std::cout << R << std::endl; + CGAL_assertion(assert_doubles(R.determinant(), 1, epsilon)); // postprocessing MatrixXf obb(8, 3); CGAL::Optimal_bounding_box::post_processing(points, R, obb); CGAL::Optimal_bounding_box::matrix_to_mesh_and_draw(obb, "data/OBB.off"); - } +void test_long_tetrahedron(std::string fname) +{ + std::ifstream input(fname); + CGAL::Surface_mesh mesh; + if (!input || !(input >> mesh) || mesh.is_empty()) { + std::cerr << fname << " is not a valid off file.\n"; + exit(1); + } + + // points in a matrix + MatrixXf points; + sm_to_matrix(mesh, points); + + MatrixXf R(3, 3); + std::size_t generations = 10; + CGAL::Optimal_bounding_box::evolution(R, points, generations); + double epsilon = 1e-5; + std::cout << R << std::endl; + CGAL_assertion(assert_doubles(R.determinant(), 1, epsilon)); + CGAL_assertion(assert_doubles(R(0,0), -1, epsilon)); + CGAL_assertion(assert_doubles(R(0,1), 0, epsilon)); + CGAL_assertion(assert_doubles(R(0,2), 0, epsilon)); + CGAL_assertion(assert_doubles(R(1,0), 0, epsilon)); + CGAL_assertion(assert_doubles(R(1,1), -0.707107, epsilon)); + CGAL_assertion(assert_doubles(R(1,2), 0.707106, epsilon) || + assert_doubles(R(1,2), -0.707106, epsilon)); + CGAL_assertion(assert_doubles(R(2,0), 0, epsilon)); + CGAL_assertion(assert_doubles(R(2,1), 0.707106, epsilon) || + assert_doubles(R(1,2), -0.707106, epsilon)); + CGAL_assertion(assert_doubles(R(2,2), 0.707107, epsilon)); + + // postprocessing + MatrixXf obb(8, 3); + CGAL::Optimal_bounding_box::post_processing(points, R, obb); + CGAL::Optimal_bounding_box::matrix_to_mesh_and_draw(obb, fname + "result.off"); +} void rotate_tetrahedron(const char* fname, const char* Rname) { @@ -267,10 +309,11 @@ int main() //test_population(); //test_nelder_mead(); //test_genetic_algorithm(); - //find_obb(); + //test_random_unit_tetra(); - test_tetrahedron("data/random_tetra.off"); + test_reference_tetrahedron("data/reference_tetrahedron.off"); + //test_long_tetrahedron("data/long_tetrahedron.off"); //rotate_tetrahedron("data/random_tetra.off", "data/rotation.dat");