diff --git a/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp b/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp index 405213bb2..9ecba77e8 100644 --- a/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp @@ -26,6 +26,7 @@ #include #include #include + #if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION) #include #endif @@ -201,14 +202,20 @@ public : typedef typename Turn::robust_point_type point_type; typedef typename geometry::coordinate_type::type coordinate_type; - coordinate_type const point_y = geometry::get<1>(turn.robust_point); - +#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION) + typedef geometry::model::referring_segment segment_type; + segment_type const p(turn.rob_pi, turn.rob_pj); + segment_type const q(turn.rob_qi, turn.rob_qj); +#else typedef strategy::within::winding strategy_type; typename strategy_type::state_type state; strategy_type strategy; boost::ignore_unused(strategy); - +#endif + + coordinate_type const point_y = geometry::get<1>(turn.robust_point); + for (std::size_t s = 0; s < piece.sections.size(); s++) { section_type const& section = piece.sections[s]; @@ -223,6 +230,23 @@ public : point_type const& previous = piece.robust_ring[i - 1]; point_type const& current = piece.robust_ring[i]; +#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION) + segment_type const r(previous, current); + int const side = strategy::side::side_of_intersection::apply(p, q, r, + turn.robust_point); + + // Sections are monotonic in y-dimension + if (side == 1) + { + // Left on segment + return analyse_disjoint; + } + else if (side == 0) + { + // On segment + return analyse_on_offsetted; + } +#else analyse_result code = check_segment(previous, current, turn, false); if (code != analyse_continue) { @@ -232,10 +256,15 @@ public : // Get the state (to determine it is within), we don't have // to cover the on-segment case (covered above) strategy.apply(turn.robust_point, previous, current, state); +#endif } } } +#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION) + // It is nowhere outside, and not on segment, so it is within + return analyse_within; +#else int const code = strategy.result(state); if (code == 1) { @@ -248,6 +277,7 @@ public : // Should normally not occur - on-segment is covered return analyse_unknown; +#endif } }; diff --git a/test/algorithms/buffer/multi_point_buffer.cpp b/test/algorithms/buffer/multi_point_buffer.cpp index ed8f72716..be69ecb3f 100644 --- a/test/algorithms/buffer/multi_point_buffer.cpp +++ b/test/algorithms/buffer/multi_point_buffer.cpp @@ -80,10 +80,6 @@ void test_all() template void test_many_points_per_circle() { -#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION) - // These tests still fail for the new approach - return; -#endif // Tests for large distances / many points in circles. // Before Boost 1.58, this would (seem to) hang. It is solved by using monotonic sections in get_turns for buffer // This is more time consuming, only calculate this for counter clockwise