Add an assertion to ClipperOffset::Group::Group
checking that the lowest path has non-zero area
#965
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I am using
InflatePaths
, and I had the following problem that took a long time to figure out:Background
The
Group
constructor currently needs to figure out if exteriors are clockwise and holes are counter-clockwise, or the other way around. It accomplishes this by finding the lowest path (=the one having the highest y coordinate), because that must be an outer path, and by checking if its area is positive or negative.Problem
Now if the lowest path contains only 1 or 2 points, or otherwise has zero area, and the paths are indeed "reversed", then the above logic does not work as intended.
It wouldn't be a problem to simply drop such degenerate paths, but the issue is that if the same group contains also non-degenerate, large, significant paths, they may effectively be dropped as well. This is exactly what was sometimes happening in my use case. (Just for the record, my workaround was to weed such degenerate paths from the input, before calling
InflatePaths
. Very easy once I knew what exactly the problem was, but to get to that point took quite a while...)(Where would such degenerate paths come from? I think for example from calling OpenCV's
findContours
for 1- or 2-pixel regions.)What this PR does
This PR just adds an
assert
that should detect if the input data is such that the logic can't really work as intended. Having this available would have saved me a lot of time, so I thought it might help others who may be providing similar input data. Generallyassert
s are no-op in Release builds, so Release builds should remain unaffected. Alternatively, one could throw astd::logic_error
or similar, but I guess that doing so would be more intrusive and might break applications that are currently working (although they would be "working" only if the paths are not reversed).Alternative solutions
For clarity, I think it might be best to let the user explicitly provide the orientation also in the offset case (similar to the "main" clipping functionality, such as intersection), instead of trying to figure it out from the input data. (Should be a tad faster, too?)
Another alternative would be to find the lowest path that has non-zero area (instead of just the lowest path).
Angus, if you like either of the above suggestions, I can try and prepare an alternative PR.
Unrelated remark
(There is also a cosmetic spaces vs tabs issue here in this location, but I tried to keep the diff minimal and not start fixing that, at least for the time being.)