Fix most of the tests

(at least the compilation...)
This commit is contained in:
Mael Rouxel-Labbé 2020-03-13 13:24:03 +01:00
parent 9df21ba79d
commit a7f0473c5c
4 changed files with 329 additions and 395 deletions

View File

@ -48,6 +48,7 @@ void bench_finding_obb(const std::string fname)
convex_hull_3(mesh, poly);
timer.stop();
std::cout << "takes : " << timer.time() << " seconds to find the convex hull\n";
std::cout << num_vertices(poly) << " vertices on the convex hull" << std::endl;
// 2) using convex hull
timer.reset();

View File

@ -1,135 +1,141 @@
#include <CGAL/Eigen_linear_algebra_traits.h>
#include <CGAL/Optimal_bounding_box/nelder_mead_functions.h>
#include <CGAL/Optimal_bounding_box/fitness_function.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/optimal_bounding_box.h>
#include <CGAL/assertions.h>
bool assert_doubles(double d1, double d2, double epsilon)
#include <array>
#include <iostream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT FT;
typedef K::Point_3 Point_3;
typedef CGAL::Oriented_bounding_box_traits_3<K> Traits;
typedef Traits::Matrix Matrix;
void check_equality(const FT d1, const FT d2)
{
return (d1 < d2 + epsilon && d1 > d2 - epsilon) ? true : false;
const FT epsilon = 1e-3;
bool ok;
if(std::is_floating_point<FT>::value)
ok = CGAL::abs(d1 - d2) < epsilon * CGAL::abs(d2);
else
ok = (d1 == d2);
if(!ok)
{
std::cout << "Error: got " << d1 << " but expected: " << d2 << std::endl;
assert(false);
}
}
void test_fitness_function()
{
typedef typename CGAL::Eigen_linear_algebra_traits::MatrixXd MatrixXd;
MatrixXd data_points(4, 3);
std::array<Point_3, 4> points;
points[0] = Point_3(0.866802, 0.740808, 0.895304);
points[1] = Point_3(0.912651, 0.761565, 0.160330);
points[2] = Point_3(0.093661, 0.892578, 0.737412);
points[3] = Point_3(0.166461, 0.149912, 0.364944);
data_points.set_coef(0, 0, 0.866802);
data_points.set_coef(0, 1, 0.740808);
data_points.set_coef(0, 2, 0.895304);
Matrix rotation;
rotation.set(0, 0, -0.809204);
rotation.set(0, 1, 0.124296);
rotation.set(0, 2, 0.574230);
rotation.set(1, 0, -0.574694);
rotation.set(1, 1, 0.035719);
rotation.set(1, 2, -0.817589);
rotation.set(2, 0, -0.122134);
rotation.set(2, 1, -0.991602);
rotation.set(2, 2, 0.042528);
data_points.set_coef(1, 0, 0.912651);
data_points.set_coef(1, 1, 0.761565);
data_points.set_coef(1, 2, 0.160330);
data_points.set_coef(2, 0, 0.093661);
data_points.set_coef(2, 1, 0.892578);
data_points.set_coef(2, 2, 0.737412);
data_points.set_coef(3, 0, 0.166461);
data_points.set_coef(3, 1, 0.149912);
data_points.set_coef(3, 2, 0.364944);
typedef typename CGAL::Eigen_linear_algebra_traits::Matrix3d Matrix3d;
Matrix3d rotation;
rotation.set_coef(0, 0, -0.809204);
rotation.set_coef(0, 1, 0.124296);
rotation.set_coef(0, 2, 0.574230);
rotation.set_coef(1, 0, -0.574694);
rotation.set_coef(1, 1, 0.035719);
rotation.set_coef(1, 2, -0.817589);
rotation.set_coef(2, 0, -0.122134);
rotation.set_coef(2, 1, -0.991602);
rotation.set_coef(2, 2, 0.042528);
CGAL_assertion_code(typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits);
CGAL_assertion_code(double fitness = CGAL::Optimal_bounding_box::
compute_fitness<Linear_algebra_traits> (rotation, data_points));
CGAL_assertion(assert_doubles(fitness, 0.58606, 1e-5));
const double fitness = CGAL::Optimal_bounding_box::internal::compute_fitness<Traits>(rotation, points);
check_equality(fitness, 0.58606);
}
void test_eigen_matrix_interface()
{
CGAL_assertion_code(typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits);
typedef CGAL::Eigen_dense_matrix<double, 3, 3> Matrix;
Matrix A;
A.set(0, 0, 0.1);
A.set(0, 1, 0.2);
A.set(0, 2, 0.3);
A.set(1, 0, 0.4);
A.set(1, 1, 0.5);
A.set(1, 2, 0.6);
A.set(2, 0, 0.7);
A.set(2, 1, 0.8);
A.set(2, 2, 0.9);
Matrix A(3, 3);
A.set_coef(0, 0, 0.1);
A.set_coef(0, 1, 0.2);
A.set_coef(0, 2, 0.3);
A.set_coef(1, 0, 0.4);
A.set_coef(1, 1, 0.5);
A.set_coef(1, 2, 0.6);
A.set_coef(2, 0, 0.7);
A.set_coef(2, 1, 0.8);
A.set_coef(2, 2, 0.9);
CGAL_assertion_code(Matrix B);
CGAL_assertion_code(B = CGAL::Eigen_linear_algebra_traits::transpose(A));
CGAL_assertion_code(Matrix S);
CGAL_assertion_code(S = 0.5 * A);
Matrix C(3,3);
C.set_coef(0, 0, 0.3011944);
C.set_coef(0, 1, 0.9932761);
C.set_coef(0, 2, 0.5483701);
C.set_coef(1, 0, 0.5149142);
C.set_coef(1, 1, 0.5973263);
C.set_coef(1, 2, 0.5162336);
C.set_coef(2, 0, 0.0039213);
C.set_coef(2, 1, 0.0202949);
C.set_coef(2, 2, 0.9240308);
Matrix B;
B = CGAL::Optimal_bounding_box::internal::transpose(A);
CGAL_assertion_code(Matrix Q = CGAL::Eigen_linear_algebra_traits::get_Q(C));
CGAL_assertion_code(double epsilon = 1e-5);
CGAL_assertion(assert_doubles(Q(0,0), -0.504895, epsilon));
CGAL_assertion(assert_doubles(Q(0,1), 0.862834, epsilon));
CGAL_assertion(assert_doubles(Q(0,2), -0.024447, epsilon));
CGAL_assertion(assert_doubles(Q(1,0), -0.863156, epsilon));
CGAL_assertion(assert_doubles(Q(1,1), -0.504894, epsilon));
CGAL_assertion(assert_doubles(Q(1,2), 0.006687, epsilon));
CGAL_assertion(assert_doubles(Q(2,0), -0.006573, epsilon));
CGAL_assertion(assert_doubles(Q(2,1), 0.024478, epsilon));
CGAL_assertion(assert_doubles(Q(2,2), 0.999679, epsilon));
Matrix S;
S = 0.5 * A;
Matrix D(3,3);
D.set_coef(0, 0, -0.809204);
D.set_coef(0, 1, 0.124296);
D.set_coef(0, 2, 0.574230);
D.set_coef(1, 0, -0.574694);
D.set_coef(1, 1, 0.035719);
D.set_coef(1, 2, -0.817589);
D.set_coef(2, 0, -0.122134);
D.set_coef(2, 1, -0.991602);
D.set_coef(2, 2, 0.042528);
Matrix C;
C.set(0, 0, 0.3011944);
C.set(0, 1, 0.9932761);
C.set(0, 2, 0.5483701);
C.set(1, 0, 0.5149142);
C.set(1, 1, 0.5973263);
C.set(1, 2, 0.5162336);
C.set(2, 0, 0.0039213);
C.set(2, 1, 0.0202949);
C.set(2, 2, 0.9240308);
Matrix E(3,3);
E.set_coef(0, 0, -0.45070);
E.set_coef(0, 1, -0.32769);
E.set_coef(0, 2, -0.83035);
E.set_coef(1, 0, -0.13619);
E.set_coef(1, 1, -0.89406);
E.set_coef(1, 2, 0.42675);
E.set_coef(2, 0, -0.88222);
E.set_coef(2, 1, 0.30543);
E.set_coef(2, 2, 0.35833);
Matrix Q = Traits::get_Q(C);
CGAL_assertion_code(Matrix Sr = CGAL::Optimal_bounding_box::reflection<Linear_algebra_traits>(D, E));
CGAL_assertion(assert_doubles(Sr(0,0), -0.13359, epsilon));
CGAL_assertion(assert_doubles(Sr(0,1), -0.95986, epsilon));
CGAL_assertion(assert_doubles(Sr(0,2), -0.24664, epsilon));
CGAL_assertion(assert_doubles(Sr(1,0), -0.60307, epsilon));
CGAL_assertion(assert_doubles(Sr(1,1), -0.11875, epsilon));
CGAL_assertion(assert_doubles(Sr(1,2), 0.78880, epsilon));
CGAL_assertion(assert_doubles(Sr(2,0), -0.78642, epsilon));
CGAL_assertion(assert_doubles(Sr(2,1), 0.25411, epsilon));
CGAL_assertion(assert_doubles(Sr(2,2), -0.56300, epsilon));
check_equality(Q(0,0), -0.504895);
check_equality(Q(0,1), 0.862834);
check_equality(Q(0,2), -0.024447);
check_equality(Q(1,0), -0.863156);
check_equality(Q(1,1), -0.504894);
check_equality(Q(1,2), 0.006687);
check_equality(Q(2,0), -0.006573);
check_equality(Q(2,1), 0.024478);
check_equality(Q(2,2), 0.999679);
Matrix D;
D.set(0, 0, -0.809204);
D.set(0, 1, 0.124296);
D.set(0, 2, 0.574230);
D.set(1, 0, -0.574694);
D.set(1, 1, 0.035719);
D.set(1, 2, -0.817589);
D.set(2, 0, -0.122134);
D.set(2, 1, -0.991602);
D.set(2, 2, 0.042528);
Matrix E;
E.set(0, 0, -0.45070);
E.set(0, 1, -0.32769);
E.set(0, 2, -0.83035);
E.set(1, 0, -0.13619);
E.set(1, 1, -0.89406);
E.set(1, 2, 0.42675);
E.set(2, 0, -0.88222);
E.set(2, 1, 0.30543);
E.set(2, 2, 0.35833);
Matrix Sr = CGAL::Optimal_bounding_box::internal::reflection(D, E);
check_equality(Sr(0,0), -0.13359);
check_equality(Sr(0,1), -0.95986);
check_equality(Sr(0,2), -0.24664);
check_equality(Sr(1,0), -0.60307);
check_equality(Sr(1,1), -0.11875);
check_equality(Sr(1,2), 0.78880);
check_equality(Sr(2,0), -0.78642);
check_equality(Sr(2,1), 0.25411);
check_equality(Sr(2,2), -0.56300);
}
int main()
int main(int, char**)
{
test_fitness_function();
test_eigen_matrix_interface();
return 0;
std::cout << "Done!" << std::endl;
return EXIT_SUCCESS;
}

