Skip to content

Commit

Permalink
[union] fix issue 1100
Browse files Browse the repository at this point in the history
  • Loading branch information
barendgehrels committed Apr 19, 2023
1 parent 94f5c0e commit b1bebca
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 9 deletions.
14 changes: 14 additions & 0 deletions doc/release_notes.qbk
Expand Up @@ -19,6 +19,20 @@

[section:release_notes Release Notes]

[/=================]
[heading Boost 1.83]
[/=================]

[*Major improvements]

[*Improvements]

[*Solved issues]

* [@https://github.com/boostorg/geometry/issues/1100 1100] Fix for union

[*Breaking changes]

[/=================]
[heading Boost 1.82]
[/=================]
Expand Down
Expand Up @@ -557,6 +557,7 @@ struct touch : public base_turn_handler
>
static inline bool handle_imperfect_touch(UniqueSubRange1 const& range_p,
UniqueSubRange2 const& range_q,
int side_pk_q2,
UmbrellaStrategy const& umbrella_strategy,
TurnInfo& ti)
{
Expand Down Expand Up @@ -595,10 +596,11 @@ struct touch : public base_turn_handler
return d1.measure > 0 && d2.measure > 0;
};

if (has_distance(range_p, range_q))
if (side_pk_q2 == -1 && has_distance(range_p, range_q))
{
// Even though there is a touch, Q(j) is left of P1
// and P(i) is still left from Q2.
// Q continues to the right.
// It can continue.
ti.operations[0].operation = operation_blocked;
// Q turns right -> union (both independent),
Expand All @@ -608,14 +610,11 @@ struct touch : public base_turn_handler
return true;
}

if (has_distance(range_q, range_p))
if (side_pk_q2 == 1 && has_distance(range_q, range_p))
{
// Even though there is a touch, Q(j) is left of P1
// and P(i) is still left from Q2.
// It can continue.
// Similarly, but the other way round.
// Q continues to the left.
ti.operations[0].operation = operation_union;
// Q turns right -> union (both independent),
// Q turns left -> intersection
ti.operations[1].operation = operation_blocked;
ti.touch_only = true;
return true;
Expand Down Expand Up @@ -676,8 +675,8 @@ struct touch : public base_turn_handler
|| (side_qi_p1 == 0 && side_qk_p1 == 0 && side_pk_p != -1))
{
if (side_qk_p1 == 0 && side_pk_q1 == 0
&& has_qk && has_qk
&& handle_imperfect_touch(range_p, range_q, umbrella_strategy, ti))
&& has_pk && has_qk
&& handle_imperfect_touch(range_p, range_q, side_pk_q2, umbrella_strategy, ti))
{
// If q continues collinearly (opposite) with p, it should be blocked
// but (FP) not if there is just a tiny space in between
Expand Down
6 changes: 6 additions & 0 deletions test/algorithms/overlay/overlay_cases.hpp
Expand Up @@ -1101,6 +1101,12 @@ static std::string issue_1081c[2] =
"POLYGON((423.217316892426425 67.5751428875900331,414.40388971336813 96.7777620478938587,410.429206867910466 100.02249750988706,412.848579034710781 101.010025694314706,412.502954439453561 102.98508206238165,416.996074177797027 109.05132662251431,427.364812035512671 72.6538592632950468,423.217316892426425 67.5751428875900331))"
};

static std::string issue_1100[2] =
{
"POLYGON((1.5300545419548890819e-16 2101,1 2101,1 2100,1.1102230246251565404e-16 2100,1.5300545419548890819e-16 2101))",
"POLYGON((-0.19761611601674899941 2101,0 2100.6135231738085167,0 2100,-0.5 2100,-0.5 2101,-0.19761611601674899941 2101))"
};

static std::string issue_1108[2] =
{
"POLYGON((17 -2,18 -1.269679093926235014,12 0,22 0,17 -2))",
Expand Down
3 changes: 3 additions & 0 deletions test/algorithms/set_operations/union/union.cpp
Expand Up @@ -459,6 +459,9 @@ void test_areal()
TEST_UNION(issue_1081c, 1, 1, -1, 2338.08);
TEST_UNION_REV(issue_1081c, 1, 1, -1, 2338.08);

TEST_UNION(issue_1100, BG_IF_RESCALED(2, 1), 0, -1, 1.46181);
TEST_UNION_REV(issue_1100, BG_IF_RESCALED(2, 1), 0, -1, 1.46181);

TEST_UNION(issue_1108, 1, 0, -1, 12.1742);
TEST_UNION_REV(issue_1108, 1, 0, -1, 12.1742);

Expand Down

0 comments on commit b1bebca

Please sign in to comment.