summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp
diff options
context:
space:
mode:
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.hpp41
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))