diff options
Diffstat (limited to 'boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp')
-rw-r--r-- | boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp b/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp index fb73840798..724996ae33 100644 --- a/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp +++ b/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp @@ -102,6 +102,43 @@ inline void append_no_dups_or_spikes(Range& range, Point const& point, } } +template <typename Range, typename Point, typename SideStrategy, typename RobustPolicy> +inline void append_no_collinear(Range& range, Point const& point, + SideStrategy const& strategy, + RobustPolicy const& robust_policy) +{ + // Stricter version, not allowing any point in a linear row + // (spike, continuation or same point) + + // The code below this condition checks all spikes/dups + // for geometries >= 3 points. + // So we have to check the first potential duplicate differently + if (boost::size(range) == 1 + && points_equal_or_close(*(boost::begin(range)), point, robust_policy)) + { + return; + } + + traits::push_back<Range>::apply(range, point); + + // If a point is equal, or forming a spike, remove the pen-ultimate point + // because this one caused the spike. + // If so, the now-new-pen-ultimate point can again cause a spike + // (possibly at a corner). So keep doing this. + // Besides spikes it will also avoid adding duplicates. + while(boost::size(range) >= 3 + && point_is_collinear(point, + *(boost::end(range) - 3), + *(boost::end(range) - 2), + strategy, + robust_policy)) + { + // Use the Concept/traits, so resize and append again + traits::resize<Range>::apply(range, boost::size(range) - 2); + traits::push_back<Range>::apply(range, point); + } +} + template <typename Range, typename SideStrategy, typename RobustPolicy> inline void clean_closing_dups_and_spikes(Range& range, SideStrategy const& strategy, @@ -137,8 +174,8 @@ inline void clean_closing_dups_and_spikes(Range& range, } // Check if closing point is a spike (this is so if the second point is - // considered as a spike w.r.t. the last segment) - if (point_is_spike_or_equal(*second, *ultimate, *first, strategy, robust_policy)) + // considered as collinear w.r.t. the last segment) + if (point_is_collinear(*second, *ultimate, *first, strategy, robust_policy)) { range::erase(range, first); if (BOOST_GEOMETRY_CONDITION(closed)) |