-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Edge-case bugs in boolean operations #2082
Comments
I've made some progress narrowing this down further. The problem appears to arise when the two curves contain are two nearly identical points, but which are not exactly identical (most commonly this would be due to floating point precision in an earlier calculation). This can lead to super-short segments/curves being added to a path during Part of this calculation depends on Lines 701 to 730 in f1f02cc
My solution is to do the initial check with the
@lehni Thoughts on this change? It appears to be working well so far for my application, though I'll continue to test. @iconexperience I see you've done a lot of great work on related issues - any chance you could take a look? |
I think issue 2 may be related to #1261, and the solution is similar to that proposed by @iconexperience in #1261 (comment). @lehni responded that looking initially at points within |
@lehni First of all thank you for this great library! It is an integral part of a project I've been working on for quite a while now, osd-paperjs-annotation, which integrates paper.js with OpenSeadragon - there's a demo page here. The project is still an active work-in-progress but it is already proving very useful in a number of other application I'm building.
I've come across a couple of issue with boolean operations (e.g. subtract, intersect). One of them I've tracked down and come up with a fix for, and the other I'm still working on sorting out. Both tend to affect complicated paths like those created by the magic wand tool (which you can see in the demo page for reference).
First issue: float truncation - workaround identified
The first one crops up when large coordinate values are used (in the 10,000-20,000+ range, typically). When the values are this big, the
epsilon
that gets added to the coordinate can get truncated due to floating point precision, which disrupts the winding calculations. My workaround for this is to test whether the bounds of the paths are large enough to cause this issue, and if so, translate and scale the paths as needed to reduce the size of the coordinates, then do the boolean operation, and then undo the transformation. I've implemented this as a monkey patch, rather than a direct modification of the library code itself at this point. I'm posting the code here in case it is useful to others. If you approve of the approach, I can try putting a PR together to address this more formally within this library itself.Second issue: Many overlapping segments - unresolved
The second issue, which I'm still working on tracking down, comes up when two paths have a lot of overlapping segments - like when
PathItem.subtract
is used to subtract one path from another, the borders align perfectly. The problem is when the result of the subtract operation and the original path are then tested against each other.For example, with paths
A
andB
, letR = A.subtract(B)
.R
andB
are now non-overlapping, with a shared stretch of border.R.subtract(B)
should just returnR
again (no overlap = nothing to subtract), but sometimes the result is entirely empty. It depends a lot on the exact coordinates of the polygon coordinates. See this sketch for an example.Note that in the screenshot, the log message for the bottom three tests are truncating the offset: it is actually
new Point(0.0000001, 0)
(not0,0
).I'm looking for any pointers on where the issue might be arising, and how to best test for these cases. If I can identify the cause I'll also try to put in a PR for this.
Thanks again for the great library!
The text was updated successfully, but these errors were encountered: