Concern about PointInPolygon() robustness #146
Replies: 2 comments 4 replies
-
Sure! Thanks. 😁 |
Beta Was this translation helpful? Give feedback.
-
Hi again Alexis. And before I address your comments above, I'll outline my design objectives for Clipper2, and perhaps for later development too (Clipper3). Excellent performance is most definitely very close to the top of my objectives for Clipper2. But I'm prepared to make small compromises there when I believe it'll make the code too complicated, at least for me to maintain. And Clipper2 is already very complicated. However, I can see there's a place for Clipper2 forks where performance isn't compromised; where paths might be separated into separate X and Y arrays (and Z arrays), and where various instruction set optimisations are considered. And it's very likely that someone can do this in a way that doesn't make my existing code too complicated. And yes, the code logic in clipper.engine could greatly benefit from a lot more attention to simplification with better encapsulation (perhaps into mulitple files) and with much better documentation. And that might be Clipper3. OK, ramble over 😜.
I almost certainly won't be persuaded to change the current Point64 struct in Clipper2 . And likewise with accommodating extra 'guard' storage in a modified Path64. But these things could certainly be considered for Clipper3 😁. Nevertheless, could the performance benefits justify creating temporary arrays in the PointInPath function itself? |
Beta Was this translation helpful? Give feedback.
-
I was writing a quick SSE4.2 version of PointInPolygon() and that CrossProduct followed with
if(d == 0) return PointInPolygonResult::IsOn
worries me.We could craft a scenario where a contour is definitely inside another, yet the very first vertex (the only one tested) is so darn close to an edge of its parent contour that the floating point math returns an "outside" result. There could be a fourth option in that
PointInPolygonResult
enum ("indeterminate, please pick another vertex"), or maybeIsOn
should be triggered by a range based on the expected numerical accuracy of that double precision math (rather than == 0.0)...I'll do the math for that indeterminate numerical range.
(Current draft of C SSE 4.2 PointInPolygon() seems twice as fast, I'll share if you want, although AVX should do better)
EDIT: Okay, don't mind me, it's all good. 😆 Numerical precision is fine because errors can't accumulate enough to flip the result... (Although I would rather compare both sides within the cross product, instead of subtracting them and then comparing against zero. The apparent sequence of two roundings triggers alarms for those watching out for floating point accuracy)
Beta Was this translation helpful? Give feedback.
All reactions