View File

@ -5,106 +5,115 @@
#include <iostream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT FT;
typedef K::Point_3 Point_3;
typedef CGAL::Oriented_bounding_box_traits_3<K> Traits;
typedef Traits::Matrix Matrix;
bool are_equal(double d1, double d2, double epsilon)
void check_equality(const FT d1, const FT d2)
{
return (d1 < d2 + epsilon && d1 > d2 - epsilon) ? true : false;
const FT epsilon = 1e-3;
bool ok;
if(std::is_floating_point<FT>::value)
ok = CGAL::abs(d1 - d2) < epsilon * CGAL::abs(d2);
else
ok = (d1 == d2);
if(!ok)
{
std::cout << "Error: got " << d1 << " but expected: " << d2 << std::endl;
assert(false);
}
}
void test_simplex_operations()
void test_simplex_operations(const Traits& traits)
{
const double epsilon = 1e-5;
Matrix Sc(3, 3);
Matrix Sc;
Sc.set(0, 0, -0.809204); Sc.set(0, 1, 0.124296); Sc.set(0, 2, 0.574230);
Sc.set(1, 0, -0.574694); Sc.set(1, 1, 0.035719); Sc.set(1, 2, -0.817589);
Sc.set(2, 0, -0.122134); Sc.set(2, 1, -0.991602); Sc.set(2, 2, 0.042528);
Matrix S_worst(3, 3);
Matrix S_worst;
S_worst.set(0, 0, -0.45070); S_worst.set(0, 1, -0.32769); S_worst.set(0, 2, -0.83035);
S_worst.set(1, 0, -0.13619); S_worst.set(1, 1, -0.89406); S_worst.set(1, 2, 0.42675);
S_worst.set(2, 0, -0.88222); S_worst.set(2, 1, 0.30543); S_worst.set(2, 2, 0.35833);
Matrix Sr = CGAL::Optimal_bounding_box::reflection<Linear_algebra_traits>(Sc, S_worst);
assert(are_equal(Sr(0,0), -0.13359, epsilon));
assert(are_equal(Sr(0,1), -0.95986, epsilon));
assert(are_equal(Sr(0,2), -0.24664, epsilon));
assert(are_equal(Sr(1,0), -0.60307, epsilon));
assert(are_equal(Sr(1,1), -0.11875, epsilon));
assert(are_equal(Sr(1,2), 0.78880, epsilon));
assert(are_equal(Sr(2,0), -0.78642, epsilon));
assert(are_equal(Sr(2,1), 0.25411, epsilon));
assert(are_equal(Sr(2,2), -0.56300, epsilon));
Matrix Sr = CGAL::Optimal_bounding_box::internal::reflection(Sc, S_worst);
check_equality(Sr(0,0), -0.13359);
check_equality(Sr(0,1), -0.95986);
check_equality(Sr(0,2), -0.24664);
check_equality(Sr(1,0), -0.60307);
check_equality(Sr(1,1), -0.11875);
check_equality(Sr(1,2), 0.78880);
check_equality(Sr(2,0), -0.78642);
check_equality(Sr(2,1), 0.25411);
check_equality(Sr(2,2), -0.56300);
Matrix Se = CGAL::Optimal_bounding_box::expansion<Linear_algebra_traits>(Sc, S_worst, Sr);
assert(are_equal(Se(0,0), -0.87991, epsilon));
assert(are_equal(Se(0,1), 0.36105, epsilon));
assert(are_equal(Se(0,2), -0.30888, epsilon));
assert(are_equal(Se(1,0), -0.11816, epsilon));
assert(are_equal(Se(1,1), -0.79593, epsilon));
assert(are_equal(Se(1,2), -0.59375, epsilon));
assert(are_equal(Se(2,0), -0.460215, epsilon));
assert(are_equal(Se(2,1), -0.48595, epsilon));
assert(are_equal(Se(2,2), 0.74300, epsilon));
Matrix Se = CGAL::Optimal_bounding_box::internal::expansion(Sc, S_worst, Sr);
check_equality(Se(0,0), -0.87991);
check_equality(Se(0,1), 0.36105);
check_equality(Se(0,2), -0.30888);
check_equality(Se(1,0), -0.11816);
check_equality(Se(1,1), -0.79593);
check_equality(Se(1,2), -0.59375);
check_equality(Se(2,0), -0.460215);
check_equality(Se(2,1), -0.48595);
check_equality(Se(2,2), 0.74300);
Matrix S_a(3, 3);
Matrix S_a;
S_a.set(0, 0, -0.277970); S_a.set(0, 1, 0.953559); S_a.set(0, 2, 0.116010);
S_a.set(1, 0, -0.567497); S_a.set(1, 1, -0.065576); S_a.set(1, 2, -0.820760);
S_a.set(2, 0, -0.775035); S_a.set(2, 1, -0.293982); S_a.set(2, 2, 0.559370);
Matrix S_b(3, 3);
Matrix S_b;
S_b.set(0, 0, -0.419979); S_b.set(0, 1, 0.301765); S_b.set(0, 2, -0.8558940);
S_b.set(1, 0, -0.653011); S_b.set(1, 1, -0.755415); S_b.set(1, 2, 0.054087);
S_b.set(2, 0, -0.630234); S_b.set(2, 1, 0.581624); S_b.set(2, 2, 0.514314);
Matrix S_c = CGAL::Optimal_bounding_box::mean<Linear_algebra_traits>(S_a, S_b);
assert(are_equal(S_c(0,0), -0.35111, epsilon));
assert(are_equal(S_c(0,1), 0.79308, epsilon));
assert(are_equal(S_c(0,2), -0.49774, epsilon));
assert(are_equal(S_c(1,0), -0.61398, epsilon));
assert(are_equal(S_c(1,1), -0.59635, epsilon));
assert(are_equal(S_c(1,2), -0.51710, epsilon));
assert(are_equal(S_c(2,0), -0.70693, epsilon));
assert(are_equal(S_c(2,1), 0.12405, epsilon));
assert(are_equal(S_c(2,2), 0.69632, epsilon));
Matrix S_c = CGAL::Optimal_bounding_box::internal::mean(S_a, S_b, traits);
check_equality(S_c(0,0), -0.35111);
check_equality(S_c(0,1), 0.79308);
check_equality(S_c(0,2), -0.49774);
check_equality(S_c(1,0), -0.61398);
check_equality(S_c(1,1), -0.59635);
check_equality(S_c(1,2), -0.51710);
check_equality(S_c(2,0), -0.70693);
check_equality(S_c(2,1), 0.12405);
check_equality(S_c(2,2), 0.69632);
}
void test_centroid()
void test_centroid(const Traits& traits)
{
const double epsilon = 1e-5;
Matrix S_a;
S_a.set(0, 0, -0.588443); S_a.set(0, 1, 0.807140); S_a.set(0, 2, -0.047542);
S_a.set(1, 0, -0.786228); S_a.set(1, 1, -0.584933); S_a.set(1, 2, -0.199246);
S_a.set(2, 0, -0.188629); S_a.set(2, 1, -0.079867); S_a.set(2, 2, 0.978795);
Matrix S_b(3, 3);
Matrix S_b;
S_b.set(0, 0, -0.2192721); S_b.set(0, 1, 0.2792986); S_b.set(0, 2, -0.9348326);
S_b.set(1, 0, -0.7772152); S_b.set(1, 1, -0.6292092); S_b.set(1, 2, -0.005686);
S_b.set(2, 0, -0.5897934); S_b.set(2, 1, 0.7253193); S_b.set(2, 2, 0.3550431);
Matrix S_c(3, 3);
Matrix S_c;
S_c.set(0, 0, -0.32657); S_c.set(0, 1, -0.60013); S_c.set(0, 2, -0.730206);
S_c.set(1, 0, -0.20022); S_c.set(1, 1, -0.71110); S_c.set(1, 2, 0.67398);
S_c.set(2, 0, -0.92372); S_c.set(2, 1, 0.36630); S_c.set(2, 2, 0.11207);
Matrix S_centroid = CGAL::Optimal_bounding_box::nm_centroid<Linear_algebra_traits>(S_a, S_b, S_c);
assert(are_equal(S_centroid(0,0), -0.419979, epsilon));
assert(are_equal(S_centroid(0,1), 0.301765, epsilon));
assert(are_equal(S_centroid(0,2), -0.855894, epsilon));
assert(are_equal(S_centroid(1,0), -0.653011, epsilon));
assert(are_equal(S_centroid(1,1), -0.755415, epsilon));
assert(are_equal(S_centroid(1,2), 0.054087, epsilon));
assert(are_equal(S_centroid(2,0), -0.630234, epsilon));
assert(are_equal(S_centroid(2,1), 0.581624, epsilon));
assert(are_equal(S_centroid(2,2), 0.514314, epsilon));
Matrix S_centroid = CGAL::Optimal_bounding_box::internal::nm_centroid(S_a, S_b, S_c, traits);
check_equality(S_centroid(0,0), -0.419979);
check_equality(S_centroid(0,1), 0.301765);
check_equality(S_centroid(0,2), -0.855894);
check_equality(S_centroid(1,0), -0.653011);
check_equality(S_centroid(1,1), -0.755415);
check_equality(S_centroid(1,2), 0.054087);
check_equality(S_centroid(2,0), -0.630234);
check_equality(S_centroid(2,1), 0.581624);
check_equality(S_centroid(2,2), 0.514314);
}
void test_nelder_mead()
void test_nelder_mead(const Traits& traits)
{
std::array<Point_3, 4> points;
points[0] = Point_3(0.866802, 0.740808, 0.895304);
@ -116,21 +125,21 @@ void test_nelder_mead()
std::array<Matrix, 4> simplex;
Matrix v0, v1, v2, v3;
v0(0,0) = -0.2192721; v0(0,1) = 0.2792986; v0(0,2) = -0.9348326;
v0(1,0) = -0.7772152; v0(1,1) = -0.6292092; v0(1,2) = -0.0056861;
v0(2,0) = -0.5897934; v0(2,1) = 0.7253193; v0(2,2) = 0.3550431;
v0.set(0, 0, -0.2192721); v0.set(0, 1, 0.2792986); v0.set(0, 2, -0.9348326);
v0.set(1, 0, -0.7772152); v0.set(1, 1, -0.6292092); v0.set(1, 2, -0.0056861);
v0.set(2, 0, -0.5897934); v0.set(2, 1, 0.7253193); v0.set(2, 2, 0.3550431);
v1(0,0) = -0.588443; v1(0,1) = 0.807140; v1(0,2) = -0.047542;
v1(1,0) = -0.786228; v1(1,1) = -0.584933; v1(1,2) = -0.199246;
v1(2,0) = -0.188629; v1(2,1) = -0.079867; v1(2,2) = 0.978795;
v1.set(0, 0, -0.588443); v1.set(0, 1, 0.807140); v1.set(0, 2, -0.047542);
v1.set(1, 0, -0.786228); v1.set(1, 1, -0.584933); v1.set(1, 2, -0.199246);
v1.set(2, 0, -0.188629); v1.set(2, 1, -0.079867); v1.set(2, 2, 0.978795);
v2(0,0) = -0.277970; v2(0,1) = 0.953559; v2(0,2) = 0.116010;
v2(1,0) = -0.567497; v2(1,1) = -0.065576; v2(1,2) = -0.820760;
v2(2,0) = -0.775035; v2(2,1) = -0.293982; v2(2,2) = 0.559370;
v2.set(0, 0, -0.277970); v2.set(0, 1, 0.953559); v2.set(0, 2, 0.116010);
v2.set(1, 0, -0.567497); v2.set(1, 1, -0.065576); v2.set(1, 2, -0.820760);
v2.set(2, 0, -0.775035); v2.set(2, 1, -0.293982); v2.set(2, 2, 0.559370);
v3(0,0) = -0.32657; v3(0,1) = -0.60013; v3(0,2) = -0.73020;
v3(1,0) = -0.20022; v3(1,1) = -0.71110; v3(1,2) = 0.67398;
v3(2,0) = -0.92372; v3(2,1) = 0.36630; v3(2,2) = 0.11207;
v3.set(0, 0, -0.32657); v3.set(0, 1, -0.60013); v3.set(0, 2, -0.73020);
v3.set(1, 0, -0.20022); v3.set(1, 1, -0.71110); v3.set(1, 2, 0.67398);
v3.set(2, 0, -0.92372); v3.set(2, 1, 0.36630); v3.set(2, 2, 0.11207);
simplex[0] = v0;
simplex[1] = v1;
@ -138,59 +147,62 @@ void test_nelder_mead()
simplex[3] = v3;
std::size_t nm_iterations = 19;
CGAL::Optimal_bounding_box::internal::nelder_mead<Linear_algebra_traits>(simplex, data_points, nm_iterations);
CGAL::Optimal_bounding_box::internal::nelder_mead(points, nm_iterations, traits, simplex);
double epsilon = 1e-5;
const Matrix& v0_new = simplex[0];
assert(assert_doubles(v0_new(0,0), -0.288975, epsilon));
assert(assert_doubles(v0_new(0,1), 0.7897657, epsilon));
assert(assert_doubles(v0_new(0,2), -0.541076, epsilon));
assert(assert_doubles(v0_new(1,0), -0.9407046, epsilon));
assert(assert_doubles(v0_new(1,1), -0.3391466, epsilon));
assert(assert_doubles(v0_new(1,2), 0.0073817, epsilon));
assert(assert_doubles(v0_new(2,0), -0.1776743, epsilon));
assert(assert_doubles(v0_new(2,1), 0.5111260, epsilon));
assert(assert_doubles(v0_new(2,2), 0.84094, epsilon));
check_equality(v0_new(0,0), -0.288975);
check_equality(v0_new(0,1), 0.7897657);
check_equality(v0_new(0,2), -0.541076);
check_equality(v0_new(1,0), -0.9407046);
check_equality(v0_new(1,1), -0.3391466);
check_equality(v0_new(1,2), 0.0073817);
check_equality(v0_new(2,0), -0.1776743);
check_equality(v0_new(2,1), 0.5111260);
check_equality(v0_new(2,2), 0.84094);
const Matrix& v1_new = simplex[1];
assert(assert_doubles(v1_new(0,0), -0.458749, epsilon));
assert(assert_doubles(v1_new(0,1), 0.823283, epsilon));
assert(assert_doubles(v1_new(0,2), -0.334296, epsilon));
assert(assert_doubles(v1_new(1,0), -0.885235, epsilon));
assert(assert_doubles(v1_new(1,1), -0.455997, epsilon));
assert(assert_doubles(v1_new(1,2), 0.091794, epsilon));
assert(assert_doubles(v1_new(2,0), -0.076866, epsilon));
assert(assert_doubles(v1_new(2,1), 0.338040, epsilon));
assert(assert_doubles(v1_new(2,2), 0.937987, epsilon));
check_equality(v1_new(0,0), -0.458749);
check_equality(v1_new(0,1), 0.823283);
check_equality(v1_new(0,2), -0.334296);
check_equality(v1_new(1,0), -0.885235);
check_equality(v1_new(1,1), -0.455997);
check_equality(v1_new(1,2), 0.091794);
check_equality(v1_new(2,0), -0.076866);
check_equality(v1_new(2,1), 0.338040);
check_equality(v1_new(2,2), 0.937987);
const Matrix& v2_new = simplex[2];
assert(assert_doubles(v2_new(0,0), -0.346582, epsilon));
assert(assert_doubles(v2_new(0,1), 0.878534, epsilon));
assert(assert_doubles(v2_new(0,2), -0.328724, epsilon));
assert(assert_doubles(v2_new(1,0), -0.936885, epsilon));
assert(assert_doubles(v2_new(1,1), -0.341445, epsilon));
assert(assert_doubles(v2_new(1,2), 0.075251, epsilon));
assert(assert_doubles(v2_new(2,0), -0.046131, epsilon));
assert(assert_doubles(v2_new(2,1), 0.334057, epsilon));
assert(assert_doubles(v2_new(2,2), 0.941423, epsilon));
check_equality(v2_new(0,0), -0.346582);
check_equality(v2_new(0,1), 0.878534);
check_equality(v2_new(0,2), -0.328724);
check_equality(v2_new(1,0), -0.936885);
check_equality(v2_new(1,1), -0.341445);
check_equality(v2_new(1,2), 0.075251);
check_equality(v2_new(2,0), -0.046131);
check_equality(v2_new(2,1), 0.334057);
check_equality(v2_new(2,2), 0.941423);
const Matrix& v3_new = simplex[3];
assert(assert_doubles(v3_new(0,0), -0.394713, epsilon));
assert(assert_doubles(v3_new(0,1), 0.791782, epsilon));
assert(assert_doubles(v3_new(0,2), -0.466136, epsilon));
assert(assert_doubles(v3_new(1,0), -0.912112, epsilon));
assert(assert_doubles(v3_new(1,1), -0.398788, epsilon));
assert(assert_doubles(v3_new(1,2), 0.094972, epsilon));
assert(assert_doubles(v3_new(2,0), -0.110692, epsilon));
assert(assert_doubles(v3_new(2,1), 0.462655, epsilon));
assert(assert_doubles(v3_new(2,2), 0.879601, epsilon));
check_equality(v3_new(0,0), -0.394713);
check_equality(v3_new(0,1), 0.791782);
check_equality(v3_new(0,2), -0.466136);
check_equality(v3_new(1,0), -0.912112);
check_equality(v3_new(1,1), -0.398788);
check_equality(v3_new(1,2), 0.094972);
check_equality(v3_new(2,0), -0.110692);
check_equality(v3_new(2,1), 0.462655);
check_equality(v3_new(2,2), 0.879601);
}
int main()
int main(int, char**)
{
test_simplex_operations();
test_centroid();
test_nelder_mead();
Traits traits;
return 0;
test_simplex_operations(traits);
test_centroid(traits);
test_nelder_mead(traits);
std::cout << "Done!" << std::endl;
return EXIT_SUCCESS;
}

