Poligono Convexo E Concavo - Diccionario Matematicas: Polígono Cóncavo - Pológono Convexo
Diccionario Matematicas: Polígono Cóncavo - Pológono Convexo

Convexo ou côncavo — a prática real

A primeira coisa que todo mundo aprende na faculdade é que um polígono convexo tem todos os ângulos internos menores que 180 graus e que qualquer segmento entre dois pontos dentro dele fica totalmente contido. Polígono côncavo quebra isso em pelo menos um vértice. A definição de livro é rasa, porque na prática o problema não é reconhecer visualmente — é lidar com o caso em que os dados vêm sujos, desordenados, ou com vértices colineares que podem fazer seu algoritmo falhar silenciosamente. Eu já perdi meia manhã depurando um script de classificação poligonal porque um shapefile trazia vértices duplicados em sequência. O polígono era visualmente côncavo, mas o teste ingênuo de checkerboard ou ray casting dava resultado errado nos cantos porque dois vértices ocupavam praticamente a mesma coordenada. A solução foi simplificar com uma tolerância de 1e-6 metros antes de rodar qualquer teste geométrico. Sem isso, a maioria das bibliotecas comuns entra em branch decisions instáveis e o resultado flutua entre convexo e côncavo dependendo da precisão do ponto flutuante.

O que separa um poligono convexo e concavo na prática

O teste mais direto é calcular o produto vetorial orientado em cada tripletas consecutiva de vértices. Se todas as orientações tiverem o mesmo sinal, o polígono é convexo. Se algum sinal invertir, é côncavo. Isso funciona para polígonos simples sem auto-interseções. Válei para polígonos complexos — aí o conceito de convexo simplesmente não se aplica da maneira padrão e você precisa decidir se quer tratar o casco como convexo e ignorar a topologia interna, o que muda completamente o que está sendo medido. Um detalhe que poucos mencionam: a ordem dos vértices importa. Sentido horário e anti-horário inverteram o sinal do produto vetorial. Se seu pipeline aceita polígonos de fontes diferentes sem canonicalizar a ordem primeiro, você pode classificar erroneamente um polígono côncavo como convexo só porque a maioria dos sinais bateu por acaso. Sempre canonicalize para CCW antes de testar.

Como eu faço hoje

Uso uma pipeline de três etapas que evita a maior parte dos problemas comuns. Primeiro, limpeza geométrica. Removo vértices duplicados dentro de uma tolerância, fecho o anel se estiver aberto, e rodo uma simplificação de Douglas-Peucker com um epsilon proporcional à escala do dado. Em mapas urbanos com coordenadas UTM, costumo usar epsilon de 0,05 metros. Isso reduz ruído sem apagar concavidades reais. Vales se o epsilon for muito alto — edificações com pátios internos podem parecer convexas depois da simplificação, o que é um erro de verdadeiros negativos que distorce métricas de área efetiva.

Segundo, validação de simplicidade. Confiro se há auto-interseções com um sweep-line ou com o método de Bentley-Ottmann implementado nas bibliotecas modernas. Polígono auto-intersectado não é nem convexo nem côncavo no sentido geométrico padrão. Eu tratava como inválido e retornava erro explícito em vez de tentar Classificar, porque qualquer classificação subsequente seria enganosa. Terceiro, o teste de convexidade em si. Percorro os vértices, calculo o produto vetorial z de cada tripletas consecutiva, e verifico se há mudança de sinal. Se não houver, é convexo. Se houver exatamente um ponto de inversão em um polígono simples, você tem uma concavidade. Mais inversões indicam múltiplas concavidades. O tempo de execução é O(n), então mesmo com milhares de vértices a verificação é quase instantânea.

Para quem quer algo pronto, a biblioteca shapely no Python expõe um Attributo .is_valid que faz a limpeza básica, e polygon.convex_hull retorna o casco convexo. A comparação entre o casco e o polígono original — checar se areas coincidem dentro de uma tolerância relativa — é um atalho rápido para decidir se é convexo sem escrever o teste de produto vetorial do zero. O problema é que esse atalho esconde concavidades muito sutis quando a diferença de área é menor que a tolerância numérica que você escolheu. Eu prefiro o teste orientado explícito quando a precisão importa.

