/earcut

The fastest and smallest JavaScript polygon triangulation library for your WebGL apps

Primary LanguageJavaScriptISC LicenseISC

Earcut

The fastest and smallest JavaScript polygon triangulation library. 2.5KB gzipped.

Build Status Coverage Status

The algorithm

The library implements a modified ear slicing algorithm, optimized by z-order curve hashing and extended to handle holes, twisted polygons, degeneracies and self-intersections in a way that doesn't guarantee correctness of triangulation, but attempts to always produce acceptable results for practical data.

It's based on ideas from FIST: Fast Industrial-Strength Triangulation of Polygons by Martin Held and Triangulation by Ear Clipping by David Eberly.

Why another triangulation library?

The aim of this project is to create a JS triangulation library that is fast enough for real-time triangulation in the browser, sacrificing triangulation quality for raw speed and simplicity, while being robust enough to handle most practical datasets without crashing or producing garbage. Some benchmarks using Node 0.12:

(ops/sec) pts earcut libtess poly2tri pnltri
OSM building 15 688,671 50,640 61,501 122,966
dude shape 94 34,806 10,339 8,784 11,172
holed dude shape 104 19,553 8,883 7,494 2,130
complex OSM water 2523 537 77.54 failure failure
huge OSM water 5667 97.79 29.30 failure failure

The original use case it was created for is Mapbox GL, WebGL-based interactive maps.

If you want to get correct triangulation even on very bad data with lots of self-intersections and earcut is not precise enough, take a look at libtess.js.

Usage

var triangles = earcut([[[10,0],[0,50],[60,60],[70,10]]]);
// [[0,50],[10,0],[70,10], [70,10],[60,60],[0,50]]

Input should be an array of rings, where the first is outer ring and others are holes; each ring is an array of points, where each point is of the [x, y] or [x, y, z] form.

Each group of three points in the resulting array forms a triangle.

Alternatively, you can get triangulation results in the form of flat index and vertex arrays by passing true as a second argument to earcut (convenient for uploading results directly to WebGL as buffers):

var triangles = earcut([[[10,0],[0,50],[60,60],[70,10]]], true);
// {vertices: [0,50, 10,0, 70,10, 60,60], indices: [1,0,2, 3,2,1]}

Install

NPM and Browserify:

npm install earcut

Browser builds:

npm install
npm run build-dev # builds dist/earcut.dev.js, a dev version with a source map
npm run build-min # builds dist/earcut.min.js, a minified production build

Running tests:

npm test

Ports to other languages

Changelog

1.4.2 (Mar 18, 2015)
  • Fixed another rare edge case with a tiny hole in a huge polygon.
1.4.1 (Mar 17, 2015)
  • Fixed a rare edge case that led to incomplete triangulation.
1.4.0 (Mar 9, 2015)
  • Fixed indexed output to produce indices not multiplied by dimension and work with any number of dimensions.
1.3.0 (Feb 24, 2015)
  • Added a second argument to earcut that switches output format to flat vertex and index arrays if set to true.
1.2.3 (Feb 10, 2015)
  • Improved performance (especially on recent v8) by avoiding Array push with multiple arguments.
1.2.2 (Jan 27, 2015)
  • Significantly improved performance for polygons with self-intersections (e.g. big OSM water polygons are now handled 2-3x faster)
1.2.1 (Jan 26, 2015)
  • Significantly improved performance on polygons with high number of vertices by using z-order curve hashing for vertice lookup.
  • Slightly improved overall performance with better point filtering.
1.1.0 (Jan 21, 2015)
  • Improved performance on polygons with holes by switching from Held to Eberly hole elimination algorithm
  • More robustness fixes and tests
1.0.1 — 1.0.6 (Jan 20, 2015)
  • Various robustness improvements and fixes.
1.0.0 (Jan 18, 2015)
  • Initial release.