From 22d5a5b884ee64c265e702b85e7aaacac6dffff9 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 15 Dec 2017 10:45:25 +0100 Subject: [PATCH] Fix Convex_hull_3 quickhull, with coplanar point `CGAL::convex_hull_3` documents that the output is a triangulation polyhedron. That is true... but for coplanar input points! In case of coplanar input point, the output before this patch was a polyhedron with a single polygonal face. The patch triangulates the face using a pivot point and Euler operations. --- Convex_hull_3/include/CGAL/convex_hull_3.h | 17 +++++++++++++++-- .../test/Convex_hull_3/quickhull_test_3.cpp | 18 ++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Convex_hull_3/include/CGAL/convex_hull_3.h b/Convex_hull_3/include/CGAL/convex_hull_3.h index 7eb685447d7..5e4c96b774a 100644 --- a/Convex_hull_3/include/CGAL/convex_hull_3.h +++ b/Convex_hull_3/include/CGAL/convex_hull_3.h @@ -315,13 +315,26 @@ void coplanar_3_hull(InputIterator first, InputIterator beyond, typename boost::property_map::type vpm = get(CGAL::vertex_point, P); - std::vector::vertex_descriptor> vertices; + typedef boost::graph_traits Graph_traits; + typedef typename Graph_traits::vertex_descriptor vertex_descriptor; + typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename Graph_traits::face_descriptor face_descriptor; + std::vector vertices; vertices.reserve(CH_2.size()); BOOST_FOREACH(const Point_3& p, CH_2){ vertices.push_back(add_vertex(P)); put(vpm, vertices.back(),p); } - Euler::add_face(vertices, P); + face_descriptor f = Euler::add_face(vertices, P); + + // Then triangulate that face + const halfedge_descriptor he = halfedge(f, P); + halfedge_descriptor other_he = next(next(he, P), P); + for(std::size_t i = 3, end = vertices.size(); i < end; ++i) { + const halfedge_descriptor next_he = next(other_he, P); + Euler::split_face(other_he, he, P); + other_he = next_he; + } } diff --git a/Convex_hull_3/test/Convex_hull_3/quickhull_test_3.cpp b/Convex_hull_3/test/Convex_hull_3/quickhull_test_3.cpp index c5c4f22a255..61756f28d79 100644 --- a/Convex_hull_3/test/Convex_hull_3/quickhull_test_3.cpp +++ b/Convex_hull_3/test/Convex_hull_3/quickhull_test_3.cpp @@ -106,6 +106,22 @@ void test_small_hull() polyhedron2.size_of_facets() == 6 ); } +void test_coplanar_hull() +{ + std::vector points; + points.push_back(Point_3(0,0,0)); + points.push_back(Point_3(1,0,0)); + points.push_back(Point_3(0,1,0)); + points.push_back(Point_3(1,1,0)); + points.push_back(Point_3(1.5,0.5,0)); + points.push_back(Point_3(0.5,1.1,0)); + Polyhedron_3 polyhedron; + CGAL::convex_hull_3(points.begin(), points.end(), polyhedron, Traits()); + assert( polyhedron.is_valid() ); + assert( polyhedron.size_of_facets() == 4 ); + assert( polyhedron.is_pure_triangle() ); +} + int main() { @@ -115,6 +131,8 @@ int main() test_tetrahedron_convexity(); std::cerr << "Testing small hull" << std::endl; test_small_hull(); + std::cerr << "Testing coplanar hull" << std::endl; + test_coplanar_hull(); std::cerr << "Testing 500 random points" << std::endl; std::vector points;