[buffer] use range instead of two points as output for buffer_side strategy

This commit is contained in:
Barend Gehrels
2014-07-02 13:04:16 +02:00
parent c94d6d469d
commit c9880fbdff
3 changed files with 29 additions and 24 deletions

View File

@@ -203,6 +203,9 @@ struct buffer_range
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;
@@ -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<output_point_type> 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);
}
}

View File

@@ -589,8 +589,9 @@ struct buffered_piece_collection
return m_pieces.back();
}
template <typename Range>
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,

View File

@@ -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<Point>::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);
}
};