Earstrip vs earcut: testamos a triangulação de 3,7 milhões de polígonos do OpenStreetMap ✅ yoDEV Tested

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.

:white_check_mark: 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 suporte require(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 ready antes da primeira chamada (import { ready } from 'earstrip').
  • C++. Copie include/earstrip.hpp para 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() informou approximate.

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 direct escrevem o polígono diretamente na memória de WebAssembly e retornam um único index buffer pronto para TRIANGLE_STRIP em 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?

O que o faria mudar de triangulador?
  • Velocidade com polígonos complexos
  • Que desenhe bem a geometria quebrada
  • Index buffers menores (triangle strips)
  • Prefiro outra opção (nos conte qual)
0 votantes

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