close
Skip to content

[union] fix missing interior ring and double traversed exterior ring - #1113

Merged
vissarion merged 1 commit into
boostorg:developfrom
barendgehrels:issue-1108-fix-interior-ring-for-union
Mar 7, 2023
Merged

[union] fix missing interior ring and double traversed exterior ring#1113
vissarion merged 1 commit into
boostorg:developfrom
barendgehrels:issue-1108-fix-interior-ring-for-union

Conversation

@barendgehrels

Copy link
Copy Markdown
Collaborator

fixes: #1109 and #1108
keeps fixed: #1081

@vissarion vissarion left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I am OK with merging!

#else
using point_t = decltype(turns[*indices.begin()].point);
using coor_t = typename coordinate_type<point_t>::type;
coor_t centroid_0{};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not remember using this initialization in boost geometry. I am not against though, just to check.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to assign 0 explicitly because for user-defined numerical type this could result in default ctor call which could initialize variable to something different than 0.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will update it. Thanks.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️

// The coordinates are averaged.
// It is necessary to avoid artefacts and invalidities.
template <typename Turns, typename Clusters>
inline void colocate_clusters(Turns& turns, Clusters const& clusters)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the order be the other way around? Such that the output is after then input?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right will fix it.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️

test_one<multi_polygon_type, polygon_type>("rt_p11", rt_p11, join_miter, end_flat, 28.7426, 1.0);
test_one<multi_polygon_type, polygon_type>("rt_p12", rt_p12, join_miter, end_flat, 22.5711, 1.0);

// Needs centroid of cluster turn points

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is related to flag BOOST_GEOMETRY_USE_FIRST_POINT_AT_CLUSTER

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This define is now gone.
✔️

// which is now return T(1) (earlier it was 1000)
double const multiplier = 1.0 / 1000.0;
// which is now return T(100) (earlier it was 1000)
double const multiplier = 1.0 / 10.0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it hold multiplier = T / 1000.0; ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand. Maybe the comment needs to point to the source in get_clusters.hpp

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My question is: "should multiplier be a function of T e.g. multiplier = T / 1000.0; instead of manually update the fraction every time you change the threshold?" Am I missing something in the context here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed these lines a bit, avoiding the multiplier and enhancing the comment
✔️

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My question is: "should multiplier be a function of T e.g. multiplier = T / 1000.0; instead of manually update the fraction every time you change the threshold?" Am I missing something in the context here?

Sorry, I noticed this answer only after my own reply.
But I changed it, without multiplier now. I hope the threshold won't change again. Is it fine like this?

Comment on lines +112 to +118
for (const auto& index : indices)
{
centroid_0 += geometry::get<0>(turns[index].point);
centroid_1 += geometry::get<1>(turns[index].point);
}
centroid_0 /= indices.size();
centroid_1 /= indices.size();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIU this is only correct for cartesian. Can this be a problem?

Another issue is that for integral coordinates this could result in overflow.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good points.
Happening on the dateline would be a rare case... but, see below.
Integral coordinates: if they are clustered, they are (by definition) on the same location. So they don't need this, the first point is fine.
I'll update the implementation to cover these two situations (which means: for geographic or integer coordinates take the first).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So indeed it was a problem, reported as #1116 which was found on this branch.
Good catch!
My updated implementation solved that already, but I will create a testcase.
That will be done in a separate PR. If you approve, this can be merged now.

@barendgehrels
barendgehrels force-pushed the issue-1108-fix-interior-ring-for-union branch from 7f75e4f to 51fa43c Compare February 22, 2023 12:30
for (++it; it != indices.end(); ++it)
{
turns[*it].point = first_point;
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because all implementation is here, I removed the define, better like this.
Thanks for the comments.

}

remove_clusters(turns, clusters);
colocate_clusters(clusters, turns);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now looks a bit weird (by the order change).
I will change it in a later PR but I didn't want to do it in this one, to keep the size smaller.

@barendgehrels
barendgehrels force-pushed the issue-1108-fix-interior-ring-for-union branch from 51fa43c to ec7f9c9 Compare February 22, 2023 12:34
@vissarion

Copy link
Copy Markdown
Member

@barendgehrels do you want to have this PR in 1.82 beta? Deadline 8/3

Side note: there is an error in buffer tests https://app.circleci.com/pipelines/github/boostorg/geometry/374/workflows/e4f969a0-4b45-4af2-8316-328437fde513/jobs/19175 probably not related to this PR.

@vissarion
vissarion merged commit dfcbb75 into boostorg:develop Mar 7, 2023
@vissarion vissarion added this to the 1.82 milestone Apr 3, 2023
@barendgehrels
barendgehrels deleted the issue-1108-fix-interior-ring-for-union branch December 14, 2024 11:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Union result goes around twice. bg::union_(polygon,ring) returns wrong result. Inner loop disappears.

3 participants