mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 21:44:04 +00:00
[intersection] fix cases where intersection has to travel through uu/ux
This commit is contained in:
parent
d256e57487
commit
8364aed91b
@ -258,10 +258,10 @@ struct traversal
|
||||
std::set<signed_size_type> const& ids = mit->second;
|
||||
|
||||
sbs_type sbs;
|
||||
bool has_subject = false;
|
||||
|
||||
// Check if it is a combination with uu
|
||||
bool uu_combi = false;
|
||||
bool has_subject = false;
|
||||
bool has_uu = false;
|
||||
bool has_operation = false;
|
||||
|
||||
for (typename std::set<signed_size_type>::const_iterator sit = ids.begin();
|
||||
sit != ids.end(); ++sit)
|
||||
@ -273,11 +273,17 @@ struct traversal
|
||||
// Defensive check, discarded turns should not be in cluster
|
||||
continue;
|
||||
}
|
||||
if (OperationType == operation_union
|
||||
&& cturn.both(operation_union))
|
||||
|
||||
if (cturn.both(operation_union))
|
||||
{
|
||||
uu_combi = true;
|
||||
has_uu = true;
|
||||
}
|
||||
|
||||
if (cturn.has(OperationType))
|
||||
{
|
||||
has_operation = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
turn_operation_type const& cop = cturn.operations[i];
|
||||
@ -300,12 +306,13 @@ struct traversal
|
||||
}
|
||||
sbs.apply(turn.point);
|
||||
|
||||
if (uu_combi)
|
||||
if (has_uu && OperationType == operation_union)
|
||||
{
|
||||
sbs.reverse();
|
||||
}
|
||||
|
||||
if (uu_combi)
|
||||
|
||||
if (has_uu && OperationType == operation_union)
|
||||
{
|
||||
std::size_t index = sbs.first_open_index();
|
||||
if (index < sbs.m_ranked_points.size())
|
||||
@ -319,6 +326,11 @@ struct traversal
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! has_operation && OperationType == operation_intersection)
|
||||
{
|
||||
sbs.find_open();
|
||||
}
|
||||
|
||||
// Normal intersection or non-reversed union
|
||||
// (TODO: move this to sbs too)
|
||||
const std::size_t target_main_rank = 1;
|
||||
@ -340,10 +352,29 @@ struct traversal
|
||||
return false;
|
||||
}
|
||||
|
||||
bool allow = ranked_point.operation == OperationType
|
||||
|| ranked_point.operation == operation_continue;
|
||||
|
||||
if (! allow
|
||||
&& !result
|
||||
&& OperationType == operation_intersection
|
||||
&& ranked_point.right_count == 2
|
||||
&& ! has_operation)
|
||||
{
|
||||
// In some cases it is necessary for intersection to continue
|
||||
// through a cluster with only uu and cc turns (because uu turns
|
||||
// are not blocked anymore). For example an intersection of
|
||||
// equal multi-polygons, both having a uu turn
|
||||
turn_type const& ranked_turn = m_turns[ranked_point.turn_index];
|
||||
if (ranked_turn.both(operation_union))
|
||||
{
|
||||
allow = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ranked_point.main_rank == target_main_rank
|
||||
&& ranked_point.index == sort_by_side::index_to
|
||||
&& (ranked_point.operation == OperationType
|
||||
|| ranked_point.operation == operation_continue))
|
||||
&& allow)
|
||||
{
|
||||
turn_type const& ranked_turn = m_turns[ranked_point.turn_index];
|
||||
|
||||
|
@ -613,6 +613,20 @@ static std::string case_recursive_boxes_30[2] =
|
||||
"MULTIPOLYGON(((2 1,2 3,1 3,1 4,2 5,2 4,3 4,3 5,5 5,5 4,4 4,3.5 3.5,4 3,4 4,5 3,4.5 2.5,5 2,5 0,4 0,4 2,3 2,3 3,2.5 2.5,4 1,3 1,3 0,1 0,2 1)))"
|
||||
};
|
||||
|
||||
static std::string case_recursive_boxes_31[2] =
|
||||
{
|
||||
// Requires allowing traverse through clusters having only uu/cc for intersection
|
||||
"MULTIPOLYGON(((1 4,1 1,0 1,0 4,1 4)),((1 1,2 1,2 0,1 0,1 1)),((2 2,1 2,2 3,2 2)))",
|
||||
"MULTIPOLYGON(((2 3,2 2,1 2,2 3)),((0 1,0 3,1 3,1 1,0 1)),((1 1,1 0,0 0,1 1)))"
|
||||
};
|
||||
|
||||
static std::string case_recursive_boxes_32[2] =
|
||||
{
|
||||
// Similar to #31 but here uu/ux/cc
|
||||
"MULTIPOLYGON(((1 3,2 3,2 2,1 1,1 3)),((2 2,3 1,3 0,2 0,2 2)),((1 1,2 1,1 0,0 0,0 1,1 1)))",
|
||||
"MULTIPOLYGON(((3 1,3 0,2 0,2 2,3 1)),((1 1,0 1,0 2,1 2,2 1,1 1)))"
|
||||
};
|
||||
|
||||
static std::string pie_21_7_21_0_3[2] =
|
||||
{
|
||||
"MULTIPOLYGON(((2500 2500,2500 3875,2855 3828,3187 3690,3472 3472,3690 3187,3828 2855,3875 2500,3828 2144,3690 1812,3472 1527,3187 1309,2855 1171,2499 1125,2144 1171,1812 1309,1527 1527,1309 1812,1171 2144,1125 2499,1171 2855,1309 3187,2500 2500)))",
|
||||
|
@ -216,6 +216,12 @@ void test_areal()
|
||||
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_30",
|
||||
case_recursive_boxes_30[0], case_recursive_boxes_30[1],
|
||||
4, 0, 6.0);
|
||||
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_31",
|
||||
case_recursive_boxes_31[0], case_recursive_boxes_31[1],
|
||||
2, 0, 2.5);
|
||||
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_32",
|
||||
case_recursive_boxes_32[0], case_recursive_boxes_32[1],
|
||||
2, 0, 1.75);
|
||||
|
||||
test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120915_h2_a",
|
||||
ggl_list_20120915_h2[0], ggl_list_20120915_h2[1],
|
||||
|
@ -207,6 +207,12 @@ void test_areal()
|
||||
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_30",
|
||||
case_recursive_boxes_30[0], case_recursive_boxes_30[1],
|
||||
1, 1, -1, 17.5);
|
||||
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_31",
|
||||
case_recursive_boxes_31[0], case_recursive_boxes_31[1],
|
||||
3, 0, -1, 5.0);
|
||||
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_32",
|
||||
case_recursive_boxes_32[0], case_recursive_boxes_32[1],
|
||||
2, 0, -1, 5.75);
|
||||
|
||||
test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120915_h2_a",
|
||||
ggl_list_20120915_h2[0], ggl_list_20120915_h2[1],
|
||||
|
Loading…
x
Reference in New Issue
Block a user