From 529b8e804c02ec454c5c014ea969752bcd013ed3 Mon Sep 17 00:00:00 2001 From: Barend Gehrels Date: Wed, 11 Nov 2015 16:18:19 +0100 Subject: [PATCH] [overlay] fix ux/ux cases by sort order (instead of handle tangencies) --- .../detail/overlay/less_by_segment_ratio.hpp | 34 +++++++++++++++++-- test/algorithms/buffer/buffer_multi_point.cpp | 2 -- .../buffer/buffer_multi_polygon.cpp | 2 -- test/algorithms/buffer/buffer_polygon.cpp | 2 -- .../algorithms/set_operations/union/union.cpp | 2 -- .../set_operations/union/union_multi.cpp | 6 +--- 6 files changed, 33 insertions(+), 15 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/overlay/less_by_segment_ratio.hpp b/include/boost/geometry/algorithms/detail/overlay/less_by_segment_ratio.hpp index 6b77ab474..f0f8c3e76 100644 --- a/include/boost/geometry/algorithms/detail/overlay/less_by_segment_ratio.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/less_by_segment_ratio.hpp @@ -153,16 +153,46 @@ public : } + typedef typename boost::range_value::type turn_type; + turn_type const& left_turn = m_turn_points[left.turn_index]; + turn_type const& right_turn = m_turn_points[right.turn_index]; + // First check "real" intersection (crosses) // -> distance zero due to precision, solve it by sorting - if (m_turn_points[left.turn_index].method == method_crosses - && m_turn_points[right.turn_index].method == method_crosses) + if (left_turn.method == method_crosses + && right_turn.method == method_crosses) { return consider_relative_order(left, right); } + bool const left_ux = left_turn.combination(operation_blocked, operation_union); + bool const right_ux = right_turn.combination(operation_blocked, operation_union); + + operation_type const left_other_op = left_turn.operations[1 - left.operation_index].operation; + operation_type const right_other_op = right_turn.operations[1 - right.operation_index].operation; + + if (left_ux && right_ux) + { + + // Two ux on same ring at same point. Sort the open one last + // For example: + // 3 POINT(2 3) (left) x s:0, v:0, m:1 // u s:1, v:3, m:1 + // 2 POINT(2 3) (right) u s:0, v:0, m:1 // x s:1, v:1, m:0 + // Should be sorted as: first right, then left, because left has + // the union operation on the other ring + + BOOST_ASSERT(left_other_op != right_other_op); + + int const left_code = left_other_op == operation_blocked ? 0 : 1; + int const right_code = right_other_op == operation_blocked ? 0 : 1; + + return left_code < right_code; + } + + // OBSOLETE // If that is not the case, cluster it later on. // Indicate that this is necessary. + *m_clustered = true; return default_order(left, right); diff --git a/test/algorithms/buffer/buffer_multi_point.cpp b/test/algorithms/buffer/buffer_multi_point.cpp index 36a5eca6e..fc83d758f 100644 --- a/test/algorithms/buffer/buffer_multi_point.cpp +++ b/test/algorithms/buffer/buffer_multi_point.cpp @@ -62,11 +62,9 @@ void test_all() { bg::strategy::buffer::point_square point_strategy; -#ifdef BOOST_GEOMETRY_TEST_FAIL_TANGENCIES test_with_custom_strategies("grid_a50", grid_a, join, end_flat, distance_strategy(0.5), side_strategy, point_strategy, 7.0); -#endif #if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION) test_with_custom_strategies("grid_a54", diff --git a/test/algorithms/buffer/buffer_multi_polygon.cpp b/test/algorithms/buffer/buffer_multi_polygon.cpp index 5d8e6d581..a700a43d5 100644 --- a/test/algorithms/buffer/buffer_multi_polygon.cpp +++ b/test/algorithms/buffer/buffer_multi_polygon.cpp @@ -441,9 +441,7 @@ void test_all() test_one("rt_p22", rt_p22, join_miter, end_flat, 26.5711, 1.0); -#ifdef BOOST_GEOMETRY_TEST_FAIL_TANGENCIES test_one("rt_q1", rt_q1, join_miter, end_flat, 27, 1.0); -#endif test_one("rt_q2", rt_q2, join_miter, end_flat, 26.4853, 1.0); test_one("rt_q2", rt_q2, join_miter, end_flat, 0.9697, -0.25); diff --git a/test/algorithms/buffer/buffer_polygon.cpp b/test/algorithms/buffer/buffer_polygon.cpp index 34bfcdb77..31a91d024 100644 --- a/test/algorithms/buffer/buffer_polygon.cpp +++ b/test/algorithms/buffer/buffer_polygon.cpp @@ -358,9 +358,7 @@ void test_all() test_one("gammagate1", gammagate, join_miter, end_flat, 88, 1); test_one("fork_a1", fork_a, join_miter, end_flat, 88, 1); test_one("fork_b1", fork_b, join_miter, end_flat, 154, 1); -#ifdef BOOST_GEOMETRY_TEST_FAIL_TANGENCIES test_one("fork_c1", fork_c, join_miter, end_flat, 152, 1); -#endif test_one("triangle", triangle, join_miter, end_flat, 14.6569, 1.0); test_one("degenerate0", degenerate0, join_round, end_round, 0.0, 1.0); diff --git a/test/algorithms/set_operations/union/union.cpp b/test/algorithms/set_operations/union/union.cpp index 455bae775..c297514ae 100644 --- a/test/algorithms/set_operations/union/union.cpp +++ b/test/algorithms/set_operations/union/union.cpp @@ -179,10 +179,8 @@ void test_areal() test_one("58_iet", case_58[0], case_58[2], 1, 3, 20, 12.16666); -#ifdef BOOST_GEOMETRY_TEST_FAIL_TANGENCIES test_one("59_iet", case_59[0], case_59[2], 1, 1, 14, 17.20833); -#endif test_one("80", case_80[0], case_80[1], 2, 2, 18, 129.0); diff --git a/test/algorithms/set_operations/union/union_multi.cpp b/test/algorithms/set_operations/union/union_multi.cpp index 7140cf72f..ad6cdbfb9 100644 --- a/test/algorithms/set_operations/union/union_multi.cpp +++ b/test/algorithms/set_operations/union/union_multi.cpp @@ -67,11 +67,9 @@ void test_areal() 1, 3, 17, 48.333333); // Constructed cases for multi/touch/equal/etc -#ifdef BOOST_GEOMETRY_TEST_FAIL_TANGENCIES test_one("case_61_multi", case_61_multi[0], case_61_multi[1], 1, 0, 11, 4.0); -#endif test_one("case_62_multi", case_62_multi[0], case_62_multi[1], 2, 0, 10, 2.0); @@ -120,20 +118,18 @@ void test_areal() test_one("case_recursive_boxes_2", case_recursive_boxes_2[0], case_recursive_boxes_2[1], 1, 0, 14, 100.0); // Area from SQL Server -#ifdef BOOST_GEOMETRY_TEST_FAIL_TANGENCIES test_one("case_recursive_boxes_3", case_recursive_boxes_3[0], case_recursive_boxes_3[1], 17, 0, 159, 56.5); // Area from SQL Server -#endif test_one("case_recursive_boxes_4", case_recursive_boxes_4[0], case_recursive_boxes_4[1], 1, 1, 42, 96.75); -#ifdef BOOST_GEOMETRY_TEST_FAIL_TANGENCIES test_one("case_recursive_boxes_5", case_recursive_boxes_5[0], case_recursive_boxes_5[1], 3, 2, 110, 70.0); +#ifdef BOOST_GEOMETRY_TEST_FAIL_TANGENCIES // TODO: fix self touching interior ring (should get 3 interior rings) test_one("case_recursive_boxes_6", case_recursive_boxes_6[0], case_recursive_boxes_6[1],