Speed tests* (faster is better) ... | Features ... | Cost | ||||||
Classic 174239¹ | Ellipses & Fan | Ellipses & Rectangles | Overlap Stars | Complex Polygons² | Supports complex polygons | Miscellaneous | Free for commercial use | |
General Polygon Clipper | 2785 ms | 112 ms | 125 ms | 31 ms | Multiple errors³ | Yes | Last updated Dec 2004 | No |
PolyBool | 835 ms | 138 ms | 174 ms | 28 ms | N/A | No | Last updated Jun 2006 | No |
Boost Geometry | 78 ms | 43 ms | 33 ms | 25 ms | N/A | No | C++ only Depends on Boost Library |
Yes |
Clipper | 113 ms | 31 ms | 36 ms | 9 ms | No errors | Yes | C++,C#,Delphi, Offsetting, Minkowski Sum |
Yes |
Code snippets showing how to use the Clipper library to do a polygon intersection ... |
#include "clipper.hpp" //from clipper.hpp ... //typedef signed long long cInt; //struct IntPoint {cInt X; cInt Y;}; //typedef std::vector<IntPoint> Path; //typedef std::vector<Path> Paths; ... using namespace ClipperLib; Paths subj(2), clip(1), solution; //define outer blue 'subject' polygon subj[0] << IntPoint(180,200) << IntPoint(260,200) << IntPoint(260,150) << IntPoint(180,150); //define subject's inner triangular 'hole' (with reverse orientation) subj[1] << IntPoint(215,160) << IntPoint(230,190) << IntPoint(200,190); //define orange 'clipping' polygon clip[0] << IntPoint(190,210) << IntPoint(240,210) << IntPoint(240,130) << IntPoint(190,130); //draw input polygons with user-defined routine ... DrawPolygons(subj, 0x160000FF, 0x600000FF); //blue DrawPolygons(clip, 0x20FFFF00, 0x30FF0000); //orange //perform intersection ... Clipper c; c.AddPaths(subj, ptSubject, true); c.AddPaths(clip, ptClip, true); c.Execute(ctIntersection, solution, pftNonZero, pftNonZero); //draw solution with user-defined routine ... DrawPolygons(solution, 0x3000FF00, 0xFF006600); //solution shaded green |
uses Clipper; ... var i: integer; subj, clip, solution: TPaths; begin setlength(subj, 2); setlength(subj[0], 4); subj[0][0] := IntPoint(180,200); subj[0][1] := IntPoint(260,200); subj[0][2] := IntPoint(260,150); subj[0][3] := IntPoint(180,150); setlength(subj[1], 3); subj[1][0] := IntPoint(215,160); subj[1][1] := IntPoint(230,190); subj[1][2] := IntPoint(200,190); setlength(clip, 1); setlength(clip[0], 4); clip[0][0] := IntPoint(190,210); clip[0][1] := IntPoint(240,210); clip[0][2] := IntPoint(240,130); clip[0][3] := IntPoint(190,130); DrawPolygons(subj, $160000FF, $600000FF); DrawPolygons(clip, $20FFFF00, $30FF0000); with TClipper.Create do try AddPaths(subj, ptSubject, true); AddPaths(clip, ptClip, true); Execute(ctIntersection, solution, pftNonZero, pftNonZero); DrawPolygons(solution, $3000FF00, $FF006600); finally free; end; end; |
using ClipperLib; using Path = List<IntPoint>; using Paths = List<List<IntPoint>>; ... Paths subj = new Paths(2); subj.Add (new Path(4)); subj[0].Add(new IntPoint(180, 200)); subj[0].Add(new IntPoint(260, 200)); subj[0].Add(new IntPoint(260, 150)); subj[0].Add(new IntPoint(180, 150)); subj.Add(new Path(3)); subj[1].Add(new IntPoint(215, 160)); subj[1].Add(new IntPoint(230, 190)); subj[1].Add(new IntPoint(200, 190)); Paths clip = new Paths(1); clip.Add(new Path(4)); clip[0].Add(new IntPoint(190, 210)); clip[0].Add(new IntPoint(240, 210)); clip[0].Add(new IntPoint(240, 130)); clip[0].Add(new IntPoint(190, 130)); DrawPolygons(subj, Color.FromArgb(0x16, 0, 0, 0xFF), Color.FromArgb(0x60, 0, 0, 0xFF)); DrawPolygons(clip, Color.FromArgb(0x20, 0xFF, 0xFF, 0), Color.FromArgb(0x30, 0xFF, 0, 0)); Paths solution = new Paths(); Clipper c = new Clipper(); c.AddPaths(subj, PolyType.ptSubject, true); c.AddPaths(clip, PolyType.ptClip, true); c.Execute(ClipType.ctIntersection, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); DrawPolygons(solution, Color.FromArgb(0x30, 0, 0xFF, 0), Color.FromArgb(0xFF, 0, 0x66, 0)); |