mirror of https://github.com/CGAL/cgal
parent
9df21ba79d
commit
a7f0473c5c
|
|
@ -48,6 +48,7 @@ void bench_finding_obb(const std::string fname)
|
||||||
convex_hull_3(mesh, poly);
|
convex_hull_3(mesh, poly);
|
||||||
timer.stop();
|
timer.stop();
|
||||||
std::cout << "takes : " << timer.time() << " seconds to find the convex hull\n";
|
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
|
// 2) using convex hull
|
||||||
timer.reset();
|
timer.reset();
|
||||||
|
|
|
||||||
|
|
@ -1,135 +1,141 @@
|
||||||
#include <CGAL/Eigen_linear_algebra_traits.h>
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
#include <CGAL/Optimal_bounding_box/nelder_mead_functions.h>
|
|
||||||
#include <CGAL/Optimal_bounding_box/fitness_function.h>
|
#include <CGAL/optimal_bounding_box.h>
|
||||||
|
|
||||||
#include <CGAL/assertions.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()
|
void test_fitness_function()
|
||||||
{
|
{
|
||||||
typedef typename CGAL::Eigen_linear_algebra_traits::MatrixXd MatrixXd;
|
std::array<Point_3, 4> points;
|
||||||
MatrixXd data_points(4, 3);
|
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);
|
Matrix rotation;
|
||||||
data_points.set_coef(0, 1, 0.740808);
|
rotation.set(0, 0, -0.809204);
|
||||||
data_points.set_coef(0, 2, 0.895304);
|
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);
|
const double fitness = CGAL::Optimal_bounding_box::internal::compute_fitness<Traits>(rotation, points);
|
||||||
data_points.set_coef(1, 1, 0.761565);
|
check_equality(fitness, 0.58606);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void test_eigen_matrix_interface()
|
void test_eigen_matrix_interface()
|
||||||
{
|
{
|
||||||
CGAL_assertion_code(typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits);
|
Matrix A;
|
||||||
typedef CGAL::Eigen_dense_matrix<double, 3, 3> Matrix;
|
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);
|
Matrix B;
|
||||||
A.set_coef(0, 0, 0.1);
|
B = CGAL::Optimal_bounding_box::internal::transpose(A);
|
||||||
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);
|
|
||||||
|
|
||||||
CGAL_assertion_code(Matrix Q = CGAL::Eigen_linear_algebra_traits::get_Q(C));
|
Matrix S;
|
||||||
CGAL_assertion_code(double epsilon = 1e-5);
|
S = 0.5 * A;
|
||||||
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 D(3,3);
|
Matrix C;
|
||||||
D.set_coef(0, 0, -0.809204);
|
C.set(0, 0, 0.3011944);
|
||||||
D.set_coef(0, 1, 0.124296);
|
C.set(0, 1, 0.9932761);
|
||||||
D.set_coef(0, 2, 0.574230);
|
C.set(0, 2, 0.5483701);
|
||||||
D.set_coef(1, 0, -0.574694);
|
C.set(1, 0, 0.5149142);
|
||||||
D.set_coef(1, 1, 0.035719);
|
C.set(1, 1, 0.5973263);
|
||||||
D.set_coef(1, 2, -0.817589);
|
C.set(1, 2, 0.5162336);
|
||||||
D.set_coef(2, 0, -0.122134);
|
C.set(2, 0, 0.0039213);
|
||||||
D.set_coef(2, 1, -0.991602);
|
C.set(2, 1, 0.0202949);
|
||||||
D.set_coef(2, 2, 0.042528);
|
C.set(2, 2, 0.9240308);
|
||||||
|
|
||||||
Matrix E(3,3);
|
Matrix Q = Traits::get_Q(C);
|
||||||
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);
|
|
||||||
|
|
||||||
CGAL_assertion_code(Matrix Sr = CGAL::Optimal_bounding_box::reflection<Linear_algebra_traits>(D, E));
|
check_equality(Q(0,0), -0.504895);
|
||||||
CGAL_assertion(assert_doubles(Sr(0,0), -0.13359, epsilon));
|
check_equality(Q(0,1), 0.862834);
|
||||||
CGAL_assertion(assert_doubles(Sr(0,1), -0.95986, epsilon));
|
check_equality(Q(0,2), -0.024447);
|
||||||
CGAL_assertion(assert_doubles(Sr(0,2), -0.24664, epsilon));
|
check_equality(Q(1,0), -0.863156);
|
||||||
CGAL_assertion(assert_doubles(Sr(1,0), -0.60307, epsilon));
|
check_equality(Q(1,1), -0.504894);
|
||||||
CGAL_assertion(assert_doubles(Sr(1,1), -0.11875, epsilon));
|
check_equality(Q(1,2), 0.006687);
|
||||||
CGAL_assertion(assert_doubles(Sr(1,2), 0.78880, epsilon));
|
check_equality(Q(2,0), -0.006573);
|
||||||
CGAL_assertion(assert_doubles(Sr(2,0), -0.78642, epsilon));
|
check_equality(Q(2,1), 0.024478);
|
||||||
CGAL_assertion(assert_doubles(Sr(2,1), 0.25411, epsilon));
|
check_equality(Q(2,2), 0.999679);
|
||||||
CGAL_assertion(assert_doubles(Sr(2,2), -0.56300, epsilon));
|
|
||||||
|
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_fitness_function();
|
||||||
test_eigen_matrix_interface();
|
test_eigen_matrix_interface();
|
||||||
|
|
||||||
return 0;
|
std::cout << "Done!" << std::endl;
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,106 +5,115 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
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;
|
typedef K::Point_3 Point_3;
|
||||||
|
|
||||||
typedef CGAL::Oriented_bounding_box_traits_3<K> Traits;
|
typedef CGAL::Oriented_bounding_box_traits_3<K> Traits;
|
||||||
typedef Traits::Matrix Matrix;
|
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;
|
||||||
|
|
||||||
Matrix Sc(3, 3);
|
|
||||||
Sc.set(0, 0, -0.809204); Sc.set(0, 1, 0.124296); Sc.set(0, 2, 0.574230);
|
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(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);
|
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(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(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);
|
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);
|
Matrix Sr = CGAL::Optimal_bounding_box::internal::reflection(Sc, S_worst);
|
||||||
assert(are_equal(Sr(0,0), -0.13359, epsilon));
|
check_equality(Sr(0,0), -0.13359);
|
||||||
assert(are_equal(Sr(0,1), -0.95986, epsilon));
|
check_equality(Sr(0,1), -0.95986);
|
||||||
assert(are_equal(Sr(0,2), -0.24664, epsilon));
|
check_equality(Sr(0,2), -0.24664);
|
||||||
assert(are_equal(Sr(1,0), -0.60307, epsilon));
|
check_equality(Sr(1,0), -0.60307);
|
||||||
assert(are_equal(Sr(1,1), -0.11875, epsilon));
|
check_equality(Sr(1,1), -0.11875);
|
||||||
assert(are_equal(Sr(1,2), 0.78880, epsilon));
|
check_equality(Sr(1,2), 0.78880);
|
||||||
assert(are_equal(Sr(2,0), -0.78642, epsilon));
|
check_equality(Sr(2,0), -0.78642);
|
||||||
assert(are_equal(Sr(2,1), 0.25411, epsilon));
|
check_equality(Sr(2,1), 0.25411);
|
||||||
assert(are_equal(Sr(2,2), -0.56300, epsilon));
|
check_equality(Sr(2,2), -0.56300);
|
||||||
|
|
||||||
Matrix Se = CGAL::Optimal_bounding_box::expansion<Linear_algebra_traits>(Sc, S_worst, Sr);
|
Matrix Se = CGAL::Optimal_bounding_box::internal::expansion(Sc, S_worst, Sr);
|
||||||
assert(are_equal(Se(0,0), -0.87991, epsilon));
|
check_equality(Se(0,0), -0.87991);
|
||||||
assert(are_equal(Se(0,1), 0.36105, epsilon));
|
check_equality(Se(0,1), 0.36105);
|
||||||
assert(are_equal(Se(0,2), -0.30888, epsilon));
|
check_equality(Se(0,2), -0.30888);
|
||||||
assert(are_equal(Se(1,0), -0.11816, epsilon));
|
check_equality(Se(1,0), -0.11816);
|
||||||
assert(are_equal(Se(1,1), -0.79593, epsilon));
|
check_equality(Se(1,1), -0.79593);
|
||||||
assert(are_equal(Se(1,2), -0.59375, epsilon));
|
check_equality(Se(1,2), -0.59375);
|
||||||
assert(are_equal(Se(2,0), -0.460215, epsilon));
|
check_equality(Se(2,0), -0.460215);
|
||||||
assert(are_equal(Se(2,1), -0.48595, epsilon));
|
check_equality(Se(2,1), -0.48595);
|
||||||
assert(are_equal(Se(2,2), 0.74300, epsilon));
|
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(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(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);
|
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(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(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);
|
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);
|
Matrix S_c = CGAL::Optimal_bounding_box::internal::mean(S_a, S_b, traits);
|
||||||
assert(are_equal(S_c(0,0), -0.35111, epsilon));
|
check_equality(S_c(0,0), -0.35111);
|
||||||
assert(are_equal(S_c(0,1), 0.79308, epsilon));
|
check_equality(S_c(0,1), 0.79308);
|
||||||
assert(are_equal(S_c(0,2), -0.49774, epsilon));
|
check_equality(S_c(0,2), -0.49774);
|
||||||
assert(are_equal(S_c(1,0), -0.61398, epsilon));
|
check_equality(S_c(1,0), -0.61398);
|
||||||
assert(are_equal(S_c(1,1), -0.59635, epsilon));
|
check_equality(S_c(1,1), -0.59635);
|
||||||
assert(are_equal(S_c(1,2), -0.51710, epsilon));
|
check_equality(S_c(1,2), -0.51710);
|
||||||
assert(are_equal(S_c(2,0), -0.70693, epsilon));
|
check_equality(S_c(2,0), -0.70693);
|
||||||
assert(are_equal(S_c(2,1), 0.12405, epsilon));
|
check_equality(S_c(2,1), 0.12405);
|
||||||
assert(are_equal(S_c(2,2), 0.69632, epsilon));
|
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;
|
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(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(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);
|
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(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(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);
|
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(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(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);
|
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);
|
Matrix S_centroid = CGAL::Optimal_bounding_box::internal::nm_centroid(S_a, S_b, S_c, traits);
|
||||||
assert(are_equal(S_centroid(0,0), -0.419979, epsilon));
|
check_equality(S_centroid(0,0), -0.419979);
|
||||||
assert(are_equal(S_centroid(0,1), 0.301765, epsilon));
|
check_equality(S_centroid(0,1), 0.301765);
|
||||||
assert(are_equal(S_centroid(0,2), -0.855894, epsilon));
|
check_equality(S_centroid(0,2), -0.855894);
|
||||||
assert(are_equal(S_centroid(1,0), -0.653011, epsilon));
|
check_equality(S_centroid(1,0), -0.653011);
|
||||||
assert(are_equal(S_centroid(1,1), -0.755415, epsilon));
|
check_equality(S_centroid(1,1), -0.755415);
|
||||||
assert(are_equal(S_centroid(1,2), 0.054087, epsilon));
|
check_equality(S_centroid(1,2), 0.054087);
|
||||||
assert(are_equal(S_centroid(2,0), -0.630234, epsilon));
|
check_equality(S_centroid(2,0), -0.630234);
|
||||||
assert(are_equal(S_centroid(2,1), 0.581624, epsilon));
|
check_equality(S_centroid(2,1), 0.581624);
|
||||||
assert(are_equal(S_centroid(2,2), 0.514314, epsilon));
|
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;
|
std::array<Point_3, 4> points;
|
||||||
points[0] = Point_3(0.866802, 0.740808, 0.895304);
|
points[0] = Point_3(0.866802, 0.740808, 0.895304);
|
||||||
|
|
@ -116,21 +125,21 @@ void test_nelder_mead()
|
||||||
std::array<Matrix, 4> simplex;
|
std::array<Matrix, 4> simplex;
|
||||||
|
|
||||||
Matrix v0, v1, v2, v3;
|
Matrix v0, v1, v2, v3;
|
||||||
v0(0,0) = -0.2192721; v0(0,1) = 0.2792986; v0(0,2) = -0.9348326;
|
v0.set(0, 0, -0.2192721); v0.set(0, 1, 0.2792986); v0.set(0, 2, -0.9348326);
|
||||||
v0(1,0) = -0.7772152; v0(1,1) = -0.6292092; v0(1,2) = -0.0056861;
|
v0.set(1, 0, -0.7772152); v0.set(1, 1, -0.6292092); v0.set(1, 2, -0.0056861);
|
||||||
v0(2,0) = -0.5897934; v0(2,1) = 0.7253193; v0(2,2) = 0.3550431;
|
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.set(0, 0, -0.588443); v1.set(0, 1, 0.807140); v1.set(0, 2, -0.047542);
|
||||||
v1(1,0) = -0.786228; v1(1,1) = -0.584933; v1(1,2) = -0.199246;
|
v1.set(1, 0, -0.786228); v1.set(1, 1, -0.584933); v1.set(1, 2, -0.199246);
|
||||||
v1(2,0) = -0.188629; v1(2,1) = -0.079867; v1(2,2) = 0.978795;
|
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.set(0, 0, -0.277970); v2.set(0, 1, 0.953559); v2.set(0, 2, 0.116010);
|
||||||
v2(1,0) = -0.567497; v2(1,1) = -0.065576; v2(1,2) = -0.820760;
|
v2.set(1, 0, -0.567497); v2.set(1, 1, -0.065576); v2.set(1, 2, -0.820760);
|
||||||
v2(2,0) = -0.775035; v2(2,1) = -0.293982; v2(2,2) = 0.559370;
|
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.set(0, 0, -0.32657); v3.set(0, 1, -0.60013); v3.set(0, 2, -0.73020);
|
||||||
v3(1,0) = -0.20022; v3(1,1) = -0.71110; v3(1,2) = 0.67398;
|
v3.set(1, 0, -0.20022); v3.set(1, 1, -0.71110); v3.set(1, 2, 0.67398);
|
||||||
v3(2,0) = -0.92372; v3(2,1) = 0.36630; v3(2,2) = 0.11207;
|
v3.set(2, 0, -0.92372); v3.set(2, 1, 0.36630); v3.set(2, 2, 0.11207);
|
||||||
|
|
||||||
simplex[0] = v0;
|
simplex[0] = v0;
|
||||||
simplex[1] = v1;
|
simplex[1] = v1;
|
||||||
|
|
@ -138,59 +147,62 @@ void test_nelder_mead()
|
||||||
simplex[3] = v3;
|
simplex[3] = v3;
|
||||||
|
|
||||||
std::size_t nm_iterations = 19;
|
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];
|
const Matrix& v0_new = simplex[0];
|
||||||
assert(assert_doubles(v0_new(0,0), -0.288975, epsilon));
|
check_equality(v0_new(0,0), -0.288975);
|
||||||
assert(assert_doubles(v0_new(0,1), 0.7897657, epsilon));
|
check_equality(v0_new(0,1), 0.7897657);
|
||||||
assert(assert_doubles(v0_new(0,2), -0.541076, epsilon));
|
check_equality(v0_new(0,2), -0.541076);
|
||||||
assert(assert_doubles(v0_new(1,0), -0.9407046, epsilon));
|
check_equality(v0_new(1,0), -0.9407046);
|
||||||
assert(assert_doubles(v0_new(1,1), -0.3391466, epsilon));
|
check_equality(v0_new(1,1), -0.3391466);
|
||||||
assert(assert_doubles(v0_new(1,2), 0.0073817, epsilon));
|
check_equality(v0_new(1,2), 0.0073817);
|
||||||
assert(assert_doubles(v0_new(2,0), -0.1776743, epsilon));
|
check_equality(v0_new(2,0), -0.1776743);
|
||||||
assert(assert_doubles(v0_new(2,1), 0.5111260, epsilon));
|
check_equality(v0_new(2,1), 0.5111260);
|
||||||
assert(assert_doubles(v0_new(2,2), 0.84094, epsilon));
|
check_equality(v0_new(2,2), 0.84094);
|
||||||
|
|
||||||
const Matrix& v1_new = simplex[1];
|
const Matrix& v1_new = simplex[1];
|
||||||
assert(assert_doubles(v1_new(0,0), -0.458749, epsilon));
|
check_equality(v1_new(0,0), -0.458749);
|
||||||
assert(assert_doubles(v1_new(0,1), 0.823283, epsilon));
|
check_equality(v1_new(0,1), 0.823283);
|
||||||
assert(assert_doubles(v1_new(0,2), -0.334296, epsilon));
|
check_equality(v1_new(0,2), -0.334296);
|
||||||
assert(assert_doubles(v1_new(1,0), -0.885235, epsilon));
|
check_equality(v1_new(1,0), -0.885235);
|
||||||
assert(assert_doubles(v1_new(1,1), -0.455997, epsilon));
|
check_equality(v1_new(1,1), -0.455997);
|
||||||
assert(assert_doubles(v1_new(1,2), 0.091794, epsilon));
|
check_equality(v1_new(1,2), 0.091794);
|
||||||
assert(assert_doubles(v1_new(2,0), -0.076866, epsilon));
|
check_equality(v1_new(2,0), -0.076866);
|
||||||
assert(assert_doubles(v1_new(2,1), 0.338040, epsilon));
|
check_equality(v1_new(2,1), 0.338040);
|
||||||
assert(assert_doubles(v1_new(2,2), 0.937987, epsilon));
|
check_equality(v1_new(2,2), 0.937987);
|
||||||
|
|
||||||
const Matrix& v2_new = simplex[2];
|
const Matrix& v2_new = simplex[2];
|
||||||
assert(assert_doubles(v2_new(0,0), -0.346582, epsilon));
|
check_equality(v2_new(0,0), -0.346582);
|
||||||
assert(assert_doubles(v2_new(0,1), 0.878534, epsilon));
|
check_equality(v2_new(0,1), 0.878534);
|
||||||
assert(assert_doubles(v2_new(0,2), -0.328724, epsilon));
|
check_equality(v2_new(0,2), -0.328724);
|
||||||
assert(assert_doubles(v2_new(1,0), -0.936885, epsilon));
|
check_equality(v2_new(1,0), -0.936885);
|
||||||
assert(assert_doubles(v2_new(1,1), -0.341445, epsilon));
|
check_equality(v2_new(1,1), -0.341445);
|
||||||
assert(assert_doubles(v2_new(1,2), 0.075251, epsilon));
|
check_equality(v2_new(1,2), 0.075251);
|
||||||
assert(assert_doubles(v2_new(2,0), -0.046131, epsilon));
|
check_equality(v2_new(2,0), -0.046131);
|
||||||
assert(assert_doubles(v2_new(2,1), 0.334057, epsilon));
|
check_equality(v2_new(2,1), 0.334057);
|
||||||
assert(assert_doubles(v2_new(2,2), 0.941423, epsilon));
|
check_equality(v2_new(2,2), 0.941423);
|
||||||
|
|
||||||
const Matrix& v3_new = simplex[3];
|
const Matrix& v3_new = simplex[3];
|
||||||
assert(assert_doubles(v3_new(0,0), -0.394713, epsilon));
|
check_equality(v3_new(0,0), -0.394713);
|
||||||
assert(assert_doubles(v3_new(0,1), 0.791782, epsilon));
|
check_equality(v3_new(0,1), 0.791782);
|
||||||
assert(assert_doubles(v3_new(0,2), -0.466136, epsilon));
|
check_equality(v3_new(0,2), -0.466136);
|
||||||
assert(assert_doubles(v3_new(1,0), -0.912112, epsilon));
|
check_equality(v3_new(1,0), -0.912112);
|
||||||
assert(assert_doubles(v3_new(1,1), -0.398788, epsilon));
|
check_equality(v3_new(1,1), -0.398788);
|
||||||
assert(assert_doubles(v3_new(1,2), 0.094972, epsilon));
|
check_equality(v3_new(1,2), 0.094972);
|
||||||
assert(assert_doubles(v3_new(2,0), -0.110692, epsilon));
|
check_equality(v3_new(2,0), -0.110692);
|
||||||
assert(assert_doubles(v3_new(2,1), 0.462655, epsilon));
|
check_equality(v3_new(2,1), 0.462655);
|
||||||
assert(assert_doubles(v3_new(2,2), 0.879601, epsilon));
|
check_equality(v3_new(2,2), 0.879601);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
test_simplex_operations();
|
Traits traits;
|
||||||
test_centroid();
|
|
||||||
test_nelder_mead();
|
|
||||||
|
|
||||||
return 0;
|
test_simplex_operations(traits);
|
||||||
|
test_centroid(traits);
|
||||||
|
test_nelder_mead(traits);
|
||||||
|
|
||||||
|
std::cout << "Done!" << std::endl;
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,75 +2,62 @@
|
||||||
|
|
||||||
#include <CGAL/Surface_mesh.h>
|
#include <CGAL/Surface_mesh.h>
|
||||||
|
|
||||||
#include <CGAL/Eigen_linear_algebra_traits.h>
|
#include <CGAL/optimal_bounding_box.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 <array>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#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()
|
void test_genetic_algorithm()
|
||||||
{
|
{
|
||||||
CGAL::Eigen_dense_matrix<double, -1, -1> data_points(4, 3); // -1 = dynamic size at run time
|
std::array<Point_3, 4> points;
|
||||||
data_points(0,0) = 0.866802;
|
points[0] = Point_3(0.866802, 0.740808, 0.895304);
|
||||||
data_points(0,1) = 0.740808;
|
points[1] = Point_3(0.912651, 0.761565, 0.160330);
|
||||||
data_points(0,2) = 0.895304;
|
points[2] = Point_3(0.093661, 0.892578, 0.737412);
|
||||||
data_points(1,0) = 0.912651;
|
points[3] = Point_3(0.166461, 0.149912, 0.364944);
|
||||||
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::Eigen_linear_algebra_traits Linear_algebra_traits;
|
CGAL::Optimal_bounding_box::internal::Population<Traits> pop(5);
|
||||||
CGAL::Optimal_bounding_box::Population<Linear_algebra_traits> pop(5);
|
CGAL::Optimal_bounding_box::internal::Evolution<Traits> evolution(pop, data_points);
|
||||||
CGAL::Optimal_bounding_box::Evolution<Linear_algebra_traits> evolution(pop, data_points);
|
|
||||||
evolution.genetic_algorithm();
|
evolution.genetic_algorithm();
|
||||||
assert(pop.size() == 5);
|
assert(pop.size() == 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_random_unit_tetra()
|
void test_random_unit_tetra()
|
||||||
{
|
{
|
||||||
// this is dynamic at run times
|
std::array<Point_3, 4> points;
|
||||||
CGAL::Eigen_dense_matrix<double, -1, -1> data_points(4, 3);
|
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;
|
Mesh mesh;
|
||||||
Point p1(0.866802, 0.740808, 0.895304);
|
CGAL::make_tetrahedron(points[0], points[1], points[2], points[3], mesh);
|
||||||
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);
|
|
||||||
|
|
||||||
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_TEST
|
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_TEST
|
||||||
std::ofstream out("data/random_unit_tetra.off");
|
std::ofstream out("data/random_unit_tetra.off");
|
||||||
|
|
@ -78,148 +65,102 @@ void test_random_unit_tetra()
|
||||||
out.close();
|
out.close();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits;
|
|
||||||
typedef Linear_algebra_traits::Matrix Matrix;
|
|
||||||
|
|
||||||
std::size_t generations = 10;
|
std::size_t generations = 10;
|
||||||
CGAL::Optimal_bounding_box::Population<Linear_algebra_traits> pop(50);
|
CGAL::Optimal_bounding_box::internal::Population<Traits> pop(50);
|
||||||
CGAL::Optimal_bounding_box::Evolution<Linear_algebra_traits> evolution(pop, data_points);
|
CGAL::Optimal_bounding_box::internal::Evolution<Traits> evolution(pop, data_points);
|
||||||
evolution.evolve(generations);
|
evolution.evolve(generations);
|
||||||
|
|
||||||
Matrix R = evolution.get_best();
|
Matrix R = evolution.get_best();
|
||||||
const double epsilon = 1e-3;
|
check_equality(Traits::compute_determinant(R), 1);
|
||||||
assert(assert_doubles(Linear_algebra_traits::compute_determinant(R), 1, epsilon));
|
check_equality(R(0,0), -0.25791);
|
||||||
assert(assert_doubles(R(0,0), -0.25791, epsilon));
|
check_equality(R(0,1), 0.796512);
|
||||||
assert(assert_doubles(R(0,1), 0.796512, epsilon));
|
check_equality(R(0,2), -0.546855);
|
||||||
assert(assert_doubles(R(0,2), -0.546855, epsilon));
|
check_equality(R(1,0), -0.947128);
|
||||||
assert(assert_doubles(R(1,0), -0.947128, epsilon));
|
check_equality(R(1,1), -0.320242);
|
||||||
assert(assert_doubles(R(1,1), -0.320242, epsilon));
|
check_equality(R(1,2), -0.0197553);
|
||||||
assert(assert_doubles(R(1,2), -0.0197553, epsilon));
|
check_equality(R(2,0), -0.190861);
|
||||||
assert(assert_doubles(R(2,0), -0.190861, epsilon));
|
check_equality(R(2,1), 0.512847);
|
||||||
assert(assert_doubles(R(2,1), 0.512847, epsilon));
|
check_equality(R(2,2), 0.836992);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_reference_tetrahedron(const char* fname)
|
void test_reference_tetrahedron(const char* fname)
|
||||||
{
|
{
|
||||||
std::ifstream input(fname);
|
std::ifstream input(fname);
|
||||||
CGAL::Surface_mesh<K::Point_3> mesh;
|
CGAL::Surface_mesh<Point_3> 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::cerr << fname << " is not a valid off file.\n";
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits;
|
|
||||||
typedef Linear_algebra_traits::Matrix Matrix;
|
|
||||||
|
|
||||||
// points in a matrix
|
// points in a matrix
|
||||||
Matrix points;
|
Matrix points;
|
||||||
CGAL::Optimal_bounding_box::sm_to_matrix(mesh, points);
|
CGAL::Optimal_bounding_box::sm_to_matrix(mesh, points);
|
||||||
|
|
||||||
std::size_t generations = 10;
|
std::size_t generations = 10;
|
||||||
CGAL::Optimal_bounding_box::Population<Linear_algebra_traits> pop(50);
|
CGAL::Optimal_bounding_box::internal::Population<Traits> pop(50);
|
||||||
CGAL::Optimal_bounding_box::Evolution<Linear_algebra_traits> experiment(pop, points);
|
CGAL::Optimal_bounding_box::internal::Evolution<Traits> experiment(pop, points);
|
||||||
experiment.evolve(generations);
|
experiment.evolve(generations);
|
||||||
|
|
||||||
Matrix R = experiment.get_best();
|
Matrix R = experiment.get_best();
|
||||||
double epsilon = 1e-5;
|
check_equality(Traits::compute_determinant(R), 1);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_long_tetrahedron(const std::string fname)
|
void test_long_tetrahedron(const std::string fname)
|
||||||
{
|
{
|
||||||
std::ifstream input(fname);
|
std::ifstream input(fname);
|
||||||
CGAL::Surface_mesh<K::Point_3> mesh;
|
CGAL::Surface_mesh<Point_3> 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::cerr << fname << " is not a valid off file.\n";
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef CGAL::Eigen_linear_algebra_traits Linear_algebra_traits;
|
|
||||||
typedef Linear_algebra_traits::Matrix Matrix;
|
|
||||||
|
|
||||||
// points in a matrix
|
// points in a matrix
|
||||||
Matrix points;
|
Matrix points;
|
||||||
CGAL::Optimal_bounding_box::sm_to_matrix(mesh, points);
|
CGAL::Optimal_bounding_box::sm_to_matrix(mesh, points);
|
||||||
|
|
||||||
std::size_t max_generations = 10;
|
std::size_t max_generations = 10;
|
||||||
CGAL::Optimal_bounding_box::Population<Linear_algebra_traits> pop(50);
|
CGAL::Optimal_bounding_box::internal::Population<Traits> pop(50);
|
||||||
CGAL::Optimal_bounding_box::Evolution<Linear_algebra_traits> experiment(pop, points);
|
CGAL::Optimal_bounding_box::internal::Evolution<Traits> experiment(pop, points);
|
||||||
experiment.evolve(max_generations);
|
experiment.evolve(max_generations);
|
||||||
|
|
||||||
Matrix R = experiment.get_best();
|
Matrix R = experiment.get_best();
|
||||||
double epsilon = 1e-3;
|
check_equality(Traits::compute_determinant(R), 1);
|
||||||
assert(assert_doubles(Linear_algebra_traits::compute_determinant(R), 1, epsilon));
|
check_equality(R(0,0), -1);
|
||||||
assert(assert_doubles(R(0,0), -1, epsilon));
|
check_equality(R(0,1), 0);
|
||||||
assert(assert_doubles(R(0,1), 0, epsilon));
|
check_equality(R(0,2), 0);
|
||||||
assert(assert_doubles(R(0,2), 0, epsilon));
|
check_equality(R(1,0), 0);
|
||||||
assert(assert_doubles(R(1,0), 0, epsilon));
|
check_equality(R(1,1), -0.707107);
|
||||||
assert(assert_doubles(R(1,1), -0.707107, epsilon));
|
check_equality(R(1,2), 0.707106) || assert_doubles(R(1,2), -0.707106);
|
||||||
assert(assert_doubles(R(1,2), 0.707106, epsilon) ||
|
check_equality(R(2,0), 0);
|
||||||
assert_doubles(R(1,2), -0.707106, epsilon));
|
check_equality(R(2,1), 0.707106) || assert_doubles(R(1,2), -0.707106);
|
||||||
assert(assert_doubles(R(2,0), 0, epsilon));
|
check_equality(R(2,2), 0.707107);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_compute_obb_evolution(const std::string fname)
|
void test_compute_obb_evolution(const std::string fname)
|
||||||
{
|
{
|
||||||
std::ifstream input(fname);
|
std::ifstream input(fname);
|
||||||
typedef CGAL::Surface_mesh<K::Point_3> SMesh;
|
typedef CGAL::Surface_mesh<Point_3> SMesh;
|
||||||
SMesh mesh;
|
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::cerr << fname << " is not a valid off file.\n";
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get mesh points
|
Traits traits;
|
||||||
std::vector<K::Point_3> sm_points;
|
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;
|
FT vol = CGAL::Optimal_bounding_box::calculate_volume(obb_points);
|
||||||
typedef typename boost::property_map<SMesh, boost::vertex_point_t>::const_type PointPMap;
|
check_equality(vol, 0.883371);
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_TEST
|
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_TEST
|
||||||
/*
|
CGAL::Surface_mesh<Point_3> result_mesh;
|
||||||
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::make_hexahedron(obb_points[0], obb_points[1], obb_points[2], obb_points[3],
|
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");
|
std::ofstream out("data/obb_result.off");
|
||||||
out << result_mesh;
|
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)
|
void test_compute_obb_mesh(const std::string fname)
|
||||||
{
|
{
|
||||||
std::ifstream input(fname);
|
std::ifstream input(fname);
|
||||||
CGAL::Surface_mesh<K::Point_3> mesh;
|
CGAL::Surface_mesh<Point_3> 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::cerr << fname << " is not a valid off file.\n";
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGAL::Eigen_linear_algebra_traits la_traits;
|
CGAL::Surface_mesh<Point_3> obbmesh;
|
||||||
CGAL::Surface_mesh< K::Point_3> obbmesh;
|
CGAL::oriented_bounding_box(mesh, obbmesh);
|
||||||
CGAL::Optimal_bounding_box::compute_optimal_bounding_box(mesh, obbmesh, la_traits, true);
|
|
||||||
|
|
||||||
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_TEST
|
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_TEST
|
||||||
std::ofstream out("/tmp/result_elephant.off");
|
std::ofstream out("/tmp/result_elephant.off");
|
||||||
|
|
@ -248,46 +188,21 @@ void test_compute_obb_mesh(const std::string fname)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_function_defaults_traits(const std::string fname1,
|
void test_function_defaults_traits(const std::string fname1)
|
||||||
const std::string fname2)
|
|
||||||
{
|
{
|
||||||
std::ifstream input1(fname1);
|
std::ifstream input1(fname1);
|
||||||
CGAL::Surface_mesh<K::Point_3> mesh1;
|
CGAL::Surface_mesh<Point_3> mesh1;
|
||||||
if (!input1 || !(input1 >> mesh1) || mesh1.is_empty())
|
if(!input1 || !(input1 >> mesh1) || mesh1.is_empty())
|
||||||
{
|
{
|
||||||
std::cerr << fname1 << " is not a valid off file.\n";
|
std::cerr << fname1 << " is not a valid off file.\n";
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ifstream input2(fname2);
|
std::array<Point_3, 8> obb_points;
|
||||||
CGAL::Surface_mesh<K::Point_3> mesh2;
|
CGAL::oriented_bounding_box(sm_points, obb_points, CGAL::parameters::use_convex_hull(true));
|
||||||
if (!input2 || !(input2 >> mesh2) || mesh2.is_empty())
|
|
||||||
{
|
|
||||||
std::cerr << fname2 << " is not a valid off file.\n";
|
|
||||||
std::exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// test one
|
const FT vol = CGAL::Optimal_bounding_box::calculate_volume(obb_points);
|
||||||
std::vector<K::Point_3> sm_points;
|
check_equality(vol, 0.883371);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
|
|
@ -299,7 +214,7 @@ int main()
|
||||||
test_long_tetrahedron("data/long_tetrahedron.off");
|
test_long_tetrahedron("data/long_tetrahedron.off");
|
||||||
test_compute_obb_evolution("data/random_unit_tetra.off");
|
test_compute_obb_evolution("data/random_unit_tetra.off");
|
||||||
test_compute_obb_mesh("data/elephant.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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue