Clipper - an open source freeware library for
clipping and offsetting lines and polygons.

The Clipper library performs line & polygon clipping - intersection, union, difference & exclusive-or,
and line & polygon offsetting. The library is based on Vatti's clipping algorithm.

The download package contains the library's full source code (written in Delphi, C++ and C#),
numerous demos, a help file and links to third party Python, Perl, Ruby and Haskell modules.

Version: 6.1.3
Last updated: 19 January 2014
Freeware for both open source and commercial applications (Boost Software License).
Copyright © 2010-2014 Angus Johnson

Clipper's features compared with 3 other polygon clipping libraries:
  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
Clipper 113 ms 31 ms 36 ms 9 ms No errors Yes C++,C#,Delphi,
Offsetting, Minkowski Sum

* Speed tests were performed using the latest versions of all software as published on the respective websites (as of 11 April 2013). The benchmark test utility with full source code can be downloaded here. Tests were performed on a PC with 2.53 gigahertz Intel Core2 Duo P8700 processor with 4GB RAM running Window 7 Professional.
¹ The 'Classic 174239' test uses a test data sample from the PolyBoolean website here.
² The 'Complex Polygons' test consists of intersecting a single subject and single clip polygon with random vertices. Coordinates are rounded to multiples of 10 to substantially increase the frequency that more than two edges intersect at a given point. This "stress-tests" the clipping algorithms. (PolyBoolean and Boost Geometry could not be tested since they do not allow boolean operations on complex polygons.)
³ The errors in GPC's random polygon test are unhandled exceptions that result in a failure of the clipping operation.

An independent test of multiple polygon clipping libraries can be found here:

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;
	  i: integer;
	  subj, clip, solution: TPaths;
	  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
	    AddPaths(subj, ptSubject, true);
	    AddPaths(clip, ptClip, true);
	    Execute(ctIntersection, solution, pftNonZero, pftNonZero);
	    DrawPolygons(solution, $3000FF00, $FF006600);

	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));

Back to my Delphi Page « » Back to my Home Page