diff --git a/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp b/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp index adae2205f..943a62869 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp @@ -203,6 +203,9 @@ struct buffer_range geometry::recalculate(previous_robust_input, *begin, robust_policy); + std::vector generated_side; + generated_side.reserve(2); + for (Iterator prev = it++; it != end; ++it) { robust_point_type robust_input; @@ -211,35 +214,35 @@ struct buffer_range // unlikely (though possible by rescaling) if (! detail::equals::equals_point_point(previous_robust_input, robust_input)) { - output_point_type p1, p2; - + generated_side.clear(); strategy::buffer::buffer_side::apply(*prev, - *it, side, distance_strategy, p1, p2); + *it, side, distance_strategy, generated_side); if (! first) { add_join(collection, phase, penultimate_point, *prev, previous_p1, previous_p2, - *it, p1, p2, + *it, generated_side.front(), generated_side.back(), side, distance_strategy, join_strategy, end_strategy, robust_policy); } + collection.add_piece(strategy::buffer::buffered_segment, - *prev, *it, p1, p2, first); + *prev, *it, generated_side, first); penultimate_point = *prev; ultimate_point = *it; - previous_p1 = p1; - previous_p2 = p2; + previous_p1 = generated_side.front(); + previous_p2 = generated_side.back(); prev = it; if (first) { first = false; second_point = *it; - first_p1 = p1; - first_p2 = p2; + first_p1 = generated_side.front(); + first_p2 = generated_side.back(); } } previous_robust_input = robust_input; @@ -265,16 +268,16 @@ struct buffer_range // Generate perpendicular points to the reverse side, // these points are necessary for all end-cap strategies // TODO fix this (approach) for one-side buffer (1.5 - -1.0) - output_point_type rp1, rp2; + generated_side.clear(); strategy::buffer::buffer_side::apply(ultimate_point, penultimate_point, side == strategy::buffer::buffer_side_left ? strategy::buffer::buffer_side_right : strategy::buffer::buffer_side_left, - distance_strategy, rp2, rp1); + distance_strategy, generated_side); std::vector range_out; - end_strategy.apply(penultimate_point, previous_p2, ultimate_point, rp2, side, distance_strategy, range_out); + end_strategy.apply(penultimate_point, previous_p2, ultimate_point, generated_side.front(), side, distance_strategy, range_out); collection.add_endcap(end_strategy, range_out, ultimate_point); } } 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 dfdd15636..bdad2acf8 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp @@ -589,8 +589,9 @@ struct buffered_piece_collection return m_pieces.back(); } + template inline void add_piece(strategy::buffer::piece_type type, point_type const& p1, point_type const& p2, - point_type const& b1, point_type const& b2, bool first) + Range const& range, bool first) { piece& pc = add_piece(type, ! first); @@ -599,14 +600,14 @@ struct buffered_piece_collection // But for now we need it to calculate intersections if (first) { - add_point(b1); + add_point(range.front()); } - pc.last_segment_index = add_point(b2); + pc.last_segment_index = add_point(range.back()); - pc.helper_segments.push_back(b2); + pc.helper_segments.push_back(range.back()); pc.helper_segments.push_back(p2); pc.helper_segments.push_back(p1); - pc.helper_segments.push_back(b1); + pc.helper_segments.push_back(range.front()); } inline void add_piece(strategy::buffer::piece_type type, point_type const& p, diff --git a/include/boost/geometry/strategies/cartesian/buffer_side.hpp b/include/boost/geometry/strategies/cartesian/buffer_side.hpp index 593fd1ea2..abae27e6f 100644 --- a/include/boost/geometry/strategies/cartesian/buffer_side.hpp +++ b/include/boost/geometry/strategies/cartesian/buffer_side.hpp @@ -41,15 +41,14 @@ struct buffer_side template < typename Point, - typename OutputPointType, + typename OutputRange, typename DistanceStrategy > static inline void apply( Point const& input_p1, Point const& input_p2, strategy::buffer::buffer_side_selector side, DistanceStrategy const& distance, - // TODO: the output will be a range - OutputPointType& side_p1, OutputPointType& side_p2) + OutputRange& output_range) { typedef typename coordinate_type::type coordinate_type; // Generate a block along (left or right of) the segment @@ -71,10 +70,12 @@ struct buffer_side coordinate_type const d = distance.apply(input_p1, input_p2, side); - set<0>(side_p1, get<0>(input_p1) + px * d); - set<1>(side_p1, get<1>(input_p1) + py * d); - set<0>(side_p2, get<0>(input_p2) + px * d); - set<1>(side_p2, get<1>(input_p2) + py * d); + output_range.resize(2); + + set<0>(output_range.front(), get<0>(input_p1) + px * d); + set<1>(output_range.front(), get<1>(input_p1) + py * d); + set<0>(output_range.back(), get<0>(input_p2) + px * d); + set<1>(output_range.back(), get<1>(input_p2) + py * d); } };