Update tests

This commit is contained in:
Mael Rouxel-Labbé 2021-03-22 22:14:39 +01:00
parent 57148ce564
commit a9075e69e2
7 changed files with 424 additions and 62 deletions

View File

@ -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()

View File

@ -0,0 +1,180 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_on_sphere_traits_2.h>
#include <CGAL/Delaunay_triangulation_on_sphere_2.h>
#include <CGAL/enum.h>
#include <iostream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_3 Point;
typedef CGAL::Delaunay_triangulation_on_sphere_traits_2<K> Gt;
typedef CGAL::Delaunay_triangulation_on_sphere_2<Gt> Tr;
int main(int, char**)
{
Gt traits(Point(1, 2, 3), 5);
std::vector<Point> 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<Tr::Edge> 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;
}

View File

@ -79,8 +79,6 @@ void test2()
int main(int, char**)
{
std::cout << " test remove with dim_down" << std::endl;
test1();
test2();

View File

@ -1,4 +1,5 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel_with_sqrt.h>
#include <CGAL/Delaunay_triangulation_on_sphere_traits_2.h>
#include <CGAL/Projection_on_sphere_traits_3.h>
@ -9,15 +10,6 @@
#include <iostream>
#include <vector>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_3 Point_3;
typedef CGAL::Delaunay_triangulation_on_sphere_traits_2<K> Gt;
typedef CGAL::Delaunay_triangulation_on_sphere_2<Gt> DTOS;
typedef CGAL::Projection_on_sphere_traits_3<K> PGt;
typedef CGAL::Delaunay_triangulation_on_sphere_2<PGt> PDTOS;
template <class Vertex_handle, class Face_handle>
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 <typename DTOS, typename PointContainer>
void test(const double radius,
template <typename DTOS, typename FT, typename PointContainer>
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 <typename K>
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<K> Gt;
typedef CGAL::Delaunay_triangulation_on_sphere_2<Gt> DTOS;
typedef CGAL::Projection_on_sphere_traits_3<K> PGt;
typedef CGAL::Delaunay_triangulation_on_sphere_2<PGt> 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<Point_3> 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<Point_3> 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<Point_3> 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<Point_3> 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<Point_3> 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<Point_3> 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<Point_3> 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<DTOS>(radius, coplanar_points);
test<DTOS>(radius, coplanar_points_on_great_circle);
test<DTOS>(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<PGt::Point_on_sphere_2> coplanar_ppoints;
std::vector<PGt::Point_on_sphere_2> coplanar_ppoints_on_great_circle;
std::vector<typename PGt::Point_on_sphere_2> coplanar_ppoints;
std::vector<typename PGt::Point_on_sphere_2> 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<PDTOS>(radius, coplanar_points_on_circle);
test<PDTOS>(radius, coplanar_points_on_great_circle);
test<PDTOS>(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<EPICK>();
test_kernel<EPECK_w_SQRT>();
std::cout << "Done" << std::endl;

View File

@ -0,0 +1,165 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Geographical_coordinates_traits_2.h>
#include <CGAL/Delaunay_triangulation_on_sphere_traits_2.h>
#include <CGAL/Projection_on_sphere_traits_3.h>
#include <CGAL/Delaunay_triangulation_on_sphere_2.h>
#include <CGAL/enum.h>
#include <CGAL/point_generators_3.h>
#include <iostream>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel EPICK;
template <typename K, typename PointRange>
void test(const PointRange& points)
{
// typedef CGAL::Geographical_coordinates_traits_2<K> Gt;
typedef CGAL::Projection_on_sphere_traits_3<K> Gt;
typedef CGAL::Delaunay_triangulation_on_sphere_2<Gt> 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<typename SK::Point_3> discretization_points;
CGAL::Triangulations_on_sphere_2::internal::subsample_arc_on_sphere_2<SK>(as, std::back_inserter(discretization_points));
assert(discretization_points.size() >= 2);
for(std::size_t i=0; i<discretization_points.size()-1; ++i)
out_primal << "2 " << discretization_points[i] << " " << discretization_points[i+1] << "\n";
}
else
{
Segment_3 s = dt.segment(e);
out_primal << "2 " << s.source() << " " << s.target() << "\n";
}
// Dual
if(dt.is_contour(e))
continue;
const Point_on_sphere_2 c1 = dt.circumcenter_on_sphere(e.first);
const Point_on_sphere_2 c2 = dt.circumcenter_on_sphere(dt.mirror_edge(e).first);
// That should never be possible, but with constructions...
const bool diametral_dual = CGAL::collinear(dt.construct_point(c1),
dt.construct_point(c2),
dt.geom_traits().center());
if(!diametral_dual)
{
Arc_on_sphere_2 ad = dt.dual_on_sphere(e);
std::vector<typename SK::Point_3> discretization_points;
CGAL::Triangulations_on_sphere_2::internal::subsample_arc_on_sphere_2<SK>(ad, std::back_inserter(discretization_points));
assert(discretization_points.size() >= 2);
for(std::size_t i=0; i<discretization_points.size()-1; ++i)
out_dual << "2 " << discretization_points[i] << " " << discretization_points[i+1] << "\n";
}
else
{
Segment_3 d = dt.dual(e);
out_dual << "2 " << d.source() << " " << d.target() << "\n";
};
}
}
}
template <typename K>
void test_with_ghost_faces()
{
std::vector<typename K::Point_3> 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<K>(points);
}
template <typename K>
void test_random_data(const std::size_t num_of_pts)
{
typedef typename K::Point_3 Point_3;
typedef CGAL::Creator_uniform_3<double, Point_3> Creator;
CGAL::Random r;
std::cout << "Seed is " << r.get_seed() << std::endl;
CGAL::Random_points_on_sphere_3<Point_3, Creator> on_sphere(1 /*radius*/, r);
std::vector<Point_3> points;
points.reserve(num_of_pts);
for(std::size_t c=0; c<num_of_pts; ++c)
points.push_back(*on_sphere++);
return test<K>(points);
}
int main(int argc, char** argv)
{
const std::size_t num_pts = (argc > 1) ? std::atoi(argv[1]) : 100;
test_with_ghost_faces<EPICK>();
test_random_data<EPICK>(num_pts);
std::cout << "Done!" << std::endl;
return EXIT_SUCCESS;
}

View File

@ -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);

View File

@ -14,6 +14,10 @@ typedef CGAL::Delaunay_triangulation_on_sphere_traits_2<K> 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);