mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-13 00:22:10 +00:00
[buffer] fix the case where a side was skipped because detected as equal, followed
by an end-cap. This caused further problems. Detection of empty sides is now delegated to the strategy
This commit is contained in:
@@ -253,7 +253,6 @@ struct buffer_range
|
||||
RobustPolicy
|
||||
>::type robust_point_type;
|
||||
|
||||
robust_point_type previous_robust_input;
|
||||
point_type second_point, penultimate_point, ultimate_point; // last two points from begin/end
|
||||
|
||||
/*
|
||||
@@ -278,57 +277,50 @@ struct buffer_range
|
||||
|
||||
Iterator it = begin;
|
||||
|
||||
geometry::recalculate(previous_robust_input, *begin, robust_policy);
|
||||
|
||||
std::vector<output_point_type> generated_side;
|
||||
generated_side.reserve(2);
|
||||
|
||||
for (Iterator prev = it++; it != end; ++it)
|
||||
{
|
||||
robust_point_type robust_input;
|
||||
geometry::recalculate(robust_input, *it, robust_policy);
|
||||
// Check on equality - however, if input is simplified, this is
|
||||
// unlikely (though possible by rescaling or for degenerated pointlike polygons)
|
||||
if (! detail::equals::equals_point_point(previous_robust_input, robust_input))
|
||||
generated_side.clear();
|
||||
side_strategy.apply(*prev, *it, side,
|
||||
distance_strategy, generated_side);
|
||||
|
||||
if (generated_side.empty())
|
||||
{
|
||||
generated_side.clear();
|
||||
side_strategy.apply(*prev, *it, side,
|
||||
distance_strategy, generated_side);
|
||||
|
||||
if (generated_side.empty())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
result = true;
|
||||
|
||||
if (! first)
|
||||
{
|
||||
add_join(collection,
|
||||
penultimate_point,
|
||||
*prev, last_p1, last_p2,
|
||||
*it, generated_side.front(), generated_side.back(),
|
||||
side,
|
||||
distance_strategy, join_strategy, end_strategy,
|
||||
robust_policy);
|
||||
}
|
||||
|
||||
collection.add_side_piece(*prev, *it, generated_side, first);
|
||||
|
||||
penultimate_point = *prev;
|
||||
ultimate_point = *it;
|
||||
last_p1 = generated_side.front();
|
||||
last_p2 = generated_side.back();
|
||||
prev = it;
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
second_point = *it;
|
||||
first_p1 = generated_side.front();
|
||||
first_p2 = generated_side.back();
|
||||
}
|
||||
// Because input is simplified, this is improbable,
|
||||
// but it can happen for degenerate geometries
|
||||
// Further handling of this side is skipped
|
||||
continue;
|
||||
}
|
||||
|
||||
result = true;
|
||||
|
||||
if (! first)
|
||||
{
|
||||
add_join(collection,
|
||||
penultimate_point,
|
||||
*prev, last_p1, last_p2,
|
||||
*it, generated_side.front(), generated_side.back(),
|
||||
side,
|
||||
distance_strategy, join_strategy, end_strategy,
|
||||
robust_policy);
|
||||
}
|
||||
|
||||
collection.add_side_piece(*prev, *it, generated_side, first);
|
||||
|
||||
penultimate_point = *prev;
|
||||
ultimate_point = *it;
|
||||
last_p1 = generated_side.front();
|
||||
last_p2 = generated_side.back();
|
||||
prev = it;
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
second_point = *it;
|
||||
first_p1 = generated_side.front();
|
||||
first_p2 = generated_side.back();
|
||||
}
|
||||
previous_robust_input = robust_input;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -805,11 +805,20 @@ struct buffered_piece_collection
|
||||
|
||||
inline void init_rescale_piece(piece& pc, std::size_t helper_points_size)
|
||||
{
|
||||
if (pc.first_seg_id.segment_index < 0)
|
||||
{
|
||||
// This indicates an error situation: an earlier piece was empty
|
||||
// It currently does not happen
|
||||
// std::cout << "EMPTY " << pc.type << " " << pc.index << " " << pc.first_seg_id.multi_index << std::endl;
|
||||
pc.offsetted_count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(pc.first_seg_id.multi_index >= 0);
|
||||
BOOST_ASSERT(pc.last_segment_index >= 0);
|
||||
|
||||
pc.offsetted_count = pc.last_segment_index - pc.first_seg_id.segment_index;
|
||||
BOOST_ASSERT(pc.offsetted_count >= 0);
|
||||
BOOST_ASSERT(pc.first_seg_id.multi_index >= 0);
|
||||
BOOST_ASSERT(pc.first_seg_id.segment_index >= 0);
|
||||
BOOST_ASSERT(pc.last_segment_index >= 0);
|
||||
|
||||
pc.robust_ring.reserve(pc.offsetted_count + helper_points_size);
|
||||
|
||||
@@ -853,6 +862,11 @@ struct buffered_piece_collection
|
||||
|
||||
inline void calculate_robust_envelope(piece& pc)
|
||||
{
|
||||
if (pc.offsetted_count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
geometry::detail::envelope::envelope_range::apply(pc.robust_ring,
|
||||
pc.robust_envelope);
|
||||
|
||||
@@ -879,6 +893,11 @@ struct buffered_piece_collection
|
||||
const point_type& point3)
|
||||
{
|
||||
init_rescale_piece(pc, 3u);
|
||||
if (pc.offsetted_count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
add_helper_point(pc, point1);
|
||||
robust_point_type mid_point = add_helper_point(pc, point2);
|
||||
add_helper_point(pc, point3);
|
||||
|
||||
Reference in New Issue
Block a user