earcut
The fastest and smallest JavaScript polygon triangulation library for your WebGL apps
Top Related Projects
A very fast geospatial point clustering library for browsers and Node.
Slice GeoJSON into vector tiles on the fly in the browser
Quick Overview
Earcut is a fast, small, and robust polygon triangulation library for JavaScript and TypeScript. It is designed to be a high-performance, low-overhead solution for triangulating complex polygons, making it suitable for use in various geospatial and graphics applications.
Pros
- High Performance: Earcut is known for its exceptional speed, making it a great choice for real-time applications that require fast polygon triangulation.
- Robustness: The library is designed to handle complex and even self-intersecting polygons, ensuring reliable and accurate triangulation results.
- Small Footprint: Earcut has a small file size, making it suitable for use in web-based and mobile applications where file size is a concern.
- Cross-Platform Compatibility: Earcut is written in JavaScript and can be used in both browser-based and server-side (Node.js) environments.
Cons
- Limited Functionality: Earcut is primarily focused on polygon triangulation and does not provide additional features like polygon clipping or boolean operations.
- Lack of Documentation: The project's documentation could be more comprehensive, which may make it challenging for new users to get started.
- Potential Precision Issues: In some cases, Earcut may produce triangulation results that are not pixel-perfect, which could be a concern for certain graphics applications.
- No Official Maintenance: The project is not actively maintained by the Mapbox team, which could be a concern for long-term usage and potential bug fixes.
Code Examples
Here are a few examples of how to use Earcut in your JavaScript or TypeScript projects:
import earcut from 'earcut';
// Triangulate a simple polygon
const polygon = [[0, 0], [10, 0], [10, 10], [0, 10]];
const triangles = earcut(polygon);
console.log(triangles); // Output: [0, 1, 3, 1, 2, 3]
import earcut from 'earcut';
// Triangulate a polygon with holes
const polygon = [
[0, 0], [10, 0], [10, 10], [0, 10], // Outer ring
[2, 2], [4, 2], [4, 4], [2, 4] // Inner ring
];
const triangles = earcut(polygon, [8]); // Pass the hole indices
console.log(triangles); // Output: [0, 1, 3, 1, 2, 3, 4, 5, 7, 5, 6, 7]
import earcut from 'earcut';
// Triangulate a polygon with custom data
interface PolygonPoint {
x: number;
y: number;
data: any;
}
const polygon: PolygonPoint[] = [
{ x: 0, y: 0, data: 'A' },
{ x: 10, y: 0, data: 'B' },
{ x: 10, y: 10, data: 'C' },
{ x: 0, y: 10, data: 'D' }
];
const triangles = earcut(
polygon.flatMap(p => [p.x, p.y]),
null,
2
);
console.log(triangles.map(i => polygon[i]));
// Output: [
// { x: 0, y: 0, data: 'A' },
// { x: 10, y: 0, data: 'B' },
// { x: 0, y: 10, data: 'D' }
// ]
Getting Started
To use Earcut in your project, you can install it via npm:
npm install earcut
Then, you can import the earcut
function and use it to triangulate your polygons:
import earcut from 'earcut';
// Triangulate a polygon
const polygon = [[0, 0], [10, 0], [10, 10], [0, 10]];
const triangles = earcut(polygon);
// Use the triangles
Competitor Comparisons
A very fast geospatial point clustering library for browsers and Node.
Pros of Supercluster
- Supercluster is a fast geospatial clustering library for rendering large datasets on maps.
- It provides a simple and efficient way to cluster large sets of points on a map, making it suitable for use in web applications.
- Supercluster supports a variety of input data formats, including GeoJSON, and can be easily integrated with popular mapping libraries like Mapbox GL JS.
Cons of Supercluster
- Supercluster is primarily focused on clustering points, and may not be as well-suited for other types of geospatial data, such as polygons or lines.
- The library can be more complex to set up and configure compared to simpler solutions like Earcut.
- Supercluster may have a higher memory footprint than Earcut, especially for very large datasets.
Code Comparison
Earcut:
const earcut = require('earcut');
const data = [0, 0, 10, 0, 10, 10, 0, 10];
const holes = [];
const indices = earcut(data, holes, 2);
Supercluster:
const Supercluster = require('supercluster');
const index = Supercluster({
radius: 40,
maxZoom: 16
});
index.load([
{ type: 'Feature', geometry: { type: 'Point', coordinates: [0, 0] } },
{ type: 'Feature', geometry: { type: 'Point', coordinates: [10, 10] } }
]);
const clusters = index.getClusters([-180, -90, 180, 90], 1);
Slice GeoJSON into vector tiles on the fly in the browser
Pros of GeoJSON-VT
- Optimizes GeoJSON data for fast rendering on the client-side, reducing the need for server-side processing.
- Provides a simple and efficient API for querying and rendering vector tiles.
- Supports advanced features like tile clipping, simplification, and indexing.
Cons of GeoJSON-VT
- Requires the input data to be in GeoJSON format, which may not be suitable for all use cases.
- May not be as performant as more specialized vector tile formats like Mapbox Vector Tiles.
- Lacks some of the advanced features and customization options available in other vector tile libraries.
Code Comparison
GeoJSON-VT:
var tileIndex = geojsonvt(data, {
maxZoom: 14,
tolerance: 3,
extent: 4096,
buffer: 64
});
var tile = tileIndex.getTile(12, 656, 1583);
Earcut:
var triangles = earcut(data.coordinates[0], null, 2);
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Earcut
The fastest and smallest JavaScript polygon triangulation library. 3KB gzipped.
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 | polyk |
---|---|---|---|---|---|---|
OSM building | 15 | 795,935 | 50,640 | 61,501 | 122,966 | 175,570 |
dude shape | 94 | 35,658 | 10,339 | 8,784 | 11,172 | 13,557 |
holed dude shape | 104 | 28,319 | 8,883 | 7,494 | 2,130 | n/a |
complex OSM water | 2523 | 543 | 77.54 | failure | failure | n/a |
huge OSM water | 5667 | 95 | 29.30 | failure | failure | n/a |
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
const triangles = earcut([10,0, 0,50, 60,60, 70,10]); // returns [1,0,3, 3,2,1]
Signature: earcut(vertices[, holes, dimensions = 2])
.
vertices
is a flat array of vertex coordinates like[x0,y0, x1,y1, x2,y2, ...]
.holes
is an array of hole indices if any (e.g.[5, 8]
for a 12-vertex input would mean one hole with vertices 5–7 and another with 8–11).dimensions
is the number of coordinates per vertex in the input array (2
by default). Only two are used for triangulation (x
andy
), and the rest are ignored.
Each group of three vertex indices in the resulting array forms a triangle.
// triangulating a polygon with a hole
earcut([0,0, 100,0, 100,100, 0,100, 20,20, 80,20, 80,80, 20,80], [4]);
// [3,0,4, 5,4,0, 3,4,7, 5,0,1, 2,3,7, 6,5,1, 2,7,6, 6,1,2]
// triangulating a polygon with 3d coords
earcut([10,0,1, 0,50,2, 60,60,3, 70,10,4], null, 3);
// [1,0,3, 3,2,1]
If you pass a single vertex as a hole, Earcut treats it as a Steiner point.
Note that Earcut is a 2D triangulation algorithm, and handles 3D data as if it was projected onto the XY plane (with Z component ignored).
If your input is a multi-dimensional array (e.g. GeoJSON Polygon),
you can convert it to the format expected by Earcut with earcut.flatten
:
const data = earcut.flatten(geojson.geometry.coordinates);
const triangles = earcut(data.vertices, data.holes, data.dimensions);
After getting a triangulation, you can verify its correctness with earcut.deviation
:
const deviation = earcut.deviation(vertices, holes, dimensions, triangles);
Returns the relative difference between the total area of triangles and the area of the input polygon.
0
means the triangulation is fully correct.
Install
Install with NPM: npm install earcut
, then import as a module:
import earcut from 'earcut';
Or use as a module directly in the browser with jsDelivr:
<script type="module">
import earcut from 'https://cdn.jsdelivr.net/npm/earcut/+esm';
</script>
Alternatively, there's a UMD browser bundle with an earcut
global variable (exposing the main function as earcut.default
):
<script src="https://cdn.jsdelivr.net/npm/earcut/dist/earcut.min.js"></script>
Ports to other languages
- mapbox/earcut.hpp (C++11)
- JaffaKetchup/dart_earcut (Dart)
- earcut4j/earcut4j (Java)
- the3deers/earcut-java (Java)
- Larpon/earcut (V)
- Cawfree/earcut-j (Java, outdated)
- measuredweighed/SwiftEarcut (Swift)
Top Related Projects
A very fast geospatial point clustering library for browsers and Node.
Slice GeoJSON into vector tiles on the fly in the browser
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot