diff --git a/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/CMakeLists.txt b/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/CMakeLists.txt index 058c7468c01..c661c63eecf 100644 --- a/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/CMakeLists.txt +++ b/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/CMakeLists.txt @@ -1,23 +1,28 @@ -# Created by the script cgal_create_cmake_script -# This is the CMake script for compiling a CGAL application. - cmake_minimum_required(VERSION 3.1...3.15) project( Triangulation_on_sphere_2_Tests ) -find_package(CGAL QUIET) +find_package(CGAL REQUIRED COMPONENTS Core) + +find_package(Eigen3 3.1.0) #(requires 3.1.0 or greater) +include(CGAL_Eigen3_support) if ( CGAL_FOUND ) - # create a target per cppfile - file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) - foreach(cppfile ${cppfiles}) - create_single_source_cgal_program( "${cppfile}" ) - endforeach() + create_single_source_cgal_program( "test_dtos.cpp" ) + create_single_source_cgal_program( "test_dtos2_remove.cpp" ) + create_single_source_cgal_program( "test_dtos_degenerate_cases.cpp" ) + create_single_source_cgal_program( "test_dtos_illegal_points.cpp" ) + create_single_source_cgal_program( "test_dtos_projection_traits.cpp" ) + create_single_source_cgal_program( "test_dtos_traits.cpp" ) + + if(TARGET CGAL::Eigen3_support) + create_single_source_cgal_program( "test_dtos_dual.cpp" ) + target_link_libraries(test_dtos_dual PUBLIC CGAL::Eigen3_support) + endif() else() - - message(STATUS "This program requires the CGAL library, and will not be compiled.") - -endif() + message(STATUS "This program requires the CGAL library, and will not be compiled.") + +endif() diff --git a/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos.cpp b/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos.cpp new file mode 100644 index 00000000000..394e6f24237 --- /dev/null +++ b/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos.cpp @@ -0,0 +1,180 @@ +#include + +#include +#include + +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::Point_3 Point; + +typedef CGAL::Delaunay_triangulation_on_sphere_traits_2 Gt; +typedef CGAL::Delaunay_triangulation_on_sphere_2 Tr; + +int main(int, char**) +{ + Gt traits(Point(1, 2, 3), 5); + + std::vector points; + points.emplace_back( 2, 1, 1); + points.emplace_back(-2, 1, 1); // not on the sphere + points.emplace_back( 0, 1, 1); + points.emplace_back( 1, 2, 1); + points.emplace_back( 0, 1, 1); // duplicate + points.emplace_back( 1, 0, 1); + points.emplace_back( 1, 1, 2); + + // test constructors + Tr tr0; + assert(tr0.geom_traits().center() == Point(0, 0, 0)); + assert(tr0.geom_traits().radius() == 1); + + Tr tr(traits); + assert(tr.geom_traits().center() == Point(1, 2, 3)); + assert(tr.geom_traits().radius() == 5); + + Tr tr2(tr); + assert(tr2.geom_traits().center() == tr.geom_traits().center()); + assert(tr2.geom_traits().radius() == tr.geom_traits().radius()); + + Tr tr3 = tr2; + assert(tr3.geom_traits().center() == tr2.geom_traits().center()); + assert(tr3.geom_traits().radius() == tr2.geom_traits().radius()); + + Tr tr4(points.begin(), points.end(), Point(1, 1, 1), 1); + assert(tr4.number_of_vertices() == 5); + + tr4.set_radius(0.123); + assert(tr4.number_of_vertices() == 0); + + Tr tr5(points.begin(), points.end()); + assert(tr5.geom_traits().center() == Point(0, 0, 0)); + assert(tr5.geom_traits().radius() == 1); + assert(tr5.number_of_vertices() == 0); + + Gt traits2(Point(1, 1, 1), 1); + Tr tr6(points.begin(), points.end(), traits2); + assert(tr6.number_of_vertices() == 5); + + tr6.set_center(Point(1,2,3)); + assert(tr6.number_of_vertices() == 0); + + // center / radius setting + tr.insert(Point(6, 2, 3)); + assert(tr.number_of_vertices() == 1); + + tr.set_center_and_radius(Point(1, 1, 1), 1); + assert(tr3.number_of_vertices() == 0); + assert(tr.geom_traits().center() == Point(1, 1, 1)); + assert(tr.geom_traits().radius() == 1); + + tr.insert(points.begin(), points.end()); + write_OFF("test_dtos.off", tr); + + ////////////////////////////////////////////////////////////////////////////////////////////////// + // test ranges + Tr::Vertex_handles vs = tr.vertex_handles(); + assert(vs.size() == tr.number_of_vertices() && vs.size() == 5); + + Tr::All_edges es = tr.all_edges(); + Tr::Solid_edges ses = tr.solid_edges(); + assert(es.size() == 9 && ses.size() == 8); + + Tr::All_face_handles afs = tr.all_face_handles(); + assert(afs.size() == tr.number_of_faces() && afs.size() == 6); + + Tr::Solid_face_handles sfs = tr.solid_faces(); + assert(sfs.size() == 4); + assert(tr.number_of_solid_faces() + tr.number_of_ghost_faces() == tr.number_of_faces()); + + Tr::Points pts = tr.points(); + assert(pts.size() == tr.number_of_vertices() && pts.size() == 5); + + ////////////////////////////////////////////////////////////////////////////////////////////////// + // test iterators + + // All vertices iterator + Tr::Vertices_iterator vit = tr.vertices_begin(), vend = tr.vertices_end(); + assert(std::distance(vit, vend) == 5); + + const Tr::Point& p0 = tr.point(vit); + ++vit; + const Tr::Point& p1 = tr.point(vit++); + assert(p0 != p1); + std::advance(vit, -2); + assert(p0 == vit->point()); + + // All edges iterator + Tr::All_edges_iterator eit = tr.all_edges_begin(), eend = tr.all_edges_end(); + assert(std::distance(eit, eend) == 9); + + Tr::Edge e0 = *eit; + ++eit; + Tr::Edge e1 = *eit++; + assert(e0 != e1); + std::advance(eit, -2); + assert(e0 == *eit); + + // Solid edges iterator + Tr::Solid_edges_iterator seit = tr.solid_edges_begin(), seend = tr.solid_edges_end(); + assert(std::distance(seit, seend) == 8); + + Tr::Edge se0 = *seit; + ++seit; + Tr::Edge se1 = *seit++; + assert(se0 != se1); + std::advance(seit, -2); + assert(se0 == *seit); + + // Contour edges iterator + Tr::Contour_edges_iterator ceit=tr.contour_edges_begin(), ceend=tr.contour_edges_end(); + assert(std::distance(ceit, ceend) == 4); + + std::set unique_edges; + while(ceit != ceend) + { + const Tr::Edge& e = *ceit; + unique_edges.insert(e); + assert(tr.is_ghost(e.first) != tr.is_ghost(tr.mirror_edge(e).first)); // xor + ++ceit; + } + + assert(unique_edges.size() == 4); + std::advance(ceit, -4); + assert(ceit == tr.contour_edges_begin()); + + // All faces iterator + Tr::All_faces_iterator fit = tr.all_faces_begin(), fend = tr.all_faces_end(); + assert(std::distance(fit, fend) == 6); + + Tr::Face_handle f0 = fit; + ++fit; + Tr::Face_handle f1 = fit++; + assert(f0 != f1); + std::advance(fit, -2); + assert(f0 == fit); + + // Solid faces iterator + Tr::Solid_faces_iterator sfit = tr.solid_faces_begin(), sfend = tr.solid_faces_end(); + assert(std::distance(sfit, sfend) == 4); + + Tr::Face_handle sf0 = sfit; + ++sfit; + Tr::Face_handle sf1 = sfit++; + assert(sf0 != sf1); + std::advance(sfit, -2); + Tr::Face_handle sf2 = sfit; + assert(sf0 == sf2); + + // Face Circulator + vit = tr.vertices_begin(); + std::advance(vit, 3); // top of the pyramid + Tr::Face_circulator fc = tr.incident_faces(vit), end = fc; + assert(std::distance(++fc, end) + 1 == 4); + + std::cout << "Done!" << std::endl; + + return EXIT_SUCCESS; +} diff --git a/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos2_remove.cpp b/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos2_remove.cpp index d39b4a92a2c..85a9af5d687 100644 --- a/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos2_remove.cpp +++ b/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos2_remove.cpp @@ -79,8 +79,6 @@ void test2() int main(int, char**) { - std::cout << " test remove with dim_down" << std::endl; - test1(); test2(); diff --git a/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos_degenerate_cases.cpp b/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos_degenerate_cases.cpp index 9cf5519c57e..8d40728737e 100644 --- a/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos_degenerate_cases.cpp +++ b/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos_degenerate_cases.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -9,15 +10,6 @@ #include #include -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef K::Point_3 Point_3; - -typedef CGAL::Delaunay_triangulation_on_sphere_traits_2 Gt; -typedef CGAL::Delaunay_triangulation_on_sphere_2 DTOS; - -typedef CGAL::Projection_on_sphere_traits_3 PGt; -typedef CGAL::Delaunay_triangulation_on_sphere_2 PDTOS; - template bool has_face(const Face_handle fh, const Vertex_handle v0, @@ -112,16 +104,15 @@ bool are_equal(const Triangul& triA, const Triangul& triB) // tests whether it is possible to insert points in degenerated positions // and whether the result is uniquely defined after this. -template -void test(const double radius, +template +void test(const FT radius, PointContainer coplanar_points) { + std::cout << coplanar_points.size() << " input points" << std::endl; + DTOS dtos(CGAL::ORIGIN, radius); - for(const auto& p : coplanar_points) // to avoid Hilbert sorts - { - std::cout << "------------> IIIIIIIIIIIIIIIIIIINSERT " << p << std::endl; + for(const auto& p : coplanar_points) // to avoid Hilbert sort dtos.insert(p); - } assert(dtos.is_valid()); @@ -132,14 +123,12 @@ void test(const double radius, std::cout << dtos.number_of_faces() << " nf" << std::endl; std::cout << dtos.number_of_ghost_faces() << " gf" << std::endl; - return; // @tmp - for(int i=0; i<10; ++i) { CGAL::cpp98::random_shuffle(coplanar_points.begin(), coplanar_points.end()); DTOS dtos2(CGAL::ORIGIN, radius); - for(const auto& p : coplanar_points) // to avoid Hilbert sorts + for(const auto& p : coplanar_points) // to avoid Hilbert sort dtos2.insert(p); assert(dtos2.is_valid()); @@ -149,40 +138,51 @@ void test(const double radius, } } -int main(int, char**) +template +void test_kernel() { - using std::sqrt; + std::cout << "Test: " << typeid(K).name() << std::endl; - const double radius = 100; - const double radius2 = CGAL::square(radius); + typedef typename K::FT FT; + typedef typename K::Point_3 Point_3; + + typedef CGAL::Delaunay_triangulation_on_sphere_traits_2 Gt; + typedef CGAL::Delaunay_triangulation_on_sphere_2 DTOS; + + typedef CGAL::Projection_on_sphere_traits_3 PGt; + typedef CGAL::Delaunay_triangulation_on_sphere_2 PDTOS; + + const FT radius = 100; + const FT radius2 = CGAL::square(radius); + + const FT denom = FT(1) / CGAL::sqrt(FT(2)); + const FT z = CGAL::sqrt(radius2 - 1); std::vector coplanar_low_dim { Point_3(0,0,radius), Point_3(radius,0,0), Point_3(0,radius,0) // , Point_3(0,0,-radius) }; // Points are coplanar and coplanar with the center of the sphere - std::vector coplanar_points { Point_3( radius/sqrt(2), radius/sqrt(2), 0), - Point_3(- radius/sqrt(2), radius/sqrt(2), 0), - Point_3(- radius/sqrt(2), - radius/sqrt(2), 0), - Point_3( radius/sqrt(2), - radius/sqrt(2), 0), - Point_3( radius, 0, 0), - Point_3( 0, 0, radius) }; + std::vector coplanar_points { Point_3( radius*denom, radius*denom, 0), + Point_3(- radius*denom, radius*denom, 0), + Point_3(- radius*denom, - radius*denom, 0), + Point_3( radius*denom, - radius*denom, 0), + Point_3( radius, 0, 0), + Point_3( 0, 0, radius) }; - std::vector coplanar_points_on_great_circle { Point_3( 0, 0, radius), - Point_3( 1/sqrt(2), 1/sqrt(2), sqrt(radius2 - 1)), - Point_3(-1/sqrt(2), -1/sqrt(2), sqrt(radius2 - 1)), - Point_3( 0, 1, sqrt(radius2 - 1)), - Point_3( 1, 0, sqrt(radius2 - 1)), - Point_3(-1/sqrt(2), 1/sqrt(2), sqrt(radius2 - 1)), - Point_3( 1/sqrt(2), -1/sqrt(2), sqrt(radius2 - 1)), - Point_3( radius, 0 , 0) }; + std::vector coplanar_points_on_great_circle { Point_3( 0, 0, radius), + Point_3( denom, denom, z), + Point_3(-denom, -denom, z), + Point_3( denom, denom, -z), + Point_3(-denom, -denom, -z), + Point_3( 0, 0,-radius) }; - std::vector coplanar_points_on_circle { Point_3( 1/sqrt(2), 1/sqrt(2), sqrt(radius2 - 1)), - Point_3(-1/sqrt(2), -1/sqrt(2), sqrt(radius2 - 1)), - Point_3( 0, 1, sqrt(radius2 - 1)), - Point_3( 1, 0, sqrt(radius2 - 1))/*, - Point_3(-1/sqrt(2), 1/sqrt(2), sqrt(radius2 - 1)), - Point_3( 1/sqrt(2), -1/sqrt(2), sqrt(radius2 - 1))*/ }; + std::vector coplanar_points_on_circle { Point_3( denom, denom, z), + Point_3(-denom, -denom, z), + Point_3( 0, 1, z)/*, + Point_3( 1, 0, z), + Point_3(-denom, denom, z), + Point_3( denom, -denom, z)*/ }; // ----------------------------------------------------------------------------------------------- std::cout << "Testing with Delaunay_triangulation_sphere_traits:" << std::endl; @@ -190,14 +190,15 @@ int main(int, char**) test(radius, coplanar_points); test(radius, coplanar_points_on_great_circle); test(radius, coplanar_points_on_circle); + return; // ----------------------------------------------------------------------------------------------- std::cout << "Testing with projection: " << std::endl; PGt traits(CGAL::ORIGIN, radius); - PGt::Construct_point_on_sphere_2 to_s2 = traits.construct_point_on_sphere_2_object(); + typename PGt::Construct_point_on_sphere_2 to_s2 = traits.construct_point_on_sphere_2_object(); - std::vector coplanar_ppoints; - std::vector coplanar_ppoints_on_great_circle; + std::vector coplanar_ppoints; + std::vector coplanar_ppoints_on_great_circle; std::transform(coplanar_points.begin(), coplanar_points.end(), std::back_inserter(coplanar_ppoints), to_s2); @@ -208,6 +209,15 @@ int main(int, char**) test(radius, coplanar_points_on_circle); test(radius, coplanar_points_on_great_circle); test(radius, coplanar_points_on_circle); +} + +int main(int, char**) +{ + typedef CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt EPECK_w_SQRT; + typedef CGAL::Exact_predicates_inexact_constructions_kernel EPICK; + + test_kernel(); + test_kernel(); std::cout << "Done" << std::endl; diff --git a/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos_dual.cpp b/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos_dual.cpp new file mode 100644 index 00000000000..563b6ff1333 --- /dev/null +++ b/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos_dual.cpp @@ -0,0 +1,165 @@ +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel EPICK; + +template +void test(const PointRange& points) +{ +// typedef CGAL::Geographical_coordinates_traits_2 Gt; + typedef CGAL::Projection_on_sphere_traits_3 Gt; + typedef CGAL::Delaunay_triangulation_on_sphere_2 Dt; + + typedef typename Dt::Geom_traits Gt; + typedef typename Gt::SK SK; + + typedef typename Dt::FT FT; + typedef typename Dt::Point_3 Point_3; + typedef typename Dt::Point Point_on_sphere_2; + typedef typename Dt::Segment_3 Segment_3; + typedef typename Dt::Arc_on_sphere_2 Arc_on_sphere_2; + typedef typename Dt::Face_handle Face_handle; + + Dt dt; + dt.insert(points.begin(), points.end()); + + // The triangulation, using straight edges + write_OFF("result.off", dt, CGAL::parameters::stream_precision(17)); + + std::ofstream out_primal("edges_primal.polylines.cgal"); + out_primal.precision(17); + std::ofstream out_dual("edges_dual.polylines.cgal"); + out_dual.precision(17); + + for(typename Dt::Solid_faces_iterator fit = dt.solid_faces_begin(); fit!=dt.solid_faces_end(); ++fit) + { + Face_handle fh = fit; + + const Point_3 c = dt.dual(fh); + CGAL_USE(c); + + const Point_on_sphere_2 cs = dt.dual_on_sphere(fh); + const FT r = dt.geom_traits().radius(); + assert(CGAL::abs(CGAL::squared_distance(dt.construct_point(cs), + dt.geom_traits().center()) - r*r) <= 1e-10); + + for(int i=0; i<3; ++i) + { + Face_handle nfh = fh->neighbor(i); + if(!dt.is_ghost(nfh) && fh < nfh) + continue; + + typename Dt::Edge e(fh, i); + const bool diametral_edge = CGAL::collinear(dt.construct_point(dt.point(fh, (i+1)%3)), + dt.construct_point(dt.point(fh, (i+2)%3)), + dt.geom_traits().center()); + + // primal + if(!diametral_edge) + { + Arc_on_sphere_2 as = dt.segment_on_sphere(e); + std::vector discretization_points; + CGAL::Triangulations_on_sphere_2::internal::subsample_arc_on_sphere_2(as, std::back_inserter(discretization_points)); + assert(discretization_points.size() >= 2); + + for(std::size_t i=0; i discretization_points; + CGAL::Triangulations_on_sphere_2::internal::subsample_arc_on_sphere_2(ad, std::back_inserter(discretization_points)); + assert(discretization_points.size() >= 2); + + for(std::size_t i=0; i +void test_with_ghost_faces() +{ + std::vector points; + points.emplace_back( 1, 0, 0); + points.emplace_back( 0, 1, 0); + points.emplace_back( 1, 1, 1); + points.emplace_back( -1, -1, -1); + points.emplace_back( 0.5, 0.5, 0); + points.emplace_back( 1, 1, 0); + points.emplace_back(0.25, 0.25, 0); +// points.emplace_back( 0, 0, 1); +// points.emplace_back( 2, 0, 0); +// points.emplace_back( 0.5, 0, 0); +// points.emplace_back( 0.5, 0, 0.5); +// points.emplace_back( 0.5, 0, -0.5); +// points.emplace_back( 0, 0, 0.5); +// points.emplace_back( -1, 0, 0); + + return test(points); +} + +template +void test_random_data(const std::size_t num_of_pts) +{ + typedef typename K::Point_3 Point_3; + typedef CGAL::Creator_uniform_3 Creator; + + CGAL::Random r; + std::cout << "Seed is " << r.get_seed() << std::endl; + CGAL::Random_points_on_sphere_3 on_sphere(1 /*radius*/, r); + + std::vector points; + points.reserve(num_of_pts); + + for(std::size_t c=0; c(points); +} + +int main(int argc, char** argv) +{ + const std::size_t num_pts = (argc > 1) ? std::atoi(argv[1]) : 100; + + test_with_ghost_faces(); + test_random_data(num_pts); + + std::cout << "Done!" << std::endl; + return EXIT_SUCCESS; +} diff --git a/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos_projection_traits.cpp b/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos_projection_traits.cpp index dc9770ee167..a2b69f77c5a 100644 --- a/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos_projection_traits.cpp +++ b/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos_projection_traits.cpp @@ -111,7 +111,7 @@ int main(int, char**) assert(!inside_cone(pp51, pp52, pp54)); assert(!inside_cone(pp51, pp52, pp55)); - std::cout << "Test compare_on_sphere_2" << std::endl; + std::cout << "Test Compare_on_sphere_2" << std::endl; assert(compare_on_sphere(pp31, pp31) == CGAL::EQUAL); assert(compare_on_sphere(pp31, pp32) == CGAL::EQUAL); assert(compare_on_sphere(pp31, pp33) == CGAL::SMALLER); diff --git a/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos_traits.cpp b/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos_traits.cpp index 719556c9c28..2ae1e24eb3a 100644 --- a/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos_traits.cpp +++ b/Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/test_dtos_traits.cpp @@ -14,6 +14,10 @@ typedef CGAL::Delaunay_triangulation_on_sphere_traits_2 Gt; typedef Gt::Orientation_on_sphere_2 Orientation_on_sphere_2; typedef Gt::Side_of_oriented_circle_on_sphere_2 Side_of_oriented_circle_on_sphere_2; +// This only tests non-trivial functions (a lot of functors are just calls to some functors +// of the 3D linear kernel, such as: +// typedef typename LK::Compare_xyz_3 Compare_on_sphere_2; + int main(int, char**) { Point P0 ( 0, 0, 0); @@ -44,7 +48,7 @@ int main(int, char**) assert(traits_4.radius() == traits_5.radius()); assert(traits_4.center() == traits_5.center()); - std::cout << "Test power_test_2" << std::endl; + std::cout << "Test Side_of_oriented_circle_on_sphere_2" << std::endl; CGAL::Oriented_side result; result = traits.side_of_oriented_circle_on_sphere_2_object()(P1, P2, P3, P4); assert(result == CGAL::ON_POSITIVE_SIDE);