Skip to content

Port upstream earcut v3.1.0–v3.2.3 (radix sort, block-bbox index, Delaunay refinement)#23

Merged
MichaConrad merged 5 commits into
mainfrom
copilot/port-latest-changes
Jul 8, 2026
Merged

Port upstream earcut v3.1.0–v3.2.3 (radix sort, block-bbox index, Delaunay refinement)#23
MichaConrad merged 5 commits into
mainfrom
copilot/port-latest-changes

Conversation

Copilot AI commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Ports all upstream mapbox/earcut changes from issues #14#21 to the C#/.NET repository. Covers algorithm performance improvements, a new public Delaunay refinement API, and several correctness fixes.

Core algorithm changes

  • EarcutLinked: removed the 3-pass recursion system; replaced with filteredOut/cured flags
  • FilterPoints: backward-sweep after node removal; sets s_filteredOut [ThreadStatic] flag
  • IsEarHashed: simplified from interleaved bidirectional scan to two sequential while loops; area check hoisted to caller
  • Intersects: added includeBoundary parameter; CureLocalIntersections now uses boundary=false for stricter crossing test
  • IsValidDiagonal: dropped prev.I check; added zeroLength guard
  • IntersectsPolygon: bbox short-circuit before segment tests

Performance

  • Radix sort (4-pass LSD over 8-bit digits) replaces merge sort in IndexCurve — faster for large polygons
  • Block-bbox index for FindHoleBridge — reduces O(n) scan to O(n/K) by partitioning segments into fixed-width blocks; RemoveNode maintains the index via GrowBlock when s_indexActive

New public API — Earcut.Refine()

Lawson-flip Delaunay refinement pass on an existing triangulation. Uses an undirected-edge hash with a generation counter to avoid table clears, and a 1e-13 * s² tolerance in InCircle to prevent infinite flip loops on near-cocircular quads.

int[] triangles = Earcut.Triangulate(vertices, holes);
Earcut.Refine(triangles, vertices); // legalise interior edges in-place

New fixtures & tests

  • 7 new test fixtures: earcut, self-tangent-1/2/3/4, issue147, water-huge3
  • Updated expected.json with corrected triangle counts/errors across all fixtures
  • Refine correctness tests + BlockIndexCollinear regression test
  • TriangulateWaterHuge3 and RefineWaterHuge3 benchmarks
  • --refine flag added to the viz app

Thread safety

All mutable scratch (sort arrays, block-bbox index, refine hash table) uses [ThreadStatic], matching the JS module-level state model. Node arrays are cleared after use to avoid holding GC references.

Copilot AI changed the title [WIP] Port latest changes from MichaCo/Earcut Port upstream earcut v3.1.0–v3.2.3 (radix sort, block-bbox index, Delaunay refinement) Jul 8, 2026
Copilot AI requested a review from MichaConrad July 8, 2026 15:26
@MichaConrad MichaConrad marked this pull request as ready for review July 8, 2026 17:21
@MichaConrad MichaConrad merged commit fc1bcb9 into main Jul 8, 2026
2 checks passed
@MichaConrad MichaConrad deleted the copilot/port-latest-changes branch July 8, 2026 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment