mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 13:34:10 +00:00
[buffer] change last fix by adding is_flat_start/end properties to pieces.
These marks are used to check if a turn is really inside the generated buffer, or on the flat end (then it should be kept). This will NOT YET work for one-sided buffers.
This commit is contained in:
parent
f6808f8277
commit
694299b7c7
@ -274,6 +274,9 @@ struct buffer_range
|
||||
* pup: penultimate_point
|
||||
*/
|
||||
|
||||
bool const mark_flat
|
||||
= end_strategy.get_piece_type() == geometry::strategy::buffer::buffered_flat_end;
|
||||
|
||||
geometry::strategy::buffer::result_code result = geometry::strategy::buffer::result_no_output;
|
||||
bool first = true;
|
||||
|
||||
@ -318,6 +321,11 @@ struct buffer_range
|
||||
|
||||
collection.add_side_piece(*prev, *it, generated_side, first);
|
||||
|
||||
if (first && mark_flat)
|
||||
{
|
||||
collection.mark_flat_start();
|
||||
}
|
||||
|
||||
penultimate_point = *prev;
|
||||
ultimate_point = *it;
|
||||
last_p1 = generated_side.front();
|
||||
@ -331,6 +339,12 @@ struct buffer_range
|
||||
first_p2 = generated_side.back();
|
||||
}
|
||||
}
|
||||
|
||||
if (mark_flat)
|
||||
{
|
||||
collection.mark_flat_end();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
@ -956,11 +970,6 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
|
||||
typename tag_cast<typename tag<GeometryInput>::type, areal_tag>::type,
|
||||
areal_tag
|
||||
>::type::value;
|
||||
bool const linear = boost::is_same
|
||||
<
|
||||
typename tag_cast<typename tag<GeometryInput>::type, linear_tag>::type,
|
||||
linear_tag
|
||||
>::type::value;
|
||||
|
||||
dispatch::buffer_inserter
|
||||
<
|
||||
@ -977,8 +986,7 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
|
||||
robust_policy, intersection_strategy.get_side_strategy());
|
||||
|
||||
collection.get_turns();
|
||||
collection.classify_turns(linear
|
||||
&& end_strategy.get_piece_type() == strategy::buffer::buffered_flat_end);
|
||||
collection.classify_turns();
|
||||
if (BOOST_GEOMETRY_CONDITION(areal))
|
||||
{
|
||||
collection.check_remaining_points(distance_strategy);
|
||||
|
@ -217,6 +217,8 @@ struct buffered_piece_collection
|
||||
// 2: half, not part of offsetted rings - part of robust ring
|
||||
std::vector<point_type> helper_points; // 4 points for side, 3 points for join - 0 points for flat-end
|
||||
#endif
|
||||
bool is_flat_start;
|
||||
bool is_flat_end;
|
||||
|
||||
bool is_convex;
|
||||
bool is_monotonic_increasing[2]; // 0=x, 1=y
|
||||
@ -245,6 +247,8 @@ struct buffered_piece_collection
|
||||
, right_index(-1)
|
||||
, last_segment_index(-1)
|
||||
, offsetted_count(-1)
|
||||
, is_flat_start(false)
|
||||
, is_flat_end(false)
|
||||
, is_convex(false)
|
||||
, robust_min_comparable_radius(0)
|
||||
, robust_max_comparable_radius(0)
|
||||
@ -499,7 +503,7 @@ struct buffered_piece_collection
|
||||
}
|
||||
}
|
||||
|
||||
inline void classify_turns(bool linear_flat_end)
|
||||
inline void classify_turns()
|
||||
{
|
||||
for (typename boost::range_iterator<turn_vector_type>::type it =
|
||||
boost::begin(m_turns); it != boost::end(m_turns); ++it)
|
||||
@ -508,7 +512,7 @@ struct buffered_piece_collection
|
||||
{
|
||||
it->location = inside_buffer;
|
||||
}
|
||||
if (it->count_on_original_boundary > 0 && ! linear_flat_end)
|
||||
if (it->count_on_original_boundary > 0)
|
||||
{
|
||||
it->location = inside_buffer;
|
||||
}
|
||||
@ -1233,6 +1237,24 @@ struct buffered_piece_collection
|
||||
}
|
||||
}
|
||||
|
||||
inline void mark_flat_start()
|
||||
{
|
||||
if (! m_pieces.empty())
|
||||
{
|
||||
piece& back = m_pieces.back();
|
||||
back.is_flat_start = true;
|
||||
}
|
||||
}
|
||||
|
||||
inline void mark_flat_end()
|
||||
{
|
||||
if (! m_pieces.empty())
|
||||
{
|
||||
piece& back = m_pieces.back();
|
||||
back.is_flat_end = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
inline void enrich()
|
||||
|
@ -422,6 +422,13 @@ class analyse_turn_wrt_piece
|
||||
{
|
||||
points[i] = piece.robust_ring[piece.offsetted_count + i];
|
||||
}
|
||||
|
||||
// 3--offsetted outline--0
|
||||
// | |
|
||||
// left | | right
|
||||
// | |
|
||||
// 2===>==original===>===1
|
||||
|
||||
}
|
||||
else if (helper_count == 3)
|
||||
{
|
||||
@ -445,12 +452,15 @@ class analyse_turn_wrt_piece
|
||||
{
|
||||
return analyse_on_offsetted;
|
||||
}
|
||||
if (comparator(point, points[1]) || comparator(point, points[2]))
|
||||
if (comparator(point, points[1]))
|
||||
{
|
||||
// It lies on the corner of a helper segment. For linear buffer,
|
||||
// on flat and, this point should not be deleted.
|
||||
// But if it is NOT on a flat end it might be discarded
|
||||
return analyse_on_original_boundary;
|
||||
// On original, right corner
|
||||
return piece.is_flat_end ? analyse_continue : analyse_on_original_boundary;
|
||||
}
|
||||
if (comparator(point, points[2]))
|
||||
{
|
||||
// On original, left corner
|
||||
return piece.is_flat_start ? analyse_continue : analyse_on_original_boundary;
|
||||
}
|
||||
|
||||
// Right side of the piece
|
||||
|
@ -155,6 +155,7 @@ void test_all()
|
||||
test_one<linestring, polygon>("one_bend", one_bend, join_round, end_round, 35.5603, 1.5, 1.5);
|
||||
test_one<linestring, polygon>("one_bend", one_bend, join_miter, end_round, 35.7601, 1.5, 1.5);
|
||||
|
||||
test_one<linestring, polygon>("two_bends", two_bends, join_round, end_round, 46.2995, 1.5, 1.5);
|
||||
test_one<linestring, polygon>("two_bends", two_bends, join_round, end_flat, 39.235, 1.5, 1.5);
|
||||
test_one<linestring, polygon>("two_bends", two_bends, join_round_by_divide, end_flat, 39.235, 1.5, 1.5);
|
||||
test_one<linestring, polygon>("two_bends", two_bends, join_miter, end_flat, 39.513, 1.5, 1.5);
|
||||
@ -303,6 +304,14 @@ void test_all()
|
||||
test_one<linestring, polygon>("mysql_25662426a_5", mysql_25662426a, join_round32, end_round32, 266.8505, 5.0);
|
||||
test_one<linestring, polygon>("mysql_25662426a_10", mysql_25662426a, join_round32, end_round32, 660.7355, 10.0);
|
||||
|
||||
test_one<linestring, polygon>("mysql_25662426a_05", mysql_25662426a, join_round32, end_flat, 26.8352, 0.5);
|
||||
test_one<linestring, polygon>("mysql_25662426a_1", mysql_25662426a, join_round32, end_flat, 53.3411, 1.0);
|
||||
test_one<linestring, polygon>("mysql_25662426a_2", mysql_25662426a, join_round32, end_flat, 97.3644, 2.0);
|
||||
test_one<linestring, polygon>("mysql_25662426a_3", mysql_25662426a, join_round32, end_flat, 138.0697, 3.0);
|
||||
test_one<linestring, polygon>("mysql_25662426a_4", mysql_25662426a, join_round32, end_flat, 181.5115, 4.0);
|
||||
test_one<linestring, polygon>("mysql_25662426a_5", mysql_25662426a, join_round32, end_flat, 227.8325, 5.0);
|
||||
test_one<linestring, polygon>("mysql_25662426a_10", mysql_25662426a, join_round32, end_flat, 534.1084, 10.0);
|
||||
|
||||
#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS)
|
||||
// Left
|
||||
test_one<linestring, polygon>("mysql_25662426a_1", mysql_25662426a, join_round32, end_round32, 54.9018, 1.0, 0.0);
|
||||
|
@ -268,7 +268,12 @@ private :
|
||||
typedef typename bg::point_type<ring_type>::type point_type;
|
||||
|
||||
std::ostringstream out;
|
||||
out << piece.index << " (" << piece_type_char(piece.type) << ") " << piece.first_seg_id.segment_index << ".." << piece.last_segment_index - 1;
|
||||
out << piece.index
|
||||
<< (piece.is_flat_start ? " FS" : "")
|
||||
<< (piece.is_flat_end ? " FE" : "")
|
||||
<< " (" << piece_type_char(piece.type) << ") "
|
||||
<< piece.first_seg_id.segment_index
|
||||
<< ".." << piece.last_segment_index - 1;
|
||||
point_type label_point = bg::return_centroid<point_type>(corner);
|
||||
|
||||
if ((piece.type == bg::strategy::buffer::buffered_concave
|
||||
|
Loading…
x
Reference in New Issue
Block a user