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

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 DelphiC++ and C#),
numerous demos, a help file and links to third party PythonPerlRuby 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 & FanEllipses & RectanglesOverlap StarsComplex Polygons²Supports complex polygonsMiscellaneousFree for commercial use
General Polygon Clipper2785 ms112 ms125 ms31 msMultiple errors³YesLast updated Dec 2004No
PolyBool835 ms138 ms174 ms28 msN/ANoLast updated Jun 2006No
Boost Geometry78 ms43 ms33 ms25 msN/ANoC++ only
Depends on Boost Library
Yes
Clipper113 ms31 ms36 ms9 msNo errorsYesC++,C#,Delphi,
Offsetting, Minkowski Sum
Yes

* 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:
http://rogue-modron.blogspot.com/2011/04/polygon-clipping-wrapper-benchmark.html



Code snippets showing how to use the Clipper library to do a polygon intersection ...

C++
<span style="color:#000000">	<span style="color:#3333ff"><strong>#include </strong></span><span style="color:#3333ff"><strong>"clipper.hpp"</strong></span>
	
	<span style="color:#2bb6e2"><strong><em>//from clipper.hpp ...</em></strong></span>
	<span style="color:#2bb6e2"><strong><em>//typedef signed long long cInt;</em></strong></span>
	<span style="color:#2bb6e2"><strong><em>//struct IntPoint {cInt X; cInt Y;};</em></strong></span>
	<span style="color:#2bb6e2"><strong><em>//typedef std::vector<IntPoint> Path;</em></strong></span>
	<span style="color:#2bb6e2"><strong><em>//typedef std::vector<Path> Paths;</em></strong></span>
	...
	<span style="color:#000000"><strong>using namespace</strong></span> ClipperLib;
	
	Paths subj(<span style="color:#009900"><strong>2</strong></span>), clip(<span style="color:#009900"><strong>1</strong></span>), solution;
	
	<span style="color:#2bb6e2"><strong><em>//define outer blue 'subject' polygon</em></strong></span>
	subj[<span style="color:#009900"><strong>0</strong></span>] << 
	  IntPoint(<span style="color:#009900"><strong>180</strong></span>,<span style="color:#009900"><strong>200</strong></span>) << IntPoint(<span style="color:#009900"><strong>260</strong></span>,<span style="color:#009900"><strong>200</strong></span>) <<
	  IntPoint(<span style="color:#009900"><strong>260</strong></span>,<span style="color:#009900"><strong>150</strong></span>) << IntPoint(<span style="color:#009900"><strong>180</strong></span>,<span style="color:#009900"><strong>150</strong></span>);
	
	<span style="color:#2bb6e2"><strong><em>//define subject's inner triangular 'hole' (with reverse orientation)</em></strong></span>
	subj[<span style="color:#009900"><strong>1</strong></span>] << 
	  IntPoint(<span style="color:#009900"><strong>215</strong></span>,<span style="color:#009900"><strong>160</strong></span>) << IntPoint(<span style="color:#009900"><strong>230</strong></span>,<span style="color:#009900"><strong>190</strong></span>) << IntPoint(<span style="color:#009900"><strong>200</strong></span>,<span style="color:#009900"><strong>190</strong></span>);
	
	<span style="color:#2bb6e2"><strong><em>//define orange 'clipping' polygon</em></strong></span>
	clip[<span style="color:#009900"><strong>0</strong></span>] << 
	  IntPoint(<span style="color:#009900"><strong>190</strong></span>,<span style="color:#009900"><strong>210</strong></span>) << IntPoint(<span style="color:#009900"><strong>240</strong></span>,<span style="color:#009900"><strong>210</strong></span>) << 
	  IntPoint(<span style="color:#009900"><strong>240</strong></span>,<span style="color:#009900"><strong>130</strong></span>) << IntPoint(<span style="color:#009900"><strong>190</strong></span>,<span style="color:#009900"><strong>130</strong></span>);
	
	<span style="color:#2bb6e2"><strong><em>//draw input polygons with user-defined routine ... </em></strong></span>
	DrawPolygons(subj, <span style="color:#009900"><strong>0x160000FF</strong></span>, <span style="color:#009900"><strong>0x600000FF</strong></span>); <span style="color:#2bb6e2"><strong><em>//blue</em></strong></span>
	DrawPolygons(clip, <span style="color:#009900"><strong>0x20FFFF00</strong></span>, <span style="color:#009900"><strong>0x30FF0000</strong></span>); <span style="color:#2bb6e2"><strong><em>//orange</em></strong></span>
	
	<span style="color:#2bb6e2"><strong><em>//perform intersection ...</em></strong></span>
	Clipper c;
	c.AddPaths(subj, ptSubject, true);
	c.AddPaths(clip, ptClip, true);
	c.Execute(ctIntersection, solution, pftNonZero, pftNonZero);

	<span style="color:#2bb6e2"><strong><em>//draw solution with user-defined routine ... </em></strong></span>
	DrawPolygons(solution, <span style="color:#009900"><strong>0x3000FF00</strong></span>, <span style="color:#009900"><strong>0xFF006600</strong></span>); <span style="color:#2bb6e2"><strong><em>//solution shaded green</em></strong></span>
</span>


Delphi
<span style="color:#000000">	<span style="color:#000000"><strong>uses</strong></span> Clipper;
	...
	<span style="color:#000000"><strong>var</strong></span>
	  i: integer;
	  subj, clip, solution: TPaths;
	<span style="color:#000000"><strong>begin</strong></span>
	  setlength(subj, <span style="color:#009900"><strong>2</strong></span>);
	  setlength(subj[<span style="color:#009900"><strong>0</strong></span>], <span style="color:#009900"><strong>4</strong></span>);
	  subj[<span style="color:#009900"><strong>0</strong></span>][<span style="color:#009900"><strong>0</strong></span>] := IntPoint(<span style="color:#009900"><strong>180</strong></span>,<span style="color:#009900"><strong>200</strong></span>);
	  subj[<span style="color:#009900"><strong>0</strong></span>][<span style="color:#009900"><strong>1</strong></span>] := IntPoint(<span style="color:#009900"><strong>260</strong></span>,<span style="color:#009900"><strong>200</strong></span>);
	  subj[<span style="color:#009900"><strong>0</strong></span>][<span style="color:#009900"><strong>2</strong></span>] := IntPoint(<span style="color:#009900"><strong>260</strong></span>,<span style="color:#009900"><strong>150</strong></span>);
	  subj[<span style="color:#009900"><strong>0</strong></span>][<span style="color:#009900"><strong>3</strong></span>] := IntPoint(<span style="color:#009900"><strong>180</strong></span>,<span style="color:#009900"><strong>150</strong></span>);
	  
	  setlength(subj[<span style="color:#009900"><strong>1</strong></span>], <span style="color:#009900"><strong>3</strong></span>);
	  subj[<span style="color:#009900"><strong>1</strong></span>][<span style="color:#009900"><strong>0</strong></span>] := IntPoint(<span style="color:#009900"><strong>215</strong></span>,<span style="color:#009900"><strong>160</strong></span>);
	  subj[<span style="color:#009900"><strong>1</strong></span>][<span style="color:#009900"><strong>1</strong></span>] := IntPoint(<span style="color:#009900"><strong>230</strong></span>,<span style="color:#009900"><strong>190</strong></span>);
	  subj[<span style="color:#009900"><strong>1</strong></span>][<span style="color:#009900"><strong>2</strong></span>] := IntPoint(<span style="color:#009900"><strong>200</strong></span>,<span style="color:#009900"><strong>190</strong></span>);

	  setlength(clip, <span style="color:#009900"><strong>1</strong></span>);
	  setlength(clip[<span style="color:#009900"><strong>0</strong></span>], <span style="color:#009900"><strong>4</strong></span>);
	  clip[<span style="color:#009900"><strong>0</strong></span>][<span style="color:#009900"><strong>0</strong></span>] := IntPoint(<span style="color:#009900"><strong>190</strong></span>,<span style="color:#009900"><strong>210</strong></span>);
	  clip[<span style="color:#009900"><strong>0</strong></span>][<span style="color:#009900"><strong>1</strong></span>] := IntPoint(<span style="color:#009900"><strong>240</strong></span>,<span style="color:#009900"><strong>210</strong></span>);
	  clip[<span style="color:#009900"><strong>0</strong></span>][<span style="color:#009900"><strong>2</strong></span>] := IntPoint(<span style="color:#009900"><strong>240</strong></span>,<span style="color:#009900"><strong>130</strong></span>);
	  clip[<span style="color:#009900"><strong>0</strong></span>][<span style="color:#009900"><strong>3</strong></span>] := IntPoint(<span style="color:#009900"><strong>190</strong></span>,<span style="color:#009900"><strong>130</strong></span>);
	  
	  DrawPolygons(subj, <span style="color:#009900"><strong>$160000FF</strong></span>, <span style="color:#009900"><strong>$600000FF</strong></span>);
	  DrawPolygons(clip, <span style="color:#009900"><strong>$20FFFF00</strong></span>, <span style="color:#009900"><strong>$30FF0000</strong></span>);
		
	  <span style="color:#000000"><strong>with</strong></span> TClipper<span style="color:#000000"><strong>.</strong></span>Create <span style="color:#000000"><strong>do</strong></span>
	  <span style="color:#000000"><strong>try</strong></span>
	    AddPaths(subj, ptSubject, true);
	    AddPaths(clip, ptClip, true);
	    Execute(ctIntersection, solution, pftNonZero, pftNonZero);
	    DrawPolygons(solution, <span style="color:#009900"><strong>$3000FF00</strong></span>, <span style="color:#009900"><strong>$FF006600</strong></span>);
	  <span style="color:#000000"><strong>finally</strong></span>
	    free<span style="color:#000000"><strong>;</strong></span>
	  <span style="color:#000000"><strong>end</strong></span>;
	  
	<span style="color:#000000"><strong>end</strong></span>;
