



| 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 Python;Javascript Polygon Offsetting |
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 long64; //struct IntPoint {long64 X; long64 Y;}; //typedef std::vector<IntPoint> Polygon; //typedef std::vector<Polygon> Polygons; ... using namespace ClipperLib; Polygons subj(2), clip(1), solution; //define outer blue 'subject' polygon subj[0].push_back(IntPoint(180,200)); subj[0].push_back(IntPoint(260,200)); subj[0].push_back(IntPoint(260,150)); subj[0].push_back(IntPoint(180,150)); //define subject's inner triangular 'hole' (with reverse orientation) subj[1].push_back(IntPoint(215,160)); subj[1].push_back(IntPoint(230,190)); subj[1].push_back(IntPoint(200,190)); //define orange 'clipping' polygon clip[0].push_back(IntPoint(190,210)); clip[0].push_back(IntPoint(240,210)); clip[0].push_back(IntPoint(240,130)); clip[0].push_back(IntPoint(190,130)); DrawPolygons(subj, 0x160000FF, 0x600000FF); //blue DrawPolygons(clip, 0x20FFFF00, 0x30FF0000); //orange //perform intersection ... Clipper c; c.AddPolygons(subj, ptSubject); c.AddPolygons(clip, ptClip); c.Execute(ctIntersection, solution, pftNonZero, pftNonZero); DrawPolygons(solution, 0x3000FF00, 0xFF006600); //solution shaded green |
uses Clipper; ... var i: integer; subj, clip, solution: TPolygons; 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 AddPolygons(subj, ptSubject); AddPolygons(clip, ptClip); Execute(ctIntersection, solution, pftNonZero, pftNonZero); DrawPolygons(solution, $3000FF00, $FF006600); finally free; end; end; |
using ClipperLib; using Polygon = List<IntPoint>; using Polygons = List<List<IntPoint>>; ... Polygons subj = new Polygons(2); subj.Add (new Polygon(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 Polygon(3)); subj[1].Add(new IntPoint(215, 160)); subj[1].Add(new IntPoint(230, 190)); subj[1].Add(new IntPoint(200, 190)); Polygons clip = new Polygons(1); clip.Add(new Polygon(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)); Polygons solution = new Polygons(); Clipper c = new Clipper(); c.AddPolygons(subj, PolyType.ptSubject); c.AddPolygons(clip, PolyType.ptClip); c.Execute(ClipType.ctIntersection, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); DrawPolygons(solution, Color.FromArgb(0x30, 0, 0xFF, 0), Color.FromArgb(0xFF, 0, 0x66, 0)); |