mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 21:44:04 +00:00
[buffer] fix check of buffer_flat_end for inside
This commit is contained in:
parent
da1323716a
commit
b6b49f5308
@ -413,8 +413,9 @@ struct buffer_inserter<point_tag, Point, RingOutput>
|
||||
RobustPolicy const& robust_policy)
|
||||
{
|
||||
collection.start_new_ring();
|
||||
typedef detail::buffer::buffer_point<Point, RingOutput> base;
|
||||
typedef detail::buffer::buffer_point<Point, RingOutput> base;
|
||||
base::generate_circle(point, collection, distance, join_strategy, end_strategy, robust_policy);
|
||||
collection.finish_ring();
|
||||
}
|
||||
};
|
||||
|
||||
@ -621,6 +622,7 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
|
||||
strategy::buffer::buffer_side_right,
|
||||
distance, side_strategy, join_strategy, end_strategy, robust_policy,
|
||||
first_p1);
|
||||
collection.finish_ring();
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -663,6 +665,7 @@ private:
|
||||
{
|
||||
collection.start_new_ring();
|
||||
policy::apply(*it, collection, distance, side_strategy, join_strategy, end_strategy, robust_policy);
|
||||
collection.finish_ring();
|
||||
}
|
||||
}
|
||||
|
||||
@ -711,6 +714,7 @@ public:
|
||||
collection.start_new_ring();
|
||||
policy::apply(exterior_ring(polygon), collection,
|
||||
distance, side_strategy, join_strategy, end_strategy, robust_policy);
|
||||
collection.finish_ring();
|
||||
}
|
||||
|
||||
apply_interior_rings(interior_rings(polygon),
|
||||
|
@ -118,6 +118,9 @@ struct buffered_piece_collection
|
||||
strategy::buffer::piece_type type;
|
||||
int index;
|
||||
|
||||
int left_index; // points to previous piece
|
||||
int right_index; // points to next piece
|
||||
|
||||
// The next two members form together a complete clockwise ring
|
||||
// for each piece (with one dupped point)
|
||||
|
||||
@ -139,6 +142,7 @@ struct buffered_piece_collection
|
||||
|
||||
piece_vector_type m_pieces;
|
||||
turn_vector_type m_turns;
|
||||
int m_first_piece_index;
|
||||
|
||||
buffered_ring_collection<buffered_ring<Ring> > offsetted_rings; // indexed by multi_index
|
||||
std::vector< std::vector < robust_point_type > > robust_offsetted_rings;
|
||||
@ -159,7 +163,8 @@ struct buffered_piece_collection
|
||||
};
|
||||
|
||||
buffered_piece_collection(RobustPolicy const& robust_policy)
|
||||
: m_robust_policy(robust_policy)
|
||||
: m_first_piece_index(-1)
|
||||
, m_robust_policy(robust_policy)
|
||||
{}
|
||||
|
||||
|
||||
@ -530,8 +535,8 @@ struct buffered_piece_collection
|
||||
// Check if it is inside any of the pieces
|
||||
turn_in_piece_visitor
|
||||
<
|
||||
turn_vector_type
|
||||
> visitor(m_turns);
|
||||
turn_vector_type, piece_vector_type
|
||||
> visitor(m_turns, m_pieces);
|
||||
|
||||
geometry::partition
|
||||
<
|
||||
@ -559,6 +564,19 @@ struct buffered_piece_collection
|
||||
current_segment_id.segment_index = 0;
|
||||
|
||||
offsetted_rings.resize(n + 1);
|
||||
|
||||
m_first_piece_index = boost::size(m_pieces);
|
||||
}
|
||||
|
||||
inline void finish_ring()
|
||||
{
|
||||
BOOST_ASSERT(m_first_piece_index != -1);
|
||||
|
||||
// Reassign left-of-first and right-of-last
|
||||
geometry::range::at(m_pieces, m_first_piece_index).left_index
|
||||
= boost::size(m_pieces) - 1;
|
||||
geometry::range::back(m_pieces).right_index = m_first_piece_index;
|
||||
m_first_piece_index = -1;
|
||||
}
|
||||
|
||||
inline int add_point(point_type const& p)
|
||||
@ -582,6 +600,10 @@ struct buffered_piece_collection
|
||||
pc.index = boost::size(m_pieces);
|
||||
pc.first_seg_id = current_segment_id;
|
||||
|
||||
// Assign left/right (for first/last piece per ring they will be re-assigned later)
|
||||
pc.left_index = pc.index - 1;
|
||||
pc.right_index = pc.index + 1;
|
||||
|
||||
std::size_t const n = boost::size(offsetted_rings.back());
|
||||
pc.first_seg_id.segment_index = decrease_segment_index_by_one ? n - 1 : n;
|
||||
|
||||
|
@ -44,10 +44,12 @@ struct turn_ovelaps_box
|
||||
return ! geometry::disjoint(box, turn.robust_point);
|
||||
}
|
||||
};
|
||||
template <typename Turns>
|
||||
|
||||
template <typename Turns, typename Pieces>
|
||||
class turn_in_piece_visitor
|
||||
{
|
||||
Turns& m_turns; // because partition is currently operating on const input only
|
||||
Pieces const& m_pieces; // to check for piece-type
|
||||
|
||||
template <typename Point>
|
||||
static inline bool projection_on_segment(Point const& subject, Point const& p, Point const& q)
|
||||
@ -103,10 +105,12 @@ class turn_in_piece_visitor
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
inline turn_in_piece_visitor(Turns& turns)
|
||||
inline turn_in_piece_visitor(Turns& turns, Pieces const& pieces)
|
||||
: m_turns(turns)
|
||||
, m_pieces(pieces)
|
||||
{}
|
||||
|
||||
template <typename Turn, typename Piece>
|
||||
@ -133,9 +137,23 @@ public:
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
typename boost::range_value<Pieces>::type const& pc
|
||||
= m_pieces[turn.operations[i].piece_index];
|
||||
if (pc.type == strategy::buffer::buffered_flat_end)
|
||||
{
|
||||
if (pc.left_index == piece.index
|
||||
|| pc.right_index == piece.index)
|
||||
{
|
||||
// If it is a flat end, don't compare against its neighbor:
|
||||
// it will always be located on one of the helper segments
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int geometry_code = detail::within::point_in_geometry(turn.robust_point, piece.robust_ring);
|
||||
|
||||
if (geometry_code == -1)
|
||||
{
|
||||
return;
|
||||
@ -149,7 +167,6 @@ public:
|
||||
// It is on the border but not on the offsetted ring.
|
||||
// Then it is somewhere on the helper-segments
|
||||
// Classify it as inside
|
||||
// TODO: for neighbouring flat ends this does not apply
|
||||
geometry_code = 1;
|
||||
mutable_turn.count_on_helper++;
|
||||
}
|
||||
|
@ -90,7 +90,6 @@ void test_all()
|
||||
|
||||
// Cases below should still be fixed because of remaining flat-end/inside bug
|
||||
|
||||
#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS)
|
||||
// Different cases with intersection points on flat and (left/right from line itself)
|
||||
test_one<linestring, buf::join_round, buf::end_flat, polygon>("overlapping_asym_150_010", overlapping, 48.308, 1.5, 0.25);
|
||||
test_one<linestring, buf::join_miter, buf::end_flat, polygon>("overlapping_asym_150_010", overlapping, 50.770, 1.5, 0.25);
|
||||
@ -98,12 +97,11 @@ void test_all()
|
||||
test_one<linestring, buf::join_miter, buf::end_flat, polygon>("overlapping_asym_150_075", overlapping, 60.985, 1.5, 0.75);
|
||||
test_one<linestring, buf::join_round, buf::end_flat, polygon>("overlapping_asym_150_100", overlapping, 62.514, 1.5, 1.0);
|
||||
test_one<linestring, buf::join_miter, buf::end_flat, polygon>("overlapping_asym_150_100", overlapping, 64.984, 1.5, 1.0);
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS)
|
||||
// Having flat end
|
||||
test_one<linestring, buf::join_round, buf::end_flat, polygon>("for_collinear", for_collinear, 68.561, 2.0, 2.0);
|
||||
test_one<linestring, buf::join_miter, buf::end_flat, polygon>("for_collinear", for_collinear, 72, 2.0, 2.0);
|
||||
#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS)
|
||||
test_one<linestring, buf::join_round, buf::end_flat, polygon>("for_collinear2", for_collinear2, 74.387, 2.0, 2.0);
|
||||
test_one<linestring, buf::join_miter, buf::end_flat, polygon>("for_collinear2", for_collinear2, 78.0, 2.0, 2.0);
|
||||
#endif
|
||||
|
@ -32,9 +32,7 @@ void test_all()
|
||||
|
||||
// Round joins / flat ends:
|
||||
test_one<multi_linestring_type, buf::join_round, buf::end_flat, polygon>("simplex", simplex, 38.2623, 1.5, 1.5);
|
||||
#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS)
|
||||
test_one<multi_linestring_type, buf::join_round, buf::end_flat, polygon>("two_bends", two_bends, 64.6217, 1.5, 1.5);
|
||||
#endif
|
||||
|
||||
// TODO this should be fixed test_one<multi_linestring_type, buf::join_round, buf::end_flat, polygon>("turn_inside", turn_inside, 99, 1.5, 1.5);
|
||||
test_one<multi_linestring_type, buf::join_round, buf::end_flat, polygon>("two_bends_asym", two_bends, 52.3793, 1.5, 0.75);
|
||||
@ -43,10 +41,8 @@ void test_all()
|
||||
// test_one<multi_linestring_type, buf::join_round, polygon>("turn_inside_asym_neg", turn_inside, 99, +1.5, -1.0);
|
||||
|
||||
// Miter / divide joins, various ends
|
||||
#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS)
|
||||
test_one<multi_linestring_type, buf::join_round_by_divide, buf::end_flat, polygon>("two_bends", two_bends, 64.6217, 1.5, 1.5);
|
||||
test_one<multi_linestring_type, buf::join_miter, buf::end_flat, polygon>("two_bends", two_bends, 65.1834, 1.5, 1.5);
|
||||
#endif
|
||||
test_one<multi_linestring_type, buf::join_miter, buf::end_round, polygon>("two_bends", two_bends, 75.2917, 1.5, 1.5);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user