Mapbox Earcut Python Bindings
mapbox-earcut provides Python bindings for the high-performance Mapbox Earcut C++ polygon triangulation library. It is currently at version 2.0.0 and sees active maintenance with releases addressing new Python versions and build system improvements.
Warnings
- breaking Starting with v2.0.0, support for the Python Limited API was removed. This means wheels are no longer binary compatible across different major Python versions, and new wheels will be required for each new Python release (e.g., Python 3.12, 3.13).
- breaking Version 1.0.2 introduced Python 3.9 as the minimum required version. It also dropped support for 32-bit Linux systems, aligning with NumPy's reduced wheel support for such platforms.
- gotcha The `earcut` function expects input `data` as a NumPy array of shape `(N, D)` where N is the number of vertices and D is the dimension (e.g., 2 for (x,y)). The `hole_indices` argument is an array of integer indices specifying where each hole polygon begins within the `data` array.
Install
-
pip install mapbox-earcut
Imports
- earcut
from mapbox_earcut import earcut
Quickstart
import numpy as np
from mapbox_earcut import earcut
# Define a polygon with an outer ring and an inner hole
# Vertices are flat: [x0, y0, x1, y1, ...]
# Outer ring (0-3): [10,0], [0,50], [60,60], [70,10]
# Hole (4-7): [30,10], [30,30], [20,20], [20,10]
# The hole_indices array specifies where each hole's vertices start in the `data` array.
data = np.array([
[10,0], [0,50], [60,60], [70,10],
[30,10], [30,30], [20,20], [20,10]
]).flatten() # Earcut expects a flat array of coordinates
# hole_indices tells earcut where each hole polygon starts in the data array.
# In this example, the hole starts at index 4 (since it's a flat array, this is the 5th vertex pair, or 8th element).
# No, the example from github passes non-flattened array, and `[4]` refers to the 4th *point* index.
# So, data should *not* be flattened prior to passing, it seems the C++ binding does that.
data_points = np.array([
[10,0], [0,50], [60,60], [70,10],
[30,10], [30,30], [20,20], [20,10]
])
# `data_points` is a (N, 2) array.
# `hole_indices` is an array of indices where holes start in `data_points`.
# `dimensions` is the number of dimensions per point (e.g., 2 for x,y).
result_indices = earcut(data_points, [4], 2)
# The result is a flat array of vertex indices forming triangles.
# For example, [0, 1, 2, 0, 2, 3, ...] means triangle 0 is (data_points[0], data_points[1], data_points[2]).
triangles = result_indices.reshape(-1, 3)
print(f"Input points:\n{data_points}")
print(f"Resulting triangle indices (flat):\n{result_indices}")
print(f"Resulting triangles (reshaped):\n{triangles}")