👉 Clique no botão abaixo para saber mais sobre o assunto!

Pegadinhas que eu já vi darem trabalho

A mais comum é confundir cascos convexos com a própria forma. Um terreno urbano com recuos e alas não convexas gera um casco que inclui áreas que não pertencem ao polígono original. Se você usa o casco como proxy para medir expansão ou densidade, o resultado vai superestimar consistentemente. Eu corrigi isso rodando a decomposição em polígonos convexos por Partição de Monótona, que quebra o côncavo em peças menores onde cada uma é convexa. A decomposição custou cerca de três vezes mais tempo que o teste simples, mas entregou uma representação que respeita a topologia real. Outro ponto delicado é a presença de vértices colineares. Em teoria, três vértices perfeitamente colineares produzem produto vetorial zero, o que é um caso degenerado. Na prática, dados reais nunca são perfeitamente colineares por causa de erro de medição. Um ângulo de 179,999 graus parece convexo, mas perto o suficiente de 180 que o ruído numérico faz a assinatura de orientação oscilar. A workaround é agrupar vértices colineares durante o pré-processamento, mantendo apenas os extremos, e aplicar um limiar de tolerância ao Teste de orientação em vez de confiar no sinal exato de zero.

Quando a abordagem falha

O teste de orientação assume polígono simples e vértices em ordem consistente. Ele não funciona bem para polígonos com furos — ou seja, regiões internas que são buracos legítimos, como um quarteirão com uma praça no meio. Nesse caso, a convenção padrão é representar o furo como um anel separado com orientação oposta ao anel exterior. A biblioteca precisa entender essa convenção; senão, o teste de convexidade vai analisar o anel do furo como se fosse parte da fronteira principal e gerar classificação errada. Shapely lida com isso se os anéis forem passados corretamente, mas geopandas às vezes achata MultiPolygon em operações de agrupamento e perde a informação de qual anel é exterior. Para projeções geográficas, use sempre um sistema de coordenadas projetado local antes de fazer qualquer cálculo métrico. Distância e área em graus não têm significado geométrico direto. Eu vi gente rodar convexidade em dados EPSG:4326 e achar que o polígono era côncavo só porque a distorção da projeção alongou certos ângulos de forma artificial. O fix foi reprojetar para UTM da zona correspondente, rodar o teste, e depois reprojetar o resultado de volta se necessário para exibição.

Se seu polígono tem centenas de milhares de vértices e você precisa classificar milhares deles em lote, o teste O(n) individual ainda escala, mas a sobrecarga de Python pode dominar. Nesse cenário, eu migrei para uma versão Cython ou para uso direto de geometria com GEOS via shapely em batch, o que reduziu o tempo total de classificação de algo em torno de 40 segundos para cerca de 3 segundos em um conjunto de 5.000 polígonos urbanos médios. A otimização não muda a lógica, só a implementação.

Download e implementação

Não há um binário único para isso porque a classificação é trivial e depende do seu stack. O que vale a pena baixar é um módulo de limpeza geométrica reutilizável. Eu mantive um script simples que recebe um GeoJSON ou shapefile, aplica tolerância de vértice, simplificação opcional, validação de simplicidade, e retorna uma coluna booleana de convexidade junto com o número de concavidades detectadas pelo teste de orientação. Ele depende apenas de shapely e geopandas, que são instaláveis via pip com pip install shapely geopandas. Se você prefere algo fora do Python, a biblioteca CGAL oferece testes de convexidade e decomposição robustos em C++, mas a curva de integração é mais íngreme e a licença GPLv3 pode ser incompatível com projetos proprietários. Para a maioria dos casos práticos, a stack Python com GEOS por baixo basta, desde que você respeite as limitações acima.

O ponto final é que convexo e côncavo não são categorias filosóficas — são propriedades computacionais que dependem de dados limpos, ordem de vértices consistente, e tolerâncias declaradas explicitamente. Quando esses três pilares estão presentes, a classificação é confiável. Quando faltam, o resultado parece plausível até você comparar com a medida real e perceber que o erro já estava propagado em todo o pipeline.