-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix zerolen intersect #16250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix zerolen intersect #16250
Conversation
while (c2.vertex(&x22, &y22) != agg::path_cmd_stop) { | ||
// if the segment in path 2 is 0 length, skip to next vertex | ||
if ((x21 == x22) && (y21 == y22)) { | ||
continue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you're really going to do the check to zero-len both here and in segments_intersect (which seems weird as well, I'd rather not(?)) at least the check should be the same in both places (len < epsilon)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My logic was this:
- computing
==
is cheaper - if trip the
==
condition, we will trigger the determinant condition, but the converse is not true. - do the cheaper, stricter thing here
- do the more expensive looser thing where we have to (see my discussion with @timhoffm above)
- keep all of the "isclose" logic together in the code so we are sure that the numbers don't get out of sync
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well you could change the signature of isclose() to just isclose(a, b) and force atol and rtol as constants in the body of the function... I'm not going to block over that though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if CI passes
One method to fix matplotlib#15842 In this case we check in `path_intersect_path` that as we iterate through the segments, if we hit a 0 length segment we grab the next vertex before checking if the segments from the two paths intersect.
One method to fix matplotlib#15842 In this case we check that if either segment is 0 length, it intersects with no other segments, not all other segments.
To make clear we won't be changing them.
Use length square being close to 0 rather than strict. I have a worry that because we are using "close" for identifying the determinant is 0, if we use strict equality for the length, then we may pass through the length check, but erroneously go through the den == 0 path.
Makes it a bit easier to identify failing cases.
- move the "close to 0" computation from segments_intersect to path_intersects_path so we only do it once. - change the signature of the c function isclose to back the atol and rtol into the function (to make sure the two places we use it stay in sync)
fef57d4
to
ffaf302
Compare
Owee, I'm MrMeeseeks, Look at me. There seem to be a conflict, please backport manually. Here are approximate instructions:
And apply the correct labels and milestones. Congratulation you did some good work ! Hopefully your backport PR will be tested by the continuous integration and merged soon! If these instruction are inaccurate, feel free to suggest an improvement. |
…250-on-v3.2.x Backport PR #16250 on branch v3.2.x (Fix zerolen intersect)
Merge pull request matplotlib#16250 from tacaswell/fix_zerolen_intersect Fix zerolen intersect Also re-factors some tests. Conflicts: lib/matplotlib/tests/test_path.py - unrelated change to test above new test. Kept old version of test and added new test
…-v3.1.x Backport PR #16250: Fix zerolen intersect
PR Summary
This provides two fixes for #15842 which independently fix the reported bug.
The first merges segments when iterating through the paths, the second ensures that a 0 length segment intersects with no other segment (rather than all (or maybe just some?) segments.
The 0 length segment not intersecting any segments, including ones it is a point on, matches the behavior of shapely.
attn @TarasKuzyo
PR Checklist