diff --git a/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp b/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp index b2e316837..e94072b73 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp @@ -161,6 +161,7 @@ struct buffer_range std::vector range_out; end_strategy.apply(penultimate_input, prev_perp2, previous_input, perp1, side, distance, range_out); collection.add_endcap(end_strategy, range_out, previous_input); + collection.set_current_ring_concave(); } return; case strategy::buffer::join_convex : diff --git a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp index e58297c29..6ba257eed 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp @@ -636,12 +636,15 @@ struct buffered_piece_collection } } + inline void set_current_ring_concave() + { + BOOST_ASSERT(boost::size(offsetted_rings) > 0); + offsetted_rings.back().has_concave = true; + } + inline int add_point(point_type const& p) { - BOOST_ASSERT - ( - boost::size(offsetted_rings) > 0 - ); + BOOST_ASSERT(boost::size(offsetted_rings) > 0); current_segment_id.segment_index++; offsetted_rings.back().push_back(p); @@ -652,6 +655,11 @@ struct buffered_piece_collection inline piece& create_piece(strategy::buffer::piece_type type, bool decrease_segment_index_by_one) { + if (type == strategy::buffer::buffered_concave) + { + offsetted_rings.back().has_concave = true; + } + piece pc; pc.type = type; pc.index = boost::size(m_pieces); diff --git a/include/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp b/include/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp index 03ec598c9..d7708edfa 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp @@ -43,11 +43,13 @@ struct buffered_ring_collection_tag : polygonal_tag, multi_tag template struct buffered_ring : public Ring { + bool has_concave; bool has_accepted_intersections; bool has_discarded_intersections; inline buffered_ring() - : has_accepted_intersections(false) + : has_concave(false) + , has_accepted_intersections(false) , has_discarded_intersections(false) {} diff --git a/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp b/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp index 395921cca..84900011d 100644 --- a/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp @@ -69,6 +69,17 @@ class piece_turn_visitor || piece1.index == piece2.right_index; } + template + inline bool is_on_same_convex_ring(Piece const& piece1, Piece const& piece2) const + { + if (piece1.first_seg_id.multi_index != piece2.first_seg_id.multi_index) + { + return false; + } + + return ! m_rings[piece1.first_seg_id.multi_index].has_concave; + } + template inline void move_to_next_point(Range const& range, Iterator& next) const { @@ -172,11 +183,13 @@ public: { boost::ignore_unused_variable_warning(first); if ( is_adjacent(piece1, piece2) + || is_on_same_convex_ring(piece1, piece2) || detail::disjoint::disjoint_box_box(piece1.robust_envelope, piece2.robust_envelope)) { return; } + calculate_turns(piece1, piece2); } };