earstrip é um substituto direto de earcut para triangulação de polígonos em WebGL. Em nosso teste foi cerca de 6 vezes mais rápido com polígonos com milhares de furos, e desenhou muito melhor os polígonos quebrados. Com polígonos de mapa comuns, em x86, a vantagem foi de apenas 1,1–1,2 vezes, longe dos números que o autor mediu em Apple silicon.
yoDEV Testado · 23 de outubro de 2026
Rodamos earstrip 0.2.0 contra earcut 3.2.4 (npm) e earcut.hpp 3.2.4 (C++) sobre os 5,7 milhões de polígonos de OpenStreetMap que o autor publica, em uma VM x86 com Intel Xeon, Node 22, 24 e 26, GCC 13 e Clang 18. Os resultados que relatamos como nossos saem desse teste.
O que é triangulação de polígonos e para que servem earcut e earstrip?
A triangulação de polígonos converte qualquer contorno em um conjunto de triângulos, que é tudo o que uma GPU sabe preencher. Cada edifício, parque ou lago que um mapa web ou uma cena em WebGL desenha passa primeiro por essa etapa. earcut, da Mapbox, é a biblioteca que a maioria dos stacks de mapas web usa para fazer isso: você passa as coordenadas planas e os índices onde cada furo começa, e ela retorna três índices de vértice por triângulo.
earstrip é o triangulador do motor de mapas móveis GLMap. Globus Software a publicou como biblioteca independente em 16 de outubro de 2026 e vem em dois formatos:
- um único arquivo de cabeçalho C++17 (header-only);
- um build de WebAssembly em npm cuja chamada principal recebe exatamente os mesmos argumentos que earcut.
Ela se diferencia de earcut em dois pontos:
- Triangle strips. Recorta as “orelhas” do polígono (ear clipping) seguindo fitas em zigue-zague, assim sua saída nativa precisa de cerca de 1,7 índices por triângulo em lugar de 3.
- Anéis quebrados. Quando os anéis de um polígono se cruzam ou se tocam, ela recorre a uma triangulação de Delaunay restrita (constrained Delaunay) em lugar de retornar os triângulos que tiverem ficado.
A licença é ISC, a mesma de earcut.
Como substituir earcut por earstrip?
Você instala o pacote e muda o import; esse é todo o diff:
npm install earstrip
- import earcut from 'earcut';
+ import earstrip from 'earstrip';
- const triangles = earcut(vertices, holes, dimensions);
+ const triangles = earstrip(vertices, holes, dimensions);
Se seus dados vêm em GeoJSON, earstrip traz seu próprio flatten(). Em nosso teste sua saída foi idêntica à do flatten() de earcut:
import earstrip, { flatten } from 'earstrip';
const { vertices, holes, dimensions } = flatten(geojsonPolygon.coordinates);
const triangles = earstrip(vertices, holes, dimensions);
Três notas práticas do teste:
- Formato do módulo. O pacote é apenas ESM. No Node 22,
require('earstrip')também funcionou para nós graças ao suporterequire(esm)do Node. - Carregamento. O módulo WebAssembly vem incorporado e compila de forma síncrona onde a plataforma permite. Onde não, o README indica fazer
await readyantes da primeira chamada (import { ready } from 'earstrip'). - C++. Copie
include/earstrip.hpppara seu projeto. Precisa de C++17 e nada mais que a biblioteca padrão. O conjunto de testes em C++ do repositório passou completamente em nossa máquina.
earstrip é mais rápido que earcut?
Depende de seus polígonos e da máquina. Usamos os dados de benchmark do próprio autor, com os checksums verificados: extratos de OpenStreetMap do voivodado de Mazóvia (Polônia) e as teselas do mapa mundial de GLMap. O harness foi nosso, contra os pacotes de npm, com uma thread e o melhor de 5 corridas.
| Teste | Autor (Apple M4 Pro) | yoDEV (x86 Xeon) |
|---|---|---|
| 3,74 M polígonos de mapa, chamada drop-in, V8 | 1,44× mais rápido | 1,08–1,19× mais rápido |
Igual, a API mais rápida (direct.batch) |
1,74× mais rápido | 1,21–1,38× mais rápido |
| 56 mil polígonos do mapa mundial, até 11.674 furos em um | 7,4× mais rápido | 5,6–6,0× mais rápido |
| C++ nativo vs earcut.hpp, 3,74 M polígonos | 13% mais rápido | GCC 13: empate · Clang 18: 12% mais rápido |
| C++ nativo, mapa mundial | 6,3× mais rápido | 4,0× mais rápido (GCC 13) |
Com polígonos com muitos furos, a promessa se cumpre. No set mundial, earcut precisou de cerca de 10,2 segundos no Node e earstrip entre 1,7 e 1,9. É justamente o caso onde earcut paga caro por unir cada furo ao contorno, e earstrip manda direto para sua rota de Delaunay os polígonos com mais de 128 anéis.
Com polígonos de mapa comuns, o ganho é muito menor. Em nossa máquina x86 a chamada drop-in foi entre 8 e 19 por cento mais rápida no Node 22, 24 e 26. O README relata 44 por cento para V8 em um M4 Pro.
Em C++ nativo, depende do compilador. Houve empate com GCC e uma vantagem de 12 por cento com Clang, assim o ganho com dados cotidianos parece sensível ao compilador e à CPU. Não investigamos por quê; relatamos o que medimos.
Se seus dados se parecem com os nossos e a velocidade é seu motivo para mudar, faça um benchmark primeiro no hardware onde seu código realmente roda.
O que acontece com os polígonos que se cruzam a si mesmos?
earstrip os desenha bem, e essa parte do que o autor promete foi reproduzida com precisão. Os dados de mapa arredondados para uma grade de teselas costumam terminar com anéis que se cruzam ou se tocam, e o ear clipping assume que isso não acontece. O set principal tem 82 polígonos que as orelhas não podem cortar de forma exata. Neles, os triângulos de earstrip se afastaram do preenchimento correto (even-odd) em 0,15 por cento dos pixels em média, e os de earcut.hpp em 30,7 por cento. O autor relata 0,15 e 31.
Um exemplo mínimo mostra a diferença. Pegue um polígono em forma de gravata que se cruza a si mesmo ([0,0, 10,10, 10,0, 0,10]):
- earcut retornou um único triângulo e preencheu apenas um dos dois lóbulos.
- earstrip retornou dois triângulos que cobrem ambos, e
lastStatus()informouapproximate.
Esse status permite que seu código saiba como cada polígono foi resolvido. Os valores possíveis são exact, constrained, holes-left-out, approximate e refused. No set de 3,74 milhões de polígonos, todos exceto 82 retornaram como exact.
O que são triangle strips e você precisa deles em WebGL?
Um triangle strip é uma lista de índices onde cada novo índice forma um triângulo com os dois anteriores. A GPU desenha n triângulos com cerca de n + 2 índices em lugar de 3n. earstrip escreve fitas de forma nativa:
- 1,66 índices por triângulo tanto no set principal quanto no mundial, contra 3 de uma lista de triângulos normal;
- 1,95 em um set de polígonos quase todos pequenos e simples, onde o ganho é menor.
A chamada drop-in earstrip() converte novamente as fitas em uma lista de triângulos ao estilo earcut, assim você só obtém esse ganho com as outras APIs:
strips()retorna as fitas como estão.- As chamadas
directescrevem o polígono diretamente na memória de WebAssembly e retornam um único index buffer pronto paraTRIANGLE_STRIPem WebGL 2 ou WebGPU. Essa rota foi também a mais rápida em nosso benchmark.
import { strips } from 'earstrip';
const { indices, ends, clockwise } = strips(vertices, holes);
Vale a pena mudar de earcut para earstrip?
Mude se:
- Seus dados têm polígonos com muitos furos (costas, florestas com clareiras, teselas mundiais). A aceleração de 5 a 6 vezes foi reproduzida.
- Você renderiza dados de mapa reais que podem trazer anéis que se cruzam ou se tocam, e já viu erros de preenchimento.
- Você controla o index buffer e pode usar fitas em WebGL 2 ou WebGPU.
Pense duas vezes se:
- Seus polígonos são pequenos e simples e a velocidade é seu único motivo. Em x86 o ganho que medimos foi modesto.
- O tamanho do bundle importa. Tal como publicado, o JavaScript de earstrip mais seu WebAssembly incorporado somou cerca de 41 KB com gzip, contra cerca de 13 KB do código-fonte de earcut não minificado. O número de 27 KB do README corresponde apenas ao binário WebAssembly.
- Você precisa de uma API estável. No momento de publicar esta nota (23 de outubro de 2026), earstrip está na versão 0.2.0, publicada três dias antes. Considere estável a chamada compatível com earcut; o resto pode mudar antes da 1.0.
E você? Que biblioteca você usa hoje para triangular polígonos em seu stack de mapas ou WebGL?
- Velocidade com polígonos complexos
- Que desenhe bem a geometria quebrada
- Index buffers menores (triangle strips)
- Prefiro outra opção (nos conte qual)
Comente abaixo ou, se este artigo chegou a você por email, responda diretamente: sua resposta é publicada aqui.
Relacionado: Node:ffi no Node.js 26.9: como chamar uma biblioteca de C sem compilar um addon nativo