mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 13:34:10 +00:00
[geometry] Instead of (non-rescaled) append, we clean rescaled dups afterwards.
We don't do it on the fly to avoid additional rescaling, it is done only once per point This also changes occasionally some number-of-points in testcases (now more cleaned)
This commit is contained in:
parent
2c2c384652
commit
9cd79d8033
@ -0,0 +1,135 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CLEAN_DUPS_AND_SPIKES_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CLEAN_DUPS_AND_SPIKES_HPP
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/mutable_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
// This is refactored from remove_spikes. This function considers rescaled points
|
||||
template <typename Range, typename RescalePolicy>
|
||||
static inline void clean_dups_and_spikes(Range& range,
|
||||
RescalePolicy const& rescale_policy)
|
||||
{
|
||||
std::size_t n = boost::size(range);
|
||||
if (n < core_detail::closure::minimum_ring_size
|
||||
<
|
||||
geometry::closure<Range>::value
|
||||
>::value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
typedef typename point_type<Range>::type point_type;
|
||||
|
||||
typedef std::pair
|
||||
<
|
||||
point_type,
|
||||
typename geometry::robust_point_type
|
||||
<
|
||||
point_type,
|
||||
RescalePolicy
|
||||
>::type
|
||||
> point_pair;
|
||||
|
||||
std::deque<point_pair> cleaned;
|
||||
for (typename boost::range_iterator<Range const>::type it = boost::begin(range);
|
||||
it != boost::end(range); ++it)
|
||||
{
|
||||
point_pair pp;
|
||||
pp.first = *it;
|
||||
geometry::recalculate(pp.second, pp.first, rescale_policy);
|
||||
|
||||
// Add point
|
||||
cleaned.push_back(pp);
|
||||
|
||||
while(cleaned.size() >= 3
|
||||
&& point_is_spike_or_equal(cleaned.back().second,
|
||||
(cleaned.end() - 3)->second,
|
||||
(cleaned.end() - 2)->second))
|
||||
{
|
||||
// Remove pen-ultimate point causing the spike (or which was equal)
|
||||
cleaned.erase(cleaned.end() - 2);
|
||||
}
|
||||
}
|
||||
|
||||
// For a closed-polygon, remove closing point
|
||||
// this makes checking first point(s) easier and consistent
|
||||
if (geometry::closure<Range>::value == geometry::closed)
|
||||
{
|
||||
cleaned.pop_back();
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
do
|
||||
{
|
||||
found = false;
|
||||
|
||||
// Check for spike in first point
|
||||
int const penultimate = 2;
|
||||
while(cleaned.size() > 3
|
||||
&& point_is_spike_or_equal(cleaned.front().second,
|
||||
(cleaned.end() - penultimate)->second,
|
||||
cleaned.back().second))
|
||||
{
|
||||
cleaned.pop_back();
|
||||
found = true;
|
||||
}
|
||||
|
||||
// Check for spike in second point
|
||||
while(cleaned.size() > 3
|
||||
&& point_is_spike_or_equal((cleaned.begin() + 1)->second,
|
||||
cleaned.back().second,
|
||||
cleaned.front().second))
|
||||
{
|
||||
cleaned.pop_front();
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
while (found);
|
||||
|
||||
|
||||
// Create new output
|
||||
geometry::clear(range);
|
||||
range.reserve(n);
|
||||
for (typename boost::range_iterator<std::deque<point_pair> const>::type it = boost::begin(cleaned);
|
||||
it != boost::end(cleaned); ++it)
|
||||
{
|
||||
range.push_back(it->first);
|
||||
}
|
||||
|
||||
// Close if necessary
|
||||
if (geometry::closure<Range>::value == geometry::closed)
|
||||
{
|
||||
point_type const first = range.front();
|
||||
range.push_back(first);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CLEAN_DUPS_AND_SPIKES_HPP
|
@ -93,7 +93,7 @@ struct copy_segments_ring
|
||||
|
||||
for (size_type i = 0; i < count; ++i, ++it)
|
||||
{
|
||||
detail::overlay::append_no_dups_or_spikes(current_output, *it);
|
||||
traits::push_back<RangeOut>::apply(current_output, *it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/clean_dups_and_spikes.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
|
||||
@ -139,7 +139,7 @@ inline bool assign_next_ip(G1 const& g1, G2 const& g2,
|
||||
seg_id = info.seg_id;
|
||||
}
|
||||
|
||||
detail::overlay::append_no_dups_or_spikes(current_output, ip->point);
|
||||
traits::push_back<GeometryOut>::apply(current_output, ip->point);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -391,6 +391,7 @@ public :
|
||||
detail::overlay::debug_traverse(*current, *iit, "->Finished");
|
||||
if (geometry::num_points(current_output) >= min_num_points)
|
||||
{
|
||||
clean_dups_and_spikes(current_output, rescale_policy);
|
||||
rings.push_back(current_output);
|
||||
}
|
||||
}
|
||||
|
@ -185,9 +185,7 @@ void test_areal()
|
||||
|
||||
test_one<Polygon, Polygon, Polygon>("ggl_list_20110716_enrico",
|
||||
ggl_list_20110716_enrico[0], ggl_list_20110716_enrico[1],
|
||||
3,
|
||||
if_typed<ct, double>(21, 20),
|
||||
35723.8506317139);
|
||||
3, 16, 35723.8506317139);
|
||||
|
||||
test_one<Polygon, Polygon, Polygon>("ggl_list_20131119_james",
|
||||
ggl_list_20131119_james[0], ggl_list_20131119_james[1],
|
||||
|
@ -500,7 +500,7 @@ void test_all(bool test_self_tangencies = true, bool test_mixed = false)
|
||||
}
|
||||
test_traverse<polygon, polygon, operation_intersection>::apply("53_iet", 0, 0, case_53[0], case_53[2]);
|
||||
|
||||
test_traverse<polygon, polygon, operation_intersection>::apply("54_iet_iet", 1, 2, case_54[1], case_54[3]);
|
||||
test_traverse<polygon, polygon, operation_intersection>::apply("54_iet_iet", 2, 2, case_54[1], case_54[3]);
|
||||
if (test_self_tangencies)
|
||||
{
|
||||
test_traverse<polygon, polygon, operation_intersection>::apply("54_st_iet", 1, 2, case_54[0], case_54[3]);
|
||||
@ -647,7 +647,7 @@ void test_all(bool test_self_tangencies = true, bool test_mixed = false)
|
||||
2, 16, case_53[0], case_53[2]);
|
||||
if (test_self_tangencies)
|
||||
{
|
||||
test_traverse<polygon, polygon, operation_union>::apply("54_st_st", 2, 20, case_54[0], case_54[2]);
|
||||
test_traverse<polygon, polygon, operation_union>::apply("54_st_st", 3, 20, case_54[0], case_54[2]);
|
||||
test_traverse<polygon, polygon, operation_union>::apply("54_st_iet", 2, 20, case_54[0], case_54[3]);
|
||||
test_traverse<polygon, polygon, operation_union>::apply("54_iet_st", 2, 20, case_54[1], case_54[2]);
|
||||
}
|
||||
|
@ -221,16 +221,11 @@ void test_areal()
|
||||
|
||||
test_one<Polygon, Polygon, Polygon>("ggl_list_20110627_phillip",
|
||||
ggl_list_20110627_phillip[0], ggl_list_20110627_phillip[1],
|
||||
1, 0,
|
||||
if_typed<ct, double>(5, if_typed_tt<ct>(8, 8)),
|
||||
14729.07145);
|
||||
1, 0, 8, 14729.07145);
|
||||
|
||||
// FP might return different amount of points
|
||||
test_one<Polygon, Polygon, Polygon>("ggl_list_20110716_enrico",
|
||||
ggl_list_20110716_enrico[0], ggl_list_20110716_enrico[1],
|
||||
1, 1,
|
||||
if_typed<ct, double>(18, if_typed<ct, float>(-1, 17)),
|
||||
129904.197692871);
|
||||
1, 1, 15, 129904.197692871);
|
||||
|
||||
test_one<Polygon, Polygon, Polygon>("ggl_list_20110820_christophe",
|
||||
ggl_list_20110820_christophe[0], ggl_list_20110820_christophe[1],
|
||||
|
Loading…
x
Reference in New Issue
Block a user