View File

@ -2,75 +2,62 @@
#include <CGAL/Surface_mesh.h>
#include <CGAL/Eigen_linear_algebra_traits.h>
#include <CGAL/Optimal_bounding_box/population.h>
#include <CGAL/Optimal_bounding_box/optimal_bounding_box.h>
#include <CGAL/Optimal_bounding_box/helper.h>
#include <CGAL/Optimal_bounding_box/nelder_mead_functions.h>
#include <CGAL/optimal_bounding_box.h>
#include <array>
#include <iostream>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT FT;
typedef K::Point_3 Point_3;
bool assert_doubles(double d1, double d2, double epsilon)
typedef CGAL::Surface_mesh<Point> Mesh;
typedef CGAL::Oriented_bounding_box_traits_3<K> Traits;
typedef Traits::Matrix Matrix;
void check_equality(const FT d1, const FT d2)
{
return (d1 < d2 + epsilon && d1 > d2 - epsilon) ? true : false;
const FT epsilon = 1e-3;
bool ok;
if(std::is_floating_point<FT>::value)
ok = CGAL::abs(d1 - d2) < epsilon * CGAL::abs(d2);
else
ok = (d1 == d2);
if(!ok)
{
std::cout << "Error: got " << d1 << " but expected: " << d2 << std::endl;
assert(false);
}
}
void test_genetic_algorithm()
{
CGAL::Eigen_dense_matrix<double, -1, -1> data_points(4, 3); // -1 = dynamic size at run time
data_points(0,0) = 0.866802;
data_points(0,1) = 0.740808;
data_points(0,2) = 0.895304;
data_points(1,0) = 0.912651;
data_points(1,1) = 0.761565;
data_points(1,2) = 0.160330;
data_points(2,0) = 0.093661;
data_points(2,1) = 0.892578;
data_points(2,2) = 0.737412;
data_points(3,0) = 0.166461;
data_points(3,1) = 0.149912;
data_points(3,2) = 0.364944;
std::array<Point_3, 4> points;
points[0] = Point_3(0.866802, 0.740808, 0.895304);
points[1] = Point_3(0.912651, 0.761565, 0.160330);
points[2] = Point_3(0.093661, 0.892578, 0.737412);
points[3] = Point_3(0.166461, 0.149912, 0.364944);
typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits;
CGAL::Optimal_bounding_box::Population<Linear_algebra_traits> pop(5);
CGAL::Optimal_bounding_box::Evolution<Linear_algebra_traits> evolution(pop, data_points);
CGAL::Optimal_bounding_box::internal::Population<Traits> pop(5);
CGAL::Optimal_bounding_box::internal::Evolution<Traits> evolution(pop, data_points);
evolution.genetic_algorithm();
assert(pop.size() == 5);
}
void test_random_unit_tetra()
{
// this is dynamic at run times
CGAL::Eigen_dense_matrix<double, -1, -1> data_points(4, 3);
std::array<Point_3, 4> points;
points[0] = Point_3(0.866802, 0.740808, 0.895304);
points[1] = Point_3(0.912651, 0.761565, 0.160330);
points[2] = Point_3(0.093661, 0.892578, 0.737412);
points[3] = Point_3(0.166461, 0.149912, 0.364944);
// points are on their convex hull
data_points(0,0) = 0.866802;
data_points(0,1) = 0.740808;
data_points(0,2) = 0.895304;
data_points(1,0) = 0.912651;
data_points(1,1) = 0.761565;
data_points(1,2) = 0.160330;
data_points(2,0) = 0.093661;
data_points(2,1) = 0.892578;
data_points(2,2) = 0.737412;
data_points(3,0) = 0.166461;
data_points(3,1) = 0.149912;
data_points(3,2) = 0.364944;
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_3 Point;
typedef CGAL::Surface_mesh<Point> Mesh;
// 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);
CGAL::make_tetrahedron(points[0], points[1], points[2], points[3], mesh);
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_TEST
std::ofstream out("data/random_unit_tetra.off");
@ -78,148 +65,102 @@ void test_random_unit_tetra()
out.close();
#endif
typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits;
typedef Linear_algebra_traits::Matrix Matrix;
std::size_t generations = 10;
CGAL::Optimal_bounding_box::Population<Linear_algebra_traits> pop(50);
CGAL::Optimal_bounding_box::Evolution<Linear_algebra_traits> evolution(pop, data_points);
CGAL::Optimal_bounding_box::internal::Population<Traits> pop(50);
CGAL::Optimal_bounding_box::internal::Evolution<Traits> evolution(pop, data_points);
evolution.evolve(generations);
Matrix R = evolution.get_best();
const double epsilon = 1e-3;
assert(assert_doubles(Linear_algebra_traits::compute_determinant(R), 1, epsilon));
assert(assert_doubles(R(0,0), -0.25791, epsilon));
assert(assert_doubles(R(0,1), 0.796512, epsilon));
assert(assert_doubles(R(0,2), -0.546855, epsilon));
assert(assert_doubles(R(1,0), -0.947128, epsilon));
assert(assert_doubles(R(1,1), -0.320242, epsilon));
assert(assert_doubles(R(1,2), -0.0197553, epsilon));
assert(assert_doubles(R(2,0), -0.190861, epsilon));
assert(assert_doubles(R(2,1), 0.512847, epsilon));
assert(assert_doubles(R(2,2), 0.836992, epsilon));
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_TEST
// postprocessing
CGAL::Eigen_dense_matrix<double> obb(8, 3);
CGAL::Optimal_bounding_box::post_processing(data_points, R, obb);
#endif
check_equality(Traits::compute_determinant(R), 1);
check_equality(R(0,0), -0.25791);
check_equality(R(0,1), 0.796512);
check_equality(R(0,2), -0.546855);
check_equality(R(1,0), -0.947128);
check_equality(R(1,1), -0.320242);
check_equality(R(1,2), -0.0197553);
check_equality(R(2,0), -0.190861);
check_equality(R(2,1), 0.512847);
check_equality(R(2,2), 0.836992);
}
void test_reference_tetrahedron(const char* fname)
{
std::ifstream input(fname);
CGAL::Surface_mesh<K::Point_3> mesh;
if (!input || !(input >> mesh) || mesh.is_empty()) {
CGAL::Surface_mesh<Point_3> mesh;
if(!input || !(input >> mesh) || mesh.is_empty())
{
std::cerr << fname << " is not a valid off file.\n";
std::exit(1);
}
typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits;
typedef Linear_algebra_traits::Matrix Matrix;
// points in a matrix
Matrix points;
CGAL::Optimal_bounding_box::sm_to_matrix(mesh, points);
std::size_t generations = 10;
CGAL::Optimal_bounding_box::Population<Linear_algebra_traits> pop(50);
CGAL::Optimal_bounding_box::Evolution<Linear_algebra_traits> experiment(pop, points);
CGAL::Optimal_bounding_box::internal::Population<Traits> pop(50);
CGAL::Optimal_bounding_box::internal::Evolution<Traits> experiment(pop, points);
experiment.evolve(generations);
Matrix R = experiment.get_best();
double epsilon = 1e-5;
assert(assert_doubles(Linear_algebra_traits::compute_determinant(R), 1, epsilon));
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_TEST
// postprocessing
Matrix obb(8, 3);
CGAL::Optimal_bounding_box::post_processing(points, R, obb);
#endif
check_equality(Traits::compute_determinant(R), 1);
}
void test_long_tetrahedron(const std::string fname)
{
std::ifstream input(fname);
CGAL::Surface_mesh<K::Point_3> mesh;
if (!input || !(input >> mesh) || mesh.is_empty())
CGAL::Surface_mesh<Point_3> mesh;
if(!input || !(input >> mesh) || mesh.is_empty())
{
std::cerr << fname << " is not a valid off file.\n";
std::exit(1);
}
typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits;
typedef Linear_algebra_traits::Matrix Matrix;
// points in a matrix
Matrix points;
CGAL::Optimal_bounding_box::sm_to_matrix(mesh, points);
std::size_t max_generations = 10;
CGAL::Optimal_bounding_box::Population<Linear_algebra_traits> pop(50);
CGAL::Optimal_bounding_box::Evolution<Linear_algebra_traits> experiment(pop, points);
CGAL::Optimal_bounding_box::internal::Population<Traits> pop(50);
CGAL::Optimal_bounding_box::internal::Evolution<Traits> experiment(pop, points);
experiment.evolve(max_generations);
Matrix R = experiment.get_best();
double epsilon = 1e-3;
assert(assert_doubles(Linear_algebra_traits::compute_determinant(R), 1, epsilon));
assert(assert_doubles(R(0,0), -1, epsilon));
assert(assert_doubles(R(0,1), 0, epsilon));
assert(assert_doubles(R(0,2), 0, epsilon));
assert(assert_doubles(R(1,0), 0, epsilon));
assert(assert_doubles(R(1,1), -0.707107, epsilon));
assert(assert_doubles(R(1,2), 0.707106, epsilon) ||
assert_doubles(R(1,2), -0.707106, epsilon));
assert(assert_doubles(R(2,0), 0, epsilon));
assert(assert_doubles(R(2,1), 0.707106, epsilon) ||
assert_doubles(R(1,2), -0.707106, epsilon));
assert(assert_doubles(R(2,2), 0.707107, epsilon));
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_TEST
// postprocessing
Matrix obb(8, 3);
CGAL::Optimal_bounding_box::post_processing(points, R, obb);
#endif
check_equality(Traits::compute_determinant(R), 1);
check_equality(R(0,0), -1);
check_equality(R(0,1), 0);
check_equality(R(0,2), 0);
check_equality(R(1,0), 0);
check_equality(R(1,1), -0.707107);
check_equality(R(1,2), 0.707106) || assert_doubles(R(1,2), -0.707106);
check_equality(R(2,0), 0);
check_equality(R(2,1), 0.707106) || assert_doubles(R(1,2), -0.707106);
check_equality(R(2,2), 0.707107);
}
void test_compute_obb_evolution(const std::string fname)
{
std::ifstream input(fname);
typedef CGAL::Surface_mesh<K::Point_3> SMesh;
typedef CGAL::Surface_mesh<Point_3> SMesh;
SMesh mesh;
if (!input || !(input >> mesh) || mesh.is_empty())
if(!input || !(input >> mesh) || mesh.is_empty())
{
std::cerr << fname << " is not a valid off file.\n";
std::exit(1);
}
// get mesh points
std::vector<K::Point_3> sm_points;
Traits traits;
std::array<Point_3, 8> obb_points;
CGAL::oriented_bounding_box(sm, obb_points, CGAL::parameters::use_convex_hull(true)
.geom_traits(traits));
typedef typename boost::graph_traits<SMesh>::vertex_descriptor vertex_descriptor;
typedef typename boost::property_map<SMesh, boost::vertex_point_t>::const_type PointPMap;
PointPMap pmap = get(boost::vertex_point, mesh);
for(vertex_descriptor v : vertices(mesh))
sm_points.push_back(get(pmap, v));
CGAL::Eigen_linear_algebra_traits la_traits;
std::vector<K::Point_3> obb_points;
CGAL::Optimal_bounding_box::compute_optimal_bounding_box(sm_points, obb_points, la_traits, true);
double epsilon = 1e-3;
double vol = CGAL::Optimal_bounding_box::calculate_volume(obb_points);
assert(assert_doubles(vol, 0.883371, epsilon));
FT vol = CGAL::Optimal_bounding_box::calculate_volume(obb_points);
check_equality(vol, 0.883371);
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_TEST
/*
for(int i = 0; i < 8; ++i)
std::cout << obb_points[i].x() << " " << obb_points[i].y() << " " << obb_points[i].z() << "\n" ;
*/
CGAL::Surface_mesh<K::Point_3> result_mesh;
CGAL::Surface_mesh<Point_3> result_mesh;
CGAL::make_hexahedron(obb_points[0], obb_points[1], obb_points[2], obb_points[3],
obb_points[4], obb_points[5], obb_points[6], obb_points[7], result_mesh);
obb_points[4], obb_points[5], obb_points[6], obb_points[7], result_mesh);
std::ofstream out("data/obb_result.off");
out << result_mesh;
@ -230,16 +171,15 @@ void test_compute_obb_evolution(const std::string fname)
void test_compute_obb_mesh(const std::string fname)
{
std::ifstream input(fname);
CGAL::Surface_mesh<K::Point_3> mesh;
if (!input || !(input >> mesh) || mesh.is_empty())
CGAL::Surface_mesh<Point_3> mesh;
if(!input || !(input >> mesh) || mesh.is_empty())
{
std::cerr << fname << " is not a valid off file.\n";
std::exit(1);
}
CGAL::Eigen_linear_algebra_traits la_traits;
CGAL::Surface_mesh< K::Point_3> obbmesh;
CGAL::Optimal_bounding_box::compute_optimal_bounding_box(mesh, obbmesh, la_traits, true);
CGAL::Surface_mesh<Point_3> obbmesh;
CGAL::oriented_bounding_box(mesh, obbmesh);
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_TEST
std::ofstream out("/tmp/result_elephant.off");
@ -248,46 +188,21 @@ void test_compute_obb_mesh(const std::string fname)
#endif
}
void test_function_defaults_traits(const std::string fname1,
const std::string fname2)
void test_function_defaults_traits(const std::string fname1)
{
std::ifstream input1(fname1);
CGAL::Surface_mesh<K::Point_3> mesh1;
if (!input1 || !(input1 >> mesh1) || mesh1.is_empty())
CGAL::Surface_mesh<Point_3> mesh1;
if(!input1 || !(input1 >> mesh1) || mesh1.is_empty())
{
std::cerr << fname1 << " is not a valid off file.\n";
std::exit(1);
}
std::ifstream input2(fname2);
CGAL::Surface_mesh<K::Point_3> mesh2;
if (!input2 || !(input2 >> mesh2) || mesh2.is_empty())
{
std::cerr << fname2 << " is not a valid off file.\n";
std::exit(1);
}
std::array<Point_3, 8> obb_points;
CGAL::oriented_bounding_box(sm_points, obb_points, CGAL::parameters::use_convex_hull(true));
// test one
std::vector<K::Point_3> sm_points;
typedef CGAL::Surface_mesh<K::Point_3> SMesh;
typedef typename boost::graph_traits<SMesh>::vertex_descriptor vertex_descriptor;
typedef typename boost::property_map<SMesh, boost::vertex_point_t>::const_type PointPMap;
PointPMap pmap = get(boost::vertex_point, mesh1);
for(vertex_descriptor v : vertices(mesh1))
sm_points.push_back(get(pmap, v));
std::vector<K::Point_3> obb_points;
CGAL::Optimal_bounding_box::compute_optimal_bounding_box(sm_points, obb_points, true);
const double epsilon = 1e-3;
const double vol = CGAL::Optimal_bounding_box::calculate_volume(obb_points);
assert(assert_doubles(vol, 0.883371, epsilon));
// test two
CGAL::Surface_mesh<K::Point_3> obbmesh;
CGAL::Optimal_bounding_box::compute_optimal_bounding_box(mesh2, obbmesh, true);
const FT vol = CGAL::Optimal_bounding_box::calculate_volume(obb_points);
check_equality(vol, 0.883371);
}
int main()
@ -299,7 +214,7 @@ int main()
test_long_tetrahedron("data/long_tetrahedron.off");
test_compute_obb_evolution("data/random_unit_tetra.off");
test_compute_obb_mesh("data/elephant.off");
test_function_defaults_traits("data/random_unit_tetra.off", "data/elephant.off");
test_function_defaults_traits("data/random_unit_tetra.off");
return 0;
}