Old tarballs not available anymore
Yeah - having a more informative solution output than just the point lists would be a very useful feature! There are so many use-cases where it is necessary to know which shapes were involved in a clipping result. For example - calculating the length of an intersection line, highlighting or coloring them, skipping a triangulation process because the shape in question wasn’t even cut – just to name a few! In the ClipperLib2 the PolyTree with PolyNodes has been replaced by PolyPath – could that be...
Hello, let's suppose I merge a list of profiles at once (it does not matter the number). I use the union operation, so the distinction between subject and object is not important, I insert all my profiles in the subject. Everything works great, but my question is: is it possible to locate in the output the profiles that have remained isolated after the merging (i.e. have not merged with any profile in the input list)? Thank you for your time and have a good day you all!
does version 2 release handle overlapped output polygons in the result?.
Thanks a lot , Angus ! Also very interested in this feature. Please update if it was implemented.
Nevermind, I've just about finished translating it myself.
Oh splendid - - I'd really like to look into that code, too. I'm also coding with c# (in Unity) ... so maybe Phil - if you have ported the sources already, I would be very grateful if you could share them with me ... I'm trying to implement a triangulation by myself for some time now... unfortunately without significant success I thought that I could just extend the existing method IntersectEdges(TEdge e1, TEdge e2, IntPoint pt) add a trapezoid consisting of these edges and the scanbeam.y to a list...
Clipper2 is just about finished now (at least in Delphi and C# languages), and all that's needed (except for any late bugfixes) is a documentation update. However I'm keen to host a C++ translation just as I have for Clipper1 here. But this time I'm hoping to find someone very proficient in C++ that would be willing to do at least the basic translation of Clipper2. If you're interested and might be able to help, please contact me over on GitHub. Thanks, Angus
Sorry, I have still sourceforge in my mind. Maybe you should empty it and make a link on github.
Thank you Phil. I just thought I am casting in a wrong way
Hi again Ralf. Thanks for reporting this. I'll fix it in the next upload. (That might be a few more days as I'm currently occupied with merging touching polygons in clipping solutions. I've had many attempts at this - to do it relatively simply and without a significant performance load - but this time I think/hope I've finally got it nailed.) Clipper2Lib issues should probably go to Github. Yes, I'd prefer all Clipper2 feedback here please.
Clipper2Lib issues should probably go to Github.
The scale is essentially what controls the error that you see. The larger the scale you use, the less error should be observed. I tend to scale by 1E4 or more, and because I wanted accuracy more than anything else, I tend to use doubles rather than floats. You will see the range of error if you review the returned values from Clipper; you're simply shifting the decimal point when scaling down.
Refers to Clipper 2.
Some Delphi 7 issues
scale declared as float
Hi guys, I went all over the documenation and lots of examples. I am basicaly trying to convert each coordinate from float to Clipper Long and after Execute I need to conver all back to floats. So what I found is when I convert back it does not give me very acurate numbers. I need to go up to 1000 with my scale Here is how I do it, is it wrong? // Convert input Vecto3 List to intPoints. Including float precision // http://www.angusj.com/delphi/clipper/documentation/Docs/Overview/FAQ.htm private void...
On 15.03.22 г. 2:32 ч., Angus Johnson wrote: Great, thanks for the update. Also, I might be putting the merging of touching solution polygons on the priority list (to tackle before final release of Clipper2). That may delay things a bit but hopefully not too much. Please make merging optional. It's important for motion planing. best regards, Niki
Great, thanks for the update. Also, I might be putting the merging of touching solution polygons on the priority list (to tackle before final release of Clipper2). That may delay things a bit but hopefully not too much.
Update: All good. Indeed Clipper2Lib works now for the "union of tiles" case described above. The glitches I saw where related to a minor bug in the tessellation library I use (fixed now). Combination of those glitches and the fact that Clipper2Lib does (not yet) merge touching polygons in the solution threw me off. Congrats: that is a major improvement to Clipper1! Bold red outline in the attached picture indicates the union solution polygon.
Update: All good. Indeed Clipper2Lib works now for the "union of tiles" case described above. The glitches I saw where related to a minor bug in the tessellation library I use (fixed now). Combination of those glitches and the fact that Clipper2Lib does (not yet) merge touching polygons in the solution threw me off. Congrats: that is a major improvement to Clipper1!
Not sure I fully understand: the double version (PathD) does not need any typecasting as everything is double already. Yeah, sorry, I was referring (implicitly) to Area(Path64 path) since you'd also mentioned overflow, and I didn't think you'd be concerned about overflow when multiplying floating point values And very the reason the integer version of Area returns a double is to avoid overflow. The alternative (used in Clipper1) is to use custom 128bit integers, but they create an unnecessary performance...
Not sure I fully understand: the double version (PathD) does not need any typecasting as everything is double already. Yeah, sorry, I was referring (implicitly) to Area(Path64 path) since you'd also mentioned overflow, and I didn't think you'd be concerned about multiplying floating point values And very the reason the integer version of Area returns a double is to avoid overflow. The alternative (used in Clipper1) is to use custom 128bit integers, but they create an unnecessary performance burd...
Not sure I fully understand: the double version (PathD) does not need any typecasting as everything is double already. Yeah, sorry, I was referring (implicitly) to Area(Path64 path) since you'd also mentioned overflow, and I didn't think you'd be concerned about that with floating point coordinates. And very the reason the integer version of Area returns a double is to avoid overflow. The alternative (used in Clipper1) is to use custom 128bit integers, but they create an unnecessary performance ...
Not sure I fully understand: the double version (PathD) does not need any typecasting as everything is double already. Yeah, sorry, I was referring (implicitly) to Area(Path64 path). And very the reason this function returns a double is to avoid the risk of overflow. The alternative (used in Clipper1) is to use custom 128bit integers, but they create an unnecessary performance burden.
EDITED (red outline was not result union but rather later process step clipping against earth features) Hmm...you might be right that it is technically correct. GREAT work! Clipping against the earth polygon features is a bit glitchy (see bottom left corner in Clipper2Lib picture)...need to investigate this further. See attachment. This is really difficult to reproduce and provide you samples with as the individual tiles are randomly "unified". A difficult situation is e.g. when 8 tiles have been...
Hmm...you might be right that it is technically "sort of" correct (there are some weird "spike-lines" instead of rectangles). See attachment. This is really difficult to reproduce and provide you samples with as the individual tiles are randomly "unified". A difficult situation is e.g. when 8 tiles have been merged in 3x3 tiles, and the last tile fills a hole in the middle vs top right corner tile missing. If you see in the attached picture something unexpected, maybe you are able to synthesize a...
Hmm...you might be right that it is technically "sort of" correct (there are some weird "spike-lines" instead of rectangles). See attachment. This is really difficult to reproduce and provide you samples with as the individual tiles are randomly "unified". A difficult situation is e.g. when 8 tiles have been merged in 3x3 tiles, and the last tile fills a hole in the middle vs top right corner tile missing. If you see in the attached picture something unexpected, maybe you are able to synthesize a...
Hmm...you might be right that it is technically "sort of" correct (there are some weird "spike-lines" instead of rectangles). See attachment. This is really difficult to reproduce and provide you samples with as the individual tiles are randomly "unified". A difficult situation is e.g. when 8 tiles have been merged in 3x3 tiles, and the last tile fills a hole in the middle vs top right corner tile missing. If you see in the attached picture something unexpected, maybe you are able to synthesize a...
Just tried if ClipperLib2 can do it...no luck. Is this something you would expect Clipper2Lib to ultimately be able to do, Bummer! And YES!!! Though I'm not sure what you mean by glitches. If you're meaning that the solution is technically correct (as I expect) but there are polygons in the solution that touch each other and could be simplified, then this is something that's on the "road map" for future but not promised. If you are getting results from Clipper2 that aren't technically correct, I'd...
However, I'm not sure if the line if (cnt < 3) return 0.0; is needed. It looks safe to remove (though I'm yet to test this). Indeed, in my framework the area function looks like this: public static double AreaNew(PathD path) { double a = default; for (int i = 0, cnt = path.Count; i < cnt; j = i++) a += (path[j].y + path[i].y) * (path[j].x - path[i].x) * 0.5; return a; } While the double version does not need any type casting, the integer version does need it and looks like this: public static double...
However, I'm not sure if the line if (cnt < 3) return 0.0; is needed. It looks safe to remove (though I'm yet to test this). Indeed, in my framework the area function looks like this: public static double AreaNew(PathD path) { double a = default; for (int i = 0, cnt = path.Count; i < cnt; j = i++) a += (path[j].y + path[i].y) * (path[j].x - path[i].x) * 0.5; return a; } While the double version does not need any type casting, the integer version does need it and looks like this: public static double...
However, I'm not sure if the line if (cnt < 3) return 0.0; is needed. It looks safe to remove (though I'm yet to test this). Indeed, in my framework the area function looks like this: public static double AreaNew(PathD path) { double a = default; for (int i = 0, cnt = path.Count; i < cnt; j = i++) a += (path[j].y + path[i].y) * (path[j].x - path[i].x) * 0.5; return a; } For for the integer version it would look like this: public static double AreaNew(Path64 path) { double a = default; for (int i...
Hi Angus, I got a use case where I need to create the union of individual quadratic tiles perfectly overlapping in their vertices. In my quest for a clipping algorithm that can do that perfectly without any glitches and edge cases, only Polybool worked so far. Hormann & Martinez & Clipper1 all work "sort off", but got plenty of edge cases rendering them unusable. Just tried if ClipperLib2 can do it...no luck. Is this something you would expect Clipper2Lib to ultimately be able to do, or is this a...
Hi Angus, I got a use case where I need to create the union of individual quadratic tiles perfectly overlapping in their vertices. In my quest for a clipping algorithm that can do that perfectly without any glitches and edge cases, only Polybool worked so far. Hormann & Martinez & Clippe1 all work "sort off", but got plenty of edge cases rendering them unusable. Just tried if ClipperLib2 can do it...no luck. Is this something you would expect Clipper2Lib to ultimately be able to do, or is this a...
However, I'm not sure if the line if (cnt < 3) return 0.0; is needed. It looks safe to remove (though I'm yet to test this). Indeed, in my framework the area function looks like this: public static double AreaNew(PathD path) { double a = default; for (int i = 0; i < cnt; j = i++) a += (path[j].y + path[i].y) * (path[j].x - path[i].x) * 0.5; return a; } For for the integer version it would look like this: public static double AreaNew(Path64 path) { double a = default; for (int i = 0; i < cnt; j =...
Hi Angus, I got a use case where I need create the union of individual quadratic tiles perfectly overlapping in their vertices. In my quest for a clipping algorithm that can do that perfectly without any glitches and edge cases, only Polybool worked so far. Hormann & Martinez & Clippe1 all work "sort off", but got plenty of edge cases rendering them unusable. Just tried if ClipperLib2 can do it...no luck. Is this something you would expect Clipper2Lib to ultimately be able to do, or is this a limitation...
Hi Angus, I got a use case where I need create the union of individual quadratic tiles perfectly overlapping in their vertices. In my quest for an clipping algorithm that can do that perfectly without any glitches and edge cases, onlyPolybool worked so far. Hormann & Martinez both work "sort off", but got edge cases. Just tried without if ClipperLib2 can do it...no luck. Is this something you would expect Clipper2Lib to ultimately be able to do, or is this a limitation that cannot be easily overcome?...
Hi again Terence. The area formula used in clipper continues to confuse me LOL, it confuses me too! 😕 All my development has been done using inverted Y-axis displays (0,0 at top left). This of course reverses winding orientation (clockwise vs counterclockwise ) and I recently I tried to fix this with a pre-compiler switch (that reverses orientation). Howver, in doing this I broke things and, rather than persisting, I reversed the changes. Thanks to your feedback here I'll make a more concerted effort...
Hi again Terence. The area formula used in clipper continues to confuse me LOL, it confuses me too! 😕 All my development has been done using inverted Y-axis displays (0,0 at top left). This of course reverses winding orientation (clockwise vs counterclockwise ) and I recently I tried to fix this with a pre-compiler switch (that reverses orientation). Howver, in doing this I broke things and, rather than persisting, I reversed the changes. Thanks to your feedback here I'll make a more concerted effort...
Dear Angus, The area formula used in clipper continues to confuse me as it is different than all my other polygon manipulation libraries. In cartesian coordinates (0,0 is bottom left) positive areas indicate CCW, and negative CW orientation. The area formula in clipper does that, but only by reversing the final result because it is using ((1/2 (Xi + Xi+1)(Yi-Yi+1), which is neither the Trapezoid formula (1/2 (Yi + Yi+1)(Xi-Xi+1) nor the Triangle/Shoelace Formula (1/2 (Xi * Yi+1) - (Xi+1 * Yi). To...
Dear Angus, The area formula used in clipper continues to confuse me as it is different than all my other polygon manipulation libraries. In Cartesian coordinates (0,0 is bottom left) positive areas indicate CCW, and negative CW orientation. The area formula in clipper does that, but only by reversing the final result because it is using ((1/2 (Xi + Xi+1)(Yi-Yi+1), which is neither the Trapezoid formula (1/2 (Yi + Yi+1)(Xi-Xi+1) nor the Triangle/Shoelace Formula (1/2 (Xi Yi+1) - (Xi+1 Yi). To that...
Dear Angus, The area formula used in clipper continues to confuse me as it is different than all my other polygon manipulation libraries. In Cartesian coordinates (0,0 is bottom left) positive areas indicate CCW, and negative CW orientation. The area formula in clipper does that, but only by reversing the final result because it is using ((1/2 (Xi + Xi+1)(Yi-Yi+1), which is neither the Trapezoid formula (1/2 (Yi + Yi+1)(Xi-Xi+1) nor the Triangle/Shoelace Formula (1/2 (Xi Yi+1) - (Xi+1 Yi). To that...
Hi Terence. Thank you for your feedback on this. It does need more attention, at least on my part. I do pretty much all my coding in Delphi, and this was an area in the C# code where I took what seemed a reasonable shortcut/compromise. However, I agree with you now that the IsNearZero function isn't ideal/satisfactory. However, in practise, this isn't a problem for the Clipper Library internally. In my Delphi code, the comparable PointD class doesn't have equality or inequality operators because...
As we talk about perfection, how about this to ensure equality test works for small AND large numbers? "The absolute tolerance test fails when x and y become large, and the relative tolerance test fails when they become small. " https://realtimecollisiondetection.net/blog/?p=89 const double absTol = *desired tolerance*; const double relTol = *desired tolerance*; public static bool operator ==(PointD a, PointD b) { return (Math.Abs(a.x - b.x) <= Math.Max(absTol, relTol * Math.Max(math.abs(a.x), Math.Abs(b.x))))...
As we talk about perfection, how about this to ensure equality test works for small AND large numbers? "The absolute tolerance test fails when x and y become large, and the relative tolerance test fails when they become small. " https://realtimecollisiondetection.net/blog/?p=89 const double absTol = *desired tolerance*; const double relTol = *desired tolerance*; public static bool operator ==(PointD a, PointD b) { return (Math.Abs(a.x - b.x) <= Math.Max(absTol, relTol * Math.Max(math.abs(a.x), Math.Abs(b.x))))...
As we talk about perfection, how about this to ensure equality test works for small AND large numbers? "The absolute tolerance test fails when x and y become large, and the relative tolerance test fails when they become small. " https://realtimecollisiondetection.net/blog/?p=89 const double absTol = *desired tolerance*; const double relTol = *desired tolerance*; public static bool operator ==(PointD a, PointD b) { return (Math.Abs(a.x - b.x) <= Math.Max(absTol, relTol * Math.Max(math.abs(a.x), Math.Abs(b.x))))...
As we talk about perfection, how about this to ensure equality test works for small AND large numbers? : https://realtimecollisiondetection.net/blog/?p=89 const double absTol = *desired tolerance*; const double relTol = *desired tolerance*; public static bool operator ==(PointD a, PointD b) { return (Math.Abs(a.x - b.x) <= Math.Max(absTol, relTol * Math.Max(math.abs(a.x), Math.Abs(b.x)))) && (Math.Abs(a.y - b.y) <= Math.Max(absTol, relTol * Math.Max(math.abs(a.y), Math.Abs(b.y)))); }
The algorithms depend on intersections and render /fill by a advancing scan line. FOR Clipper even within a scan beam the rendering proceeds with a scan line provided by the y coordinates of edge - edge intersection points, Where is this assertion tested and how is it reported back to the callee? I am curious only for odd-even fills of closed input polygons.
Wrong output when using ctDifference
I didn't know that it only works with integers. I rewrite the codes and it works! Thank you!
For us at the PrusaSlicer team, the Z coordinate is often used to differentiate the source of segments / vertices. However I believe it did not work quite reliably, I only guess that the Z was not processed correctly by the code removing zero area loops. On Fri, Feb 25, 2022 at 11:21 PM Angus Johnson angusj@users.sourceforge.net wrote: As you've noticed, yes this feature isn't currently supported. However, depending on the level of interest, I could be persuaded to reimplement the Z coordinate. (And...
To be clearer, ClipperLib works with integers. You'll need to scale up your geometry so that the minimum resolution sits on an integer interval (e.g. if you need to represent 0.001, you'll need to scale all of your geometry by at least 1000). You can then use this scaled geometry with ClipperLib and scale the result back down again afterwards. The main reason for this is to avoid errors from floating point precision.
I think you'll find that if you sensibly scale your polygons, you'll get the result you're expecting.
Clipper2 beta moved to GitHub
Wrong output when using ctDifference
I'll email you the Delphi code.
The triangulation code mostly works, and works well. But it crashes when under significant load, so it's not yet fit for inclusion in the library.
I'm not committed to the idea, but I thought it would be a helpful differentiation of the two classes.
Certainly looks cleaner to me. One other point I wanted to ask about - you have lowercase x/y in PointD and uppercase in Point64. Was that intentional?
How about ... private static bool IsNearZero(double value) { return (Math.Abs(value) <= Double.Epsilon); } public static bool operator ==(PointD lhs, PointD rhs) { return IsNearZero(lhs.x - rhs.x) && IsNearZero(lhs.y - rhs.y); } public static bool operator !=(PointD lhs, PointD rhs) { return !IsNearZero(lhs.x - rhs.x) || !IsNearZero(lhs.y - rhs.y); } I think it's a lot cleaner, but will the compiler inline the IsNearZero function call?
Would you be persuaded to make the keyholing available, or is that dependent on the triangulation?
I wasn't sure if that would work as that might be misunderstood as comparing objects.
👍
Do I Understand that for the XOR operation all edges are HOT Not necessarily. Yes, all edges will be HOT when using EvenOdd filling. But they won't be HOT when using NonZero filling and Abs(edge.WindCount) > 1;
Thanks. 👍
The triangulation code mostly works, and works well. But it crashes when undersignificant load, so it's not yet fit for inclusion in the library.
Thanks. Will update. But wondering if the following may be simpler... public static bool operator !=(PointD lhs, PointD rhs) { return !(lhs == rhs); }
Do I Understand that for the XOR operation all edges are HOT (i.e. have a attached output contour) only for odd even.?. I never played with other windings.
Sorry, I dont know how to use gmail properly.I will be careful when i use the reply option.!
Jay, I got hold of a original release announcement for the general polygon clipper..very old ..got it from wayback archives. It says multiple polygons are allowed on either side only if they are disjoint in the subject group and clip group. for gpc. In the XOR operation it shows some unexpected behaviour if edges within a beam are bundled.(Murta transform of edges). The XOR was introduced in the vatti family by MURTA with his Generic Polygon Clipper. I have edit his version 2.32 and 2.33(later withdrawn!)...
Well, I am just playing with a odd even rule based old program.The output shows intersections. And I thought Doinga union might help. The union can be done over the filled regions in each polygon. no.?. On Mon, Dec 20, 2021 at 4:44 PM Jay Tee jay-tee@users.sourceforge.net wrote:
I was curious whether the triangulation / keyholing code was going to be progressed and eventually see C# form. The sandbox seems to not have this code any more, so I wanted to ask in case it had been dropped.
I have this locally as a way to get Bounds from any paths. It's useful where I just want to query extents without a Boolean public static Rect64 GetBounds(Paths paths) { int i = 0, cnt = paths.Count; while (i < cnt && paths[i].Count == 0) { i++; } if (i == cnt) { return new Rect64(0, 0, 0, 0); } Rect64 result = new() { left = paths[i][0].X }; result.right = result.left; result.top = paths[i][0].Y; result.bottom = result.top; for (; i < cnt; i++) for (int j = 0; j < paths[i].Count; j++) { if (paths[i][j].X...
My IDE flags the equality checks in PointD as potentially problematic due to floating point error. I wonder if this might be better : public static bool operator ==(PointD lhs, PointD rhs) { return (Math.Abs(lhs.x - rhs.x) <= Double.Epsilon) && (Math.Abs(lhs.y - rhs.y) <= Double.Epsilon) && (Math.Abs(lhs.z - rhs.z) <= Double.Epsilon); } public static bool operator !=(PointD lhs, PointD rhs) { return (Math.Abs(lhs.x - rhs.x) > Double.Epsilon) || (Math.Abs(lhs.y - rhs.y) > Double.Epsilon) || (Math.Abs(lhs.z...
Hi again Phil. The answer would've been more obvious if your keyhole_sizing variable had been 50000. Anyhow, EndType.Closed (which is about to be renamed EndType.Joined as it currently is in the Delphi code) corresponds to EndType.etClosedLine in Clipper1. This is very different to EndType.Polygon that corresponds to EndType.etClosedPolygon in Clipper1. You've most likely just been confused by another name change, but to clarify for others (in the absense of any Clipper2 documentation) ... offsetting...
Updated Clipper2 beta
Hi again Phil. The answer would've been more obvious if your keyhole_sizing variable had been 50000. Anyhow, EndType.Closed (which is about to be renamed EndType.Joined as it currently is in the Delphi code) corresponds to EndType.etClosedLine in Clipper1. This is very different to EndType.Polygon that corresponds to EndType.etClosedPolygon in Clipper1. You've most likely just been confused by another name change, but to clarify for others (in the absense of any Clipper2 documentation) ... offsetting...
Hi again Phil. The answer would've been more obvious if your keyhole_sizing variable had been 50000. Anyhow, EndType.Closed (which is about to be renamed EndType.Joined as it currently is in the Delphi code) corresponds to EndType.etClosedLine in Clipper1. This is very different to EndType.Polygon that corresponds to EndType.etClosedPolygon in Clipper1. You've most likely just been confused by another name change, but to clarify for others (in the absense of any Clipper2 documentation) ... offsetting...
Hi again Phil. The answer would've been more obvious if your keyhole_sizing variable had been 50000. Anyhow, EndType.Closed (which is about to be renamed EndType.Joined as it currently is in the Delphi code) corresponds to EndType.etClosedLine in Clipper1. This is very different to EndType.Polygon that corresponds to EndType.etClosedPolygon in Clipper1. You've most likely just been confused by another name change, but to clarify for others (in the absense of any Clipper2 documentation) ... offsetting...
Hi again Phil. The answer would've been more obvious if your keyhole_sizing variable had been 50000. Anyhow, EndType.Closed (which is about to be renamed EndType.Joined as it currently is in the Delphi code) corresponds to EndType.etClosedLine in Clipper1. This is very different to EndType.Polygon that corresponds to EndType.etClosedPolygon in Clipper1. You've most likely just been confused by another name change, but to clarify for others (in the absense of any Clipper2 documentation) ... offsetting...
Hi again Phil. The answer would've been more obvious if your keyhole_sizing variable had been 50000. Anyhow, EndType.Closed (which is about to be renamed EndType.Joined as it currently is in the Delphi code corresponds to EndType.etClosedLine in Clipper1) is very different to EndType.Polygon (that corresponds to EndType.etClosedPolygon in Clipper1). In a sense, offsetting polygons is unidimensional in that positive offsets extend away from every edge's left side, whereas offsetting open paths (polylines)...
I tried to send this through with an attachment, but it never made it to the discussion forum. I'm seeing a major difference in offsetting between Clipper 1 and Clipper 2. Comparison tests for Clipper 1 and Clipper 2 Clipper1 Test1 Out count: 2 Clipper2 Test1 Out count: 4 I expected 2. For Clipper1Test: using ClipperLib1; namespace ClipperLib1Test; using Path = List<IntPoint>; using Paths = List<List<IntPoint>>; public static class Clipper1Test { const double keyhole_sizing = 500; public static void...
I tried to send this through with an attachment, but it never made it to the discussion forum. I'm seeing a major difference in offsetting between Clipper 1 and Clipper 2. Comparison tests for Clipper 1 and Clipper 2 Clipper1 Test1 Out count: 2 Clipper2 Test1 Out count: 4 I expected 2. For Clipper1Test: using ClipperLib1; namespace ClipperLib1Test; using Path = List<intpoint>; using Paths = List<list\<intpoint>>;</list\<intpoint></intpoint> public static class Clipper1Test { const double keyhole_sizing...
SimplifyOption was really a Union (to tidy self-intersections) and then a colinear removal. Neither self-intersections or colinear spikes should be an issue in Clipper2. It's the joining of touching polygons in solutions that was unsatisfactory in Clipper1 and left out of Clipper2.
This is what I was thinking of - I had the code in my DesignLibs_GPL project so pulled this out as an idea. From inspection of ClipperLib1, the SimplifyOption was really a Union (to tidy self-intersections) and then a colinear removal. I'd assume the colinear removal is the missing part to get this going in ClipperLib2, but admit to being uncertain. This code also assumes a closed shape because that's my use case public static Paths stripColinear(Paths source, double angularTolerance = 0.0f) { return...
Yes. I guess a combination of query and reverse would allow me to make a consistent sequence for a mix of differing Path orientations within Paths, with a convenient method to encapsulate this into a convenience call.
I'll play with it when I get the migration sorted and start running tests. I'm limited to C# but hopefully that could still be useful; this is also why I pointed at the github repository earlier. You'll see some customizations there already :)
There is a ReversePaths function but I suspect it hasn't been exposed as public.
Naively, I thought this might be done by looking for angles ~180 degrees (where epsilon is the tolerance). I'm very open to colaboration and incorporating useful code. 😁
As an additional note here, I would like to be able to force orientation, not just query it. I have a few cases where I'm not actually sure what my orientation is for the clipping geometry and used an explicit Positive for subject and Negative for clip in ClipperLib1. With the single fill rule now, I would like to be able to ensure the correct behavior
Naively, I thought this might be done by looking for angles ~180 degrees (where epsilon is the tolerance).
Is the order of argument change intended? Yes, it is 😜. Is it intentional to make the fill rule a required parameter Yes. This parameter should never have had a default value. (I also over complicated this in Clipper1 by having two filling rules, so users could specify different filling from Subject and Clip paths.) Nevertheless, the filling rule is crucial to clipping behavior and I'm not persuaded that most uses would default to even-odd filling. The filling rule really should be explicit. Anyhow,...
I was futzing around with the C# code in my Github over here. Not sure if useful, but you'll see what I was tinkering with and missing: https://github.com/philstopford/DesignLibs_GPL/tree/ClipperLib2/Common/clipper
I'll put this on my growing todo list 😱.
I'll fix. Thanks again for all the feedback. 👍