All changes to this project will be documented in this file
Engine: fixed sliver triangle union bug (#21, upstream #1067) —cleanCollinearnow always callsfixSelfIntersects, and removed faulty micro self-intersection shortcutEngine/RectClip: fixed dead assignments flagged byno-useless-assignment
- Upgraded eslint to v10, typescript-eslint to 8.56.1-alpha.3 (resolves minimatch ReDoS advisory)
Triangulation: removed deadhorizontalBetweenchecks (never reached in practice)
Offset:hypotenuseusesx * xinstead ofMath.pow(x, 2)
Offset: Z now propagates through all join types, open path caps, and single-point offsetsCore:getLineIntersectPtendpoint copies now carry Z
- Build/minifier compatibility: replaced BigInt literal syntax (eg
0n) with cachedBigInt()constants to avoid acompress.evaluateerror in some consuming pipelines and terser versions
Engine: ScanlineHeap siftUp/siftDown now use hole-sift pattern instead of destructuring swap (avoids temporary array allocation per swap step)Core: removed redundant< 46341fast path inproductsAreEqual(maxDeltaForSafeProductreplaced it)- Converted remaining TypeScript
namespacedeclarations to plainconstobjects across Core.ts, Engine.ts, and Minkowski.tsInternalClipper.UInt128Structpreserved as a deprecated type alias for backward compatibility though it's unlikely anyone was using it - Removed stale
OutPtPoolandVertexPoolfiles from dist (no corresponding source) - Added
exportsfield to package.json for modern bundler resolution - Froze
InvalidRect64andInvalidRectDsingletons withObject.freeze - Added rolldown bundled/minified single-file dist (
dist/clipper2.min.mjs) - Added
typemodifiers to type-only re-exports in index.ts
Engine: removed debug ID counters fromOutPtandOutRecEngine:cleanCollinearnow skipsfixSelfIntersectswhen no points were actually removedOffset: pushpathOutdirectly intosolutioninstead of spread-cloning it; the array is freshly allocated per output path so the copy was unnecessaryCore/Engine:getLineIntersectPtreturnsPoint64 | nullinstead of a{ intersects, point }wrapper object, eliminating an allocation on every intersection testEngine:createIntersectNodetakes ownership of the point directly instead of copying it (the caller always passes a fresh allocation)Engine:popScanlinereturnsnumber | nullinstead of a{ success, y }wrapper object, eliminating an allocation on every scanline transition in the main sweep loopRectClip:getSegmentIntersectionreturnsPoint64 | nullinstead of a wrapper object;getIntersectionreuses a single result object instead of allocating per callCore:roundToEvenrewritten to doMath.roundfirst and only correct the rare exact-half case, removing unnecessaryMath.floor/Math.absfrom the hottopXpathTriangulation:removeEdgeFromVertexuses swap-with-last-and-pop instead ofsplice
- Triangulation: fixed overlapping triangles in polygons with holes (#1062) by correcting bridge-edge visibility check in
createInnerLocMinLooseEdge - Export
polyTreeToPaths64andpolyTreeToPathsDdirectly from index (previously only available viaClippernamespace)
- Triangulation: stabilized Delaunay flip handling to prevent flip oscillations in edge-case inputs
- Triangulation: added a safe-math pre-scan for speed when coordinates stay within safe integer range
- Triangulation: expanded test coverage for failure cases and edge conditions
- Removed
Clippernamespace for better tree-shaking via #11, which was based on #4 to address #3- Added
sideEffects: falseto package.json for same reason
- Added
- Updated eslint to v9 (flat config) to resolve moderate security vulnerability
- Removed unused imports across source files
Clipperobject export fromClipper.js- use named exports orimport * as Clipperinstead
- Precision safety for large coordinates: BigInt fallback for intermediate calculations to prevent overflow beyond
MAX_SAFE_INTEGER, with runtime errors when inputs exceed safe bounds (#6)
- Fixed triangulation failures and infinite loops from upstream issues #1055/#1056 (shared endpoints and near-collinear segments)
- Rolled back precision safety changes from 2.0.1-3 while evaluating completeness and performance tradeoffs - current draft is happening in #6
- BigInt fallback for intermediate calculations (cross products, dot products, area) to handle large-but-safe coordinate values correctly
- Fixed crash in
inflatePathsDwhen given a zero-area ring — JS optional chaining returnsundefinedvs C#'snull, so changed=== nullto== nullinaddPathsToVertexList
- Interactive examples page with boolean operations, offsetting, triangulation, and Z-callback demos
- Performance: closed-path-only fast paths, reduced object allocation in hot loops
Current as of Clipper2 v2.0.1 (21ebba0)
- Updated to track Clipper2 v2.0.1 (C++ DLL export updates only; no C# library changes)
Current as of Clipper2 v2.0.0 (f39457d)
- Fixed
triangulateDto properly return error status when triangulation fails instead of always returning success
- Updated
TriangulateResultenum naming to use camelCase:no_polygons→noPolygons,paths_intersect→pathsIntersect - Removed redundant
findLocMinIdxcall in triangulation path processing
Current as of 578ca4d
- Z-coordinate support:
Point64andPointDnow support optionalzproperty ZCallback64andZCallbackDcallback types for Z interpolation at intersectionszCallbackproperty onClipper64,ClipperD, andClipperOffsetclasses- Triangulation support: constrained Delaunay triangulation (beta)
triangulate(paths, useDelaunay)for integer coordinatestriangulateD(paths, decPlaces, useDelaunay)for floating-point coordinatesTriangulateResultenum for result statusDelaunayclass for advanced triangulation control
- Glyph benchmark:
benchmarks/glyph-e.bench.tsto measure union performance on a flattened outline typical of font contours
ClipperBasescanline handling: added an adaptive array-backed scanline mode for smallminimaListworkloads, with automatic upgrade to the heap+set path when scanline count grows. This reduces overhead for small glyph-like unions while preserving existing behavior on larger inputs
- Corrected 64-bit integer handling in
multiplyUInt64by replacing unsafe>>> 0truncation withBigIntarithmetic. This fixes incorrect results for coordinates larger than 2^32
- Optimized
productsAreEqualandcrossProductSignwith fast paths for safe integer ranges (approx +/- 9e7), avoidingBigIntoverhead for typical use cases - Unrolled hot loops in
addPathsToVertexListto standardforloops for improved V8 performance
- Modernized build to ES modules with NodeNext module resolution
- Updated to ES2022 target
- Package renamed from
@countertype/clipper2-tstoclipper2-ts(no scope)
- Replaced the sorted scanline array in
ClipperBasewith a binary max-heap
- Bounding box fast exit before expensive segment intersection checks
- Fast path in
productsAreEqualfor collinearity checks when coordinate values < 46341 (avoids BigInt overhead for typical cases while maintaining accuracy for larger values)
- Inlined point equality checks in hot paths for performance
createLocalMinima()function (usenew LocalMinima()constructor directly for better performance)
Current as of 9a869ba
- Fixed iterator bug in
checkSplitOwnerthat could cause crashes when splits array is modified during recursive iteration (#1029)
Current as of 618c05c
- Upgraded to Clipper2 1.5.4+ algorithm improvements
- Implemented
CrossProductSignfor better numerical stability with large coordinates - Rewrote
SegmentsIntersectusing parametric approach for improved accuracy - Fixed critical
TriSignbug (changedx > 1tox > 0) - Updated
PointInPolygonto useCrossProductSignfor better precision - Added
GetLineIntersectPtoverload for PointD coordinates - Renamed
getSegmentIntersectPttogetLineIntersectPtfor consistency
- 128-bit overflow protection in cross product calculations
- Improved handling of near-collinear points
- Better precision in edge cases with very large coordinate values
Current as of 9741103
- Initial TypeScript port of Clipper2 library
- Includes test suite with test data from original Clipper2
This port is based on the C# version of Clipper2 by Angus Johnson. Original library: https://github.com/AngusJohnson/Clipper2