diff --git a/doc/release_notes.qbk b/doc/release_notes.qbk index 249510236..5ccdcd5f7 100644 --- a/doc/release_notes.qbk +++ b/doc/release_notes.qbk @@ -27,6 +27,7 @@ * [@https://svn.boost.org/trac/boost/ticket/9245 9245] Check for process errors in make_qbk.py * [@https://svn.boost.org/trac/boost/ticket/9081 9081] Booleans create self-intersecting polygons from non-self-intersecting polygons * [@https://svn.boost.org/trac/boost/ticket/8310 8310] Wrong results with overlapping polygons (fixed using point_on_surface for disjoint) +* [@https://svn.boost.org/trac/boost/ticket/9871 9871] Remove spike in polygon with only a spike [*Bugfixes] diff --git a/include/boost/geometry/algorithms/remove_spikes.hpp b/include/boost/geometry/algorithms/remove_spikes.hpp index 634391b64..62845135f 100644 --- a/include/boost/geometry/algorithms/remove_spikes.hpp +++ b/include/boost/geometry/algorithms/remove_spikes.hpp @@ -69,7 +69,7 @@ struct range_remove_spikes std::size_t const min_num_points = core_detail::closure::minimum_ring_size < geometry::closure::value - >::value; + >::value - 1; // subtract one: a polygon with only one spike should result into one point if (n < min_num_points) { return; @@ -104,13 +104,13 @@ struct range_remove_spikes found = false; // Check for spike in first point int const penultimate = 2; - while(cleaned.size() > 3 && detail::point_is_spike_or_equal(cleaned.front(), *(cleaned.end() - penultimate), cleaned.back())) + while(cleaned.size() >= 3 && detail::point_is_spike_or_equal(cleaned.front(), *(cleaned.end() - penultimate), cleaned.back())) { cleaned.pop_back(); found = true; } // Check for spike in second point - while(cleaned.size() > 3 && detail::point_is_spike_or_equal(*(cleaned.begin() + 1), cleaned.back(), cleaned.front())) + while(cleaned.size() >= 3 && detail::point_is_spike_or_equal(*(cleaned.begin() + 1), cleaned.back(), cleaned.front())) { cleaned.pop_front(); found = true; @@ -118,6 +118,13 @@ struct range_remove_spikes } while (found); + if (cleaned.size() == 2) + { + // Ticket #9871: open polygon with only two points. + // the second point forms, by definition, a spike + cleaned.pop_back(); + } + // Close if necessary if (geometry::closure::value == geometry::closed) { diff --git a/test/algorithms/remove_spikes.cpp b/test/algorithms/remove_spikes.cpp index 97552e570..2545e10ba 100644 --- a/test/algorithms/remove_spikes.cpp +++ b/test/algorithms/remove_spikes.cpp @@ -134,6 +134,32 @@ void test_polygons() test_geometry("spike_with_corner", "POLYGON((0 0,0 4,4 4,4 2,6 2,6 4,6 2,4 2,4 0,0 0))", 16, 16); + + test_geometry("triangle0", + "POLYGON((0 0,0 4,2 0,4 0,0 0))", + 4, 6 + sqrt(20.0)); + test_geometry("triangle1", + "POLYGON((0 4,2 0,4 0,0 0,0 4))", + 4, 6 + sqrt(20.0)); + test_geometry("triangle2", + "POLYGON((2 0,4 0,0 0,0 4,2 0))", + 4, 6 + sqrt(20.0)); + test_geometry("triangle3", + "POLYGON((4 0,0 0,0 4,2 0,4 0))", + 4, 6 + sqrt(20.0)); + + test_geometry("only_spike1", + "POLYGON((0 0,2 2,0 0))", + 0, 0); + test_geometry("only_spike2", + "POLYGON((0 0,2 2,4 4,2 2,0 0))", + 0, 0); + test_geometry("only_spike3", + "POLYGON((0 0,2 2,4 4,0 0))", + 0, 0); + test_geometry("only_spike4", + "POLYGON((0 0,4 4,2 2,0 0))", + 0, 0); }