Klip 2.0.1151

dotnet add package Klip --version 2.0.1151
                    
NuGet\Install-Package Klip -Version 2.0.1151
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Klip" Version="2.0.1151" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Klip" Version="2.0.1151" />
                    
Directory.Packages.props
<PackageReference Include="Klip" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Klip --version 2.0.1151
                    
#r "nuget: Klip, 2.0.1151"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Klip@2.0.1151
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Klip&version=2.0.1151
                    
Install as a Cake Addin
#tool nuget:?package=Klip&version=2.0.1151
                    
Install as a Cake Tool

Logo

Klip

Klip on nuget.org Build Status Test Status license code size

Fast and robust polygon clipping.

A partial F# port of Clipper2 The port is derived from the clipper2-ts TypeScript port rather than the original C#.

All tests pass. And its even faster. see Test README.

Why another port?

In short, to use it in F# and be able to compile to JavaScript via Fable So that this code - and a lot of other code using it - runs on .NET as well as in the browser.

Scope

This is a partial port - only what's needed for polygon boolean operations on a single coordinate type:

  • Polygon boolean ops (intersection, union, difference, XOR) and PolyTree output
  • 64-bit integer coordinates only, but stored as float (64-bit) so the output is Fable-friendly (no bigint in hot paths, no boxed records)
  • No offsetting / inflation, line clipping, rect clipping, Minkowski sums, triangulation, or arbitrary-precision decimal paths

The public surface is in Src/Klip.fs and includes the following key types and operations:

Core Types

  • Path64: Contains a sequence of vertices defining a single contour. X, Y, and Z ordinates are stored in parallel float buffers.
  • Paths64: A list of Path64 contours, representing multiple paths (e.g. an outer polygon and its holes).
  • PolyTree64: A specialized data structure used for returning the results of clipping operations. Unlike Paths64, which is a flat list, PolyTree64 preserves the parent-child relationships between contours (such as a hole being a child of an outer contour).
  • ZCallback64: A callback function that allows you to specify custom logic for calculating the Z-coordinate when two edges intersect and a new vertex is created.

Fill Rules

Fill rules define which regions of a complex polygon are considered "filled":

  • EvenOdd: A point is inside if a ray from it crosses an odd number of edges.
  • NonZero: A point is inside if the winding number is non-zero (default and most common).
  • Positive / Negative: Restricts filling by winding direction.

Boolean Operations

  • intersect(subject, clip, fillRule): Returns the intersection of the subject and clip paths.
  • union(subject, clip, fillRule): Returns the union of subject and clip paths.
  • unionSelf(subject, fillRule): Resolves self-intersections within a single subject path.
  • difference(subject, clip, fillRule): Returns the regions of the subject that are NOT inside the clip region.
  • xor(subject, clip, fillRule): Returns the regions of subject or clip that are not in both.
  • booleanOpWithPolyTree(clipType, subject, clip, polyTree, fillRule): Computes the boolean operation and outputs the result into a PolyTree64 to preserve the topological hierarchy.
  • polyTreeToPaths64(polyTree): Flattens a PolyTree64 back into a Paths64 list.

Building

for .NET

dotnet build

for JS

cd Test
npm install
npm run buildTS   # F# → TypeScript via Fable, then tsc
npm test          # vitest --run

The compiled TypeScript ends up in Klip/Test/_ts/Src/ and is what the test suite imports.

Differences from clipper2-ts

  • Path64 is a class with parallel xs[] / ys[] / zs[] buffers, not an array of {x, y, z} objects. This is more cache-friendly under Fable's JS output and avoids per-point object allocations.
  • Fewer features (see Scope above).

Performance

Klip when compiled to JavaScript is about 30% faster than clipper2-ts. Tested on union operations with 100 adjacent polygons.

Klip doesn't have its own Point64 object but just uses the parallel xs[] / ys[] / zs[] buffers in Path64. The internal Engine objects have just x, y and z properties instead of Point64 objects, and the scanline engine operates on these directly. So in total fewer JS objects are allocated.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.1151 80 5/1/2026

### Changed

- First release of Port of Clipper2 , ported and adapted from clipper2-ts version 2.0.1-15 to F#[2.0.1151]: https://github.com/goswinr/Klip/releases/tag/2.0.1151