earcut 3.0.2 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  ISC License
2
2
 
3
- Copyright (c) 2024, Mapbox
3
+ Copyright (c) 2026, Mapbox
4
4
 
5
5
  Permission to use, copy, modify, and/or distribute this software for any purpose
6
6
  with or without fee is hereby granted, provided that the above copyright notice
package/README.md CHANGED
@@ -1,16 +1,31 @@
1
- ## Earcut
1
+ # Earcut
2
2
 
3
- The fastest and smallest JavaScript polygon triangulation library. 3KB gzipped.
3
+ The fastest and smallest JavaScript **polygon triangulation** library. 3.5KB gzipped.
4
+
5
+ It is designed to be fast enough for real-time triangulation in the browser,
6
+ sacrificing triangulation quality for raw speed and simplicity,
7
+ while being robust enough to handle most practical datasets without crashing or producing garbage.
8
+ Originally built for [Mapbox GL JS](https://www.mapbox.com/mapbox-gljs) (WebGL-based interactive maps),
9
+ it's now also used by [Three.js](https://threejs.org/) and many other projects.
10
+
11
+ ![Earcut triangulation example](earcut.png)
4
12
 
5
13
  [![Node](https://github.com/mapbox/earcut/actions/workflows/node.yml/badge.svg)](https://github.com/mapbox/earcut/actions/workflows/node.yml)
6
14
  [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/mapbox/earcut.svg)](http://isitmaintained.com/project/mapbox/earcut "Average time to resolve an issue")
7
15
  [![Percentage of issues still open](http://isitmaintained.com/badge/open/mapbox/earcut.svg)](http://isitmaintained.com/project/mapbox/earcut "Percentage of issues still open")
8
16
  [![](https://img.shields.io/badge/simply-awesome-brightgreen.svg)](https://github.com/mourner/projects)
9
17
 
10
- #### The algorithm
18
+ ## Usage
19
+
20
+ ```js
21
+ import earcut from 'earcut';
22
+ const triangles = earcut([10,0, 0,50, 60,60, 70,10]); // returns [1,0,3, 3,2,1]
23
+ ```
24
+
25
+ ## Algorithm
11
26
 
12
27
  The library implements a modified ear slicing algorithm,
13
- optimized by [z-order curve](http://en.wikipedia.org/wiki/Z-order_curve) hashing
28
+ optimized by [z-order curve](http://en.wikipedia.org/wiki/Z-order_curve) and spatial hashing
14
29
  and extended to handle holes, twisted polygons, degeneracies and self-intersections
15
30
  in a way that doesn't _guarantee_ correctness of triangulation,
16
31
  but attempts to always produce acceptable results for practical data.
@@ -19,39 +34,59 @@ It's based on ideas from
19
34
  [FIST: Fast Industrial-Strength Triangulation of Polygons](http://www.cosy.sbg.ac.at/~held/projects/triang/triang.html) by Martin Held
20
35
  and [Triangulation by Ear Clipping](http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf) by David Eberly.
21
36
 
22
- #### Why another triangulation library?
37
+ ## Performance
23
38
 
24
- The aim of this project is to create a JS triangulation library
25
- that is **fast enough for real-time triangulation in the browser**,
26
- sacrificing triangulation quality for raw speed and simplicity,
27
- while being robust enough to handle most practical datasets without crashing or producing garbage.
28
- Some benchmarks using Node 0.12:
39
+ Earcut is heavily optimized for its primary workload triangulating polygons from
40
+ [Mapbox Vector Tiles](https://github.com/mapbox/vector-tile-spec). On a representative
41
+ benchmark of **119,680 real-world polygons** (1.9M vertices) drawn from a window of map tiles
42
+ through zooms 4–16, it triangulates the whole set in **~480 ms** on a Macbook Pro M1 Pro (2021).
43
+ You can run the benchmark yourself with `npm run bench`.
44
+
45
+ ## Robustness
29
46
 
30
- (ops/sec) | pts | earcut | libtess | poly2tri | pnltri | polyk
31
- ------------------| ---- | --------- | -------- | -------- | --------- | ------
32
- OSM building | 15 | _795,935_ | _50,640_ | _61,501_ | _122,966_ | _175,570_
33
- dude shape | 94 | _35,658_ | _10,339_ | _8,784_ | _11,172_ | _13,557_
34
- holed dude shape | 104 | _28,319_ | _8,883_ | _7,494_ | _2,130_ | n/a
35
- complex OSM water | 2523 | _543_ | _77.54_ | failure | failure | n/a
36
- huge OSM water | 5667 | _95_ | _29.30_ | failure | failure | n/a
47
+ Earcut does **not** guarantee a correct triangulation on arbitrary input — it trades quality
48
+ for speed, aiming to always produce an acceptable result on practical data without crashing or
49
+ emitting garbage. The input is assumed to be a valid polygon: rings that don't self-cross or
50
+ overlap, holes that stay inside the outer ring, and no duplicate or zero-length edges. On input
51
+ that breaks these assumptions, the result can be noticeably wrong — overlapping triangles, gaps,
52
+ or triangles outside the polygon. If correctness matters, clean your input first; for a
53
+ guaranteed-correct triangulation even on bad data, see
54
+ [libtess.js](https://github.com/brendankenny/libtess.js) (slower and larger).
37
55
 
38
- The original use case it was created for is [Mapbox GL](https://www.mapbox.com/mapbox-gl), WebGL-based interactive maps.
56
+ The output is also not _conforming_ a vertex may land in the middle of another triangle's edge
57
+ (a T-junction). This is harmless for rendering but can break navmesh or FEM use; if you need a
58
+ conforming mesh, [remove T-junctions in a post-process](https://github.com/mapbox/earcut/issues/74#issuecomment-4826113682).
39
59
 
40
- If you want to get correct triangulation even on very bad data with lots of self-intersections
41
- and earcut is not precise enough, take a look at [libtess.js](https://github.com/brendankenny/libtess.js).
60
+ ## Install
42
61
 
43
- #### Usage
62
+ Install with NPM: `npm install earcut`, then import as a module:
44
63
 
45
64
  ```js
46
- const triangles = earcut([10,0, 0,50, 60,60, 70,10]); // returns [1,0,3, 3,2,1]
65
+ import earcut, {flatten, deviation} from 'earcut';
66
+ ```
67
+
68
+ Or use as a module directly in the browser with [jsDelivr](https://www.jsdelivr.com/esm):
69
+
70
+ ```html
71
+ <script type="module">
72
+ import earcut from 'https://cdn.jsdelivr.net/npm/earcut/+esm';
73
+ </script>
74
+ ```
75
+
76
+ Alternatively, there's a UMD browser bundle with an `earcut` global variable (exposing the main function as `earcut.default`):
77
+
78
+ ```html
79
+ <script src="https://cdn.jsdelivr.net/npm/earcut/dist/earcut.min.js"></script>
47
80
  ```
48
81
 
49
- Signature: `earcut(vertices[, holes, dimensions = 2])`.
82
+ ## API
83
+
84
+ ### `earcut(vertices[, holes, dimensions = 2])`
50
85
 
51
86
  * `vertices` is a flat array of vertex coordinates like `[x0,y0, x1,y1, x2,y2, ...]`.
52
87
  * `holes` is an array of hole _indices_ if any
53
88
  (e.g. `[5, 8]` for a 12-vertex input would mean one hole with vertices 5&ndash;7 and another with 8&ndash;11).
54
- * `dimensions` is the number of coordinates per vertex in the input array (`2` by default). Only two are used for triangulation (`x` and `y`), and the rest are ignored.
89
+ * `dimensions` is the number of coordinates per vertex in the input array (`2` by default). Earcut is a **2D** algorithm: only `x` and `y` are used for triangulation, and any extra coordinates are ignored (3D data is treated as projected onto the XY plane).
55
90
 
56
91
  Each group of three vertex indices in the resulting array forms a triangle.
57
92
 
@@ -67,55 +102,35 @@ earcut([10,0,1, 0,50,2, 60,60,3, 70,10,4], null, 3);
67
102
 
68
103
  If you pass a single vertex as a hole, Earcut treats it as a Steiner point.
69
104
 
70
- 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).
105
+ Output triangles always have a consistent **winding order** regardless of the input polygon's winding &mdash; counter-clockwise in a y-up coordinate system (clockwise in y-down/screen space). If you need the opposite orientation (e.g. for back-face culling or normals in 3D), call `.reverse()` on the result.
106
+
107
+ ### `flatten(data)`
71
108
 
72
109
  If your input is a multi-dimensional array (e.g. [GeoJSON Polygon](http://geojson.org/geojson-spec.html#polygon)),
73
- you can convert it to the format expected by Earcut with `earcut.flatten`:
110
+ you can convert it to the format expected by Earcut with `flatten`:
74
111
 
75
112
  ```js
76
- const data = earcut.flatten(geojson.geometry.coordinates);
113
+ const data = flatten(geojson.geometry.coordinates);
77
114
  const triangles = earcut(data.vertices, data.holes, data.dimensions);
78
115
  ```
79
116
 
80
- After getting a triangulation, you can verify its correctness with `earcut.deviation`:
117
+ ### `deviation(vertices, holes, dimensions, triangles)`
118
+
119
+ After getting a triangulation, you can verify its correctness with `deviation`:
81
120
 
82
121
  ```js
83
- const deviation = earcut.deviation(vertices, holes, dimensions, triangles);
122
+ const d = deviation(vertices, holes, dimensions, triangles);
84
123
  ```
85
124
 
86
125
  Returns the relative difference between the total area of triangles and the area of the input polygon.
87
126
  `0` means the triangulation is fully correct.
88
127
 
89
- #### Install
90
-
91
- Install with NPM: `npm install earcut`, then import as a module:
92
-
93
- ```js
94
- import earcut from 'earcut';
95
- ```
96
-
97
- Or use as a module directly in the browser with [jsDelivr](https://www.jsdelivr.com/esm):
98
-
99
- ```html
100
- <script type="module">
101
- import earcut from 'https://cdn.jsdelivr.net/npm/earcut/+esm';
102
- </script>
103
- ```
104
-
105
- Alternatively, there's a UMD browser bundle with an `earcut` global variable (exposing the main function as `earcut.default`):
106
-
107
- ```html
108
- <script src="https://cdn.jsdelivr.net/npm/earcut/dist/earcut.min.js"></script>
109
- ```
110
-
111
- ![](https://cloud.githubusercontent.com/assets/25395/5778431/e8ec0c10-9da3-11e4-8d4e-a2ced6a7d2b7.png)
112
-
113
- #### Ports to other languages
128
+ ## Ports to other languages
114
129
 
115
130
  - [mapbox/earcut.hpp](https://github.com/mapbox/earcut.hpp) (C++11)
116
131
  - [JaffaKetchup/dart_earcut](https://github.com/JaffaKetchup/dart_earcut) (Dart)
117
132
  - [earcut4j/earcut4j](https://github.com/earcut4j/earcut4j) (Java)
118
- - [the3deers/earcut-java](https://github.com/the3deers/earcut-java) (Java)
119
133
  - [Larpon/earcut](https://github.com/Larpon/earcut) (V)
120
- - [Cawfree/earcut-j](https://github.com/Cawfree/earcut-j) (Java, outdated)
121
134
  - [measuredweighed/SwiftEarcut](https://github.com/measuredweighed/SwiftEarcut) (Swift)
135
+ - [goswinr/Earcut](https://github.com/goswinr/Earcut/)(F# / .NET)
136
+ - [tenyoru/earcut.zig](https://github.com/tenyoru/earcut.zig) (Zig)