Skip to content
This repository was archived by the owner on Oct 28, 2026. It is now read-only.
AngusJohnsonPublic archive

Latest commit

 

History

820 Commits

Folders and files

Repository files navigation

Clipper2

The future of Clipper development is now here.

The bad news: As of now I’m retiring from Clipper2 development. While this Clipper2 repository will remain, it will not be updated. So please don't post new Issues or Pull Requests here.
The good news: I’m delighted to announce that Seth Hillibrand has agreed to take over Clipper maintenance and development, and this will continue at the link above.

The long version:
Software development has been a wonderful hobby of mine for almost 50 years. I started Clipper more than 15 years ago, and it has been 15 years of fun and challenge. But over the last few months I’ve come to realise that the challenge has gone, and it has just become a responsibility.
So I’m passing the baton. And I’m delighted to announce Seth Hillibrand has agreed to pick it up and will be taking over Clipper’s ongoing maintenance and development. Seth is the founder and lead developer of KiCad Services, and has used Clipper almost from the beginning. I’m extremely confident that he has the skills and temperament to see Clipper continue to improve. But Clipper will, however, become a C++ only library; it will be up to third parties to translate Clipper into other languages, or to use it as a dynamic linked library.

Transitioning to the new Clipper2 repository:
I suggest that those who have contributed Pull Requests do so again here.
And I suggest that those who have raised Issues also resubmit them here or, even better, consider converting them into Pull Requests if you are able to do the debugging.

Finally, as I said above, creating and developing Clipper has been a lot of fun. I have learned so much from you, the library’s users, and from your code contributions. And that has been enormously encouraging. Thank you.


A Polygon Clipping, Offsetting library (in C++, C# & Delphi)

GitHub Actions C++ status C# License Nuget documentation

The Clipper2 library performs intersection, union, difference and XOR boolean operations on both simple and complex polygons. It also performs polygon offsetting. This is a major update of my original Clipper library that was written about 15 years ago. That library I'm now calling Clipper1, and while it still works very well, Clipper2 is just better.

Compilers

Clipper2 can be compiled using any one of three supported programming languages: C++, or C#, or Delphi Pascal. The library can also be accessed from other languages by dynamically linking to exported functions in the C++ compiled Clipper2 library. (The C++ compiled code is measurably faster so, where performance is critical, even C# and Delphi developers may prefer this approach in application development.)

Lang. Requirements
C++: Requires C++17, or
C#: The library uses Standard Library 2.0 but the sample code uses .NET6, or
Delphi: Compiles with any version of Delphi from version 7 to current.

Documentation

Extensive HTML documentation

Examples

Clipping

C++
// intersect a star and another modestly rotated star
Paths64 subject, clip, solution;
subject.push_back({ MakePath({200,100, 20,158, 130,4, 130,196, 20,42}) });
clip.push_back({ MakePath({196,126, 8,136, 154,16, 104,200, 38,24}) });
solution = Intersect(subject, clip, FillRule::NonZero);
DisplayAsSvgImage("Intersect Paths", FillRule::NonZero, subject, clip, solution);
C#
const FillRule fillrule = FillRule.NonZero;
Paths64 subject = new() { Clipper.MakePath(new int[] { 200, 100, 20, 158, 130, 4, 130, 196, 20, 42 }) };
Paths64 clip = new() { Clipper.MakePath(new int[] { 196, 126, 8, 136, 154, 16, 104, 200, 38, 24 }) };
Paths64 solution = Clipper.Intersect(subject, clip, fillrule);
DisplayAsSvgImage("Intersect", fillrule, subject, clip, solution);
Delphi
SetLength(subj, 1);
subj[0] := MakePathD([200,100, 20,158, 130,4, 130,196, 20,42]);
SetLength(clip, 1);
clip[0] := MakePathD([196,126, 8,136, 154,16, 104,200, 38,24]);
solution := Intersect( subj, clip, frNonZero);
DisplayAsSvg('Intersect (nonzero)', frNonZero, subj, clip, solution);

clipperB

Inflating (aka Offsetting)

C++
SvgReader svg_reader("./rabbit.svg");
PathsD p = svg_reader.paths;
PathsD solution(p);
while (p.size())
{
p = InflatePaths(p, -5, JoinType::Round, EndType::Polygon);
// SimplifyPaths is not essential but is **highly recommended**
// because it speeds up the loop by removing tiny artefacts
p = SimplifyPaths(p, 0.25);
copy(p.begin(), p.end(), back_inserter(solution));
}
DisplayAsSvgImage("rabbit_offset", FillRule::EvenOdd, nullptr, nullptr, &solution);
C#
SvgReader sr = new("..\\..\\..\\rabbit.svg");
PathsD pp = sr.Paths;
PathsD solution = new (pp);
while (pp.Count > 0)
{
pp = Clipper.InflatePaths(pp, -5, JoinType.Round, EndType.Polygon);
// SimplifyPaths - is recommended here as it removes tiny
// offsetting artefacts and speeds up this while loop
pp = Clipper.SimplifyPaths(pp, 0.25);
solution.AddRange(pp);
}
DisplaySolutionAsSvg("..\\..\\..\\rabbit_inflate.svg", solution);
Delphi
sol := GetPathsFromVerySimpleSVG('rabbit.svg');
sol := SimplifyPaths(sol, 0.25);
p := sol;
while (Length(p) > 0) do
begin
p := InflatePaths(p, -5, jtRound, etPolygon);
// SimplifyPaths is not essential but is **highly recommended**
// because it speeds up the loop by removing tiny artefacts
p := SimplifyPaths(p, 0.25);
AppendPaths(sol, p);
end;
DisplayAsSvg('DeflatedRabbit', frEvenOdd, sol, nil, sol, true);

rabbit rabbit_offset


Ports to other languages

lang. link
golang https://github.com/epit3d/goclipper2
Haxe https://github.com/jeremyfa/Clipper2/tree/main/Haxe
Java https://github.com/micycle1/Clipper2-java/
Kotlin https://github.com/Monkey-Maestro/clipper2-kotlin
Lua https://github.com/Ark223/Clipper2-Lua
Rust https://github.com/larsbrubaker/clipper2-rust
Swift https://github.com/zyunlongz/clipper2-swift
TypeScript https://github.com/countertype/clipper2-ts
WASM https://github.com/ErikSom/Clipper2-WASM/