</span>


C#
<span style="color:#000000">	<span style="color:#3333ff"><strong>using</strong></span> ClipperLib;
	
	<span style="color:#3333ff"><strong>using</strong></span> <span style="color:#2bb6e2"><strong>Path</strong></span> = <span style="color:#2bb6e2"><strong>List</strong></span><<span style="color:#2bb6e2"><strong>IntPoint</strong></span>>;
	<span style="color:#3333ff"><strong>using</strong></span> <span style="color:#2bb6e2"><strong>Paths</strong></span> = <span style="color:#2bb6e2"><strong>List</strong></span><<span style="color:#2bb6e2"><strong>List</strong></span><<span style="color:#2bb6e2"><strong>IntPoint</strong></span>>>;
	...
	<span style="color:#2bb6e2"><strong>Paths</strong></span> subj = <span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>Paths</strong></span>(2);
	subj.Add (<span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>Path</strong></span>(4));
	subj[0].Add(<span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>IntPoint</strong></span>(180, 200));
	subj[0].Add(<span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>IntPoint</strong></span>(260, 200));	
	subj[0].Add(<span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>IntPoint</strong></span>(260, 150));
	subj[0].Add(<span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>IntPoint</strong></span>(180, 150));

	subj.Add(<span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>Path</strong></span>(3));
	subj[1].Add(<span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>IntPoint</strong></span>(215, 160));
	subj[1].Add(<span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>IntPoint</strong></span>(230, 190));	
	subj[1].Add(<span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>IntPoint</strong></span>(200, 190));

	<span style="color:#2bb6e2"><strong>Paths</strong></span> clip = <span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>Paths</strong></span>(1);
	clip.Add(<span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>Path</strong></span>(4));
	clip[0].Add(<span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>IntPoint</strong></span>(190, 210));
	clip[0].Add(<span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>IntPoint</strong></span>(240, 210));	
	clip[0].Add(<span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>IntPoint</strong></span>(240, 130));
	clip[0].Add(<span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>IntPoint</strong></span>(190, 130));

	DrawPolygons(subj, <span style="color:#2bb6e2"><strong>Color</strong></span>.FromArgb(0x16, 0, 0, 0xFF), 
	  <span style="color:#2bb6e2"><strong>Color</strong></span>.FromArgb(0x60, 0, 0, 0xFF));
	DrawPolygons(clip, <span style="color:#2bb6e2"><strong>Color</strong></span>.FromArgb(0x20, 0xFF, 0xFF, 0), 
	  <span style="color:#2bb6e2"><strong>Color</strong></span>.FromArgb(0x30, 0xFF, 0, 0));

	<span style="color:#2bb6e2"><strong>Paths</strong></span> solution = <span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>Paths</strong></span>();

	<span style="color:#2bb6e2"><strong>Clipper</strong></span> c = <span style="color:#3333ff"><strong>new</strong></span> <span style="color:#2bb6e2"><strong>Clipper</strong></span>();
	c.AddPaths(subj, <span style="color:#2bb6e2"><strong>PolyType</strong></span>.ptSubject, true);
	c.AddPaths(clip, <span style="color:#2bb6e2"><strong>PolyType</strong></span>.ptClip, true);
	c.Execute(<span style="color:#2bb6e2"><strong>ClipType</strong></span>.ctIntersection, solution, 
	  <span style="color:#2bb6e2"><strong>PolyFillType</strong></span>.pftEvenOdd, <span style="color:#2bb6e2"><strong>PolyFillType</strong></span>.pftEvenOdd);
	DrawPolygons(solution, <span style="color:#2bb6e2"><strong>Color</strong></span>.FromArgb(0x30, 0, 0xFF, 0), 
	  <span style="color:#2bb6e2"><strong>Color</strong></span>.FromArgb(0xFF, 0, 0x66, 0));
	
</span>
 

http://www.angusj.com/delphi/clipper.php

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值