From 867ee52bc51cc414c9a6652310693d5b45f96e19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 13 Jul 2018 11:35:17 +0200 Subject: [PATCH 1/3] Fixed erroneous early return in filter_collinear_points --- Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h b/Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h index 9079520b94d..f7fb459c12f 100644 --- a/Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h +++ b/Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h @@ -67,9 +67,6 @@ OutputForwardIterator filter_collinear_points(InputForwardIterator first, const typename K::FT tolerance = std::numeric_limits::epsilon()) { - if(std::distance(first, beyond) < 4) - return out; - typedef typename K::FT FT; typedef typename K::Point_2 Point; From 47e97bb5ab966533c3e0230f7ef7e8c21962b2de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 13 Jul 2018 11:36:48 +0200 Subject: [PATCH 2/3] Added some stronger (yet natural) preconditions to filter_collinear_points() The range of points must describe a Polygon that is not completely flat, thus: - at least three points - points are not all collinear (up to the tolerance) --- .../include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h b/Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h index f7fb459c12f..ecec83d624d 100644 --- a/Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h +++ b/Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h @@ -60,6 +60,8 @@ namespace Polygon_2 { // by three consecutive points of the range (more specifically, // on the value of the determinant). // +// \pre The range `(first, beyond)` is composed of at least three points. +// \pre Not all points in the range `(first, beyond)` are (almost) collinear. template OutputForwardIterator filter_collinear_points(InputForwardIterator first, InputForwardIterator beyond, @@ -67,6 +69,8 @@ OutputForwardIterator filter_collinear_points(InputForwardIterator first, const typename K::FT tolerance = std::numeric_limits::epsilon()) { + CGAL_precondition(std::distance(first, beyond) >= 3); + typedef typename K::FT FT; typedef typename K::Point_2 Point; @@ -80,7 +84,9 @@ OutputForwardIterator filter_collinear_points(InputForwardIterator first, do { - CGAL_assertion(vit != vit_next && vit_next != vit_next_2 && vit != vit_next_2); + CGAL_assertion(vit != vit_next); + CGAL_assertion(vit_next != vit_next_2); + CGAL_assertion(vit != vit_next_2); const Point& o = *vit; const Point& p = *vit_next; From fa6b5af9de61231c4d4923cdac8878e49600e7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 13 Jul 2018 11:41:29 +0200 Subject: [PATCH 3/3] Added a test --- Polygon/test/Polygon/AlgorithmTest.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/Polygon/test/Polygon/AlgorithmTest.cpp b/Polygon/test/Polygon/AlgorithmTest.cpp index c86d53a8236..46db55a9d9a 100644 --- a/Polygon/test/Polygon/AlgorithmTest.cpp +++ b/Polygon/test/Polygon/AlgorithmTest.cpp @@ -20,7 +20,7 @@ void test_collinear_point_filtering(const R&, const char* FileName) std::ifstream from(FileName); if (!from) { - std::cerr << "could not open file " << FileName << "!" << endl; + std::cerr << "Could not open file " << FileName << "!" << endl; std::exit(1); } CGAL::set_ascii_mode(from); @@ -35,20 +35,33 @@ void test_collinear_point_filtering(const R&, const char* FileName) std::cout << std::endl; std::vector simplified_polygon; + std::size_t final_size; + + // check for 3 points + CGAL::internal::Polygon_2::filter_collinear_points(polygon.begin(), polygon.begin() + 3, + std::back_inserter(simplified_polygon), + 0 /*tolerance*/); + final_size = simplified_polygon.size(); + std::cout << "final size: " << final_size << std::endl; + assert(final_size == 3); + + // generic tests + simplified_polygon.clear(); CGAL::internal::Polygon_2::filter_collinear_points(polygon.begin(), polygon.end(), std::back_inserter(simplified_polygon), 0 /*tolerance*/); - std::size_t final_size = simplified_polygon.size(); + final_size = simplified_polygon.size(); std::cout << "final size (tolerance 0): " << final_size << std::endl; - CGAL_assertion(final_size == 7); + assert(final_size == 7); + // -- simplified_polygon.clear(); CGAL::internal::Polygon_2::filter_collinear_points(polygon.begin(), polygon.end(), std::back_inserter(simplified_polygon), 1e-10); final_size = simplified_polygon.size(); std::cout << "final size (tolerance 1e-10): " << final_size << std::endl; - CGAL_assertion(final_size == 5); + assert(final_size == 5); std::cout << "simplified polygon:" << std::endl; std::copy(simplified_polygon.begin(), simplified_polygon.end(), std::ostream_iterator(std::cout, "\n"));