Triangulo Circunscrito
Calculando triângulo circunscrito: o que funciona na prática
O triângulo circunscrito mais relevante no dia a dia de quem trabalha com geometria computacional é o menor triângulo circunscrito a um polígono convexo. Você tem um conjunto de pontos ou um polígono e quer envolver tudo isso com o menor triângulo possível, onde cada lado do triângulo encosta pelo menos em um vértice do polígono. Isso aparece em corte de materiais, layout de peças, simplificação de formas para impressão 3D e até em alguns algoritmos de computer vision. A maioria dos tutoriais na internet para de definir o conceito e vai direto para uma fórmula genérica. O problema real é que o menor triângulo circunscrito a um polígono convexo tem uma propriedade específica: pelo menos um dos lados do triângulo deve ser colinear com um lado do polígono. Isso reduz drasticamente o espaço de busca. Em vez de testar triângulos em qualquer orientação, você só precisa analisar triângulos construídos a partir de cada aresta do polígono como base. Eu já perdi tarde da noite num projeto de otimização de corte de chapas tentando usar uma abordagem genérica de otimização livre. O algoritmo nunca convergia ou achava soluções instáveis. Quando implementei a restrição de colinearidade com as arestas, o tempo de execução caiu de horas para segundos. O polígono era um conjunto de cerca de 200 vértices resultantes de uma nuvem de pontos segmentada, e cada iteração testava todas as arestas, encontrava os dois vértices mais distantes na direção perpendicular e calculava o triângulo correspondente. Simples assim.
O algoritmo passo a passo
Vamos começar pela entrada. Você precisa do polígono convexo, representado por seus vértices em ordem horário ou anti-horário. Se o seu polígono não for convexo, calcule o hull primeiro. Não adianta aplicar o algoritmo direto em concave, porque a propriedade de colinearidade não se sustenta. Passo 1: Para cada aresta do polígono, considere essa aresta como parte de um lado do triângulo circunscrito. O lado do triângulo vai estar sobre a reta que contém essa aresta. Passo 2: Encontrar o vértice do polígono mais distante da reta da aresta atual. Esse vértice define a direção oposta e, junto com a aresta, já começa a montar dois dos três lados do triângulo. A distância pode ser calculada com o produto vetorial: para uma aresta de A até B e um vértice P, a distância é o módulo do produto vetorial de (B-A) e (P-A), dividido pelo comprimento de (B-A).
Passo 3: A partir desse vértice mais distante, você precisa traçar as duas retas que completam o triângulo. Uma delas passa por esse vértice e é paralela à aresta original. A outra passa por esse vértice também, mas na verdade o que você faz é: projete todos os outros vértices sobre a direção perpendicular à aresta, encontre o vértice com a menor projeção (o "mais baixo" do outro lado), e use esse vértice para definir o terceiro lado. Passo 4: Calcule os três pontos de interseção entre essas retas. Esses são os vértices do triângulo circunscrito para aquela aresta base. Calcule a área com a fórmula de Shoelace ou produto vetorial. Passo 5: Repita para todas as arestas e fique com o triângulo de menor área. A complexidade é O(n²) no caso ingênuo, onde n é o número de vértices. Se precisar de performance, existe uma abordagem O(n) usando rotating calipers, mas ela é mais intricada e exige cuidado com casos degenerados.

Caso prático que quase me custou o projeto
Num projeto de tessitura de painéis solares, o polígono representava o contorno de um módulo irregular com aproximadamente 50 vértices após simplificação. O algoritmo O(n²) funcionava, mas eu estava enfrentando um problema estranho: para certas orientações da aresta base, o triângulo calculado tinha área negativa ou vértices que divergiam para infinito. O problema era que, quando dois vértices do polígono tinham exatamente a mesma projeção perpendicular (colineares em relação à direção da aresta), o algoritmo ingênuo tentava construir retas paralelas que nunca se intersectavam de forma estável. A solução foi adicionar um check: antes de calcular as interseções, verificar se o vértice "mais baixo" e o vértice "mais alto" na projeção são únicos. Se houver empate, testar ambos e pegar o que gera o triângulo de menor área. Isso corrigiu os infinitos e estabilizou o resultado. A correção adicionou talvez 10% ao tempo total, mas eliminou crashes e resultados absurdos.
Implementação básica em Python
Se você quer algo funcional para começar, aqui está uma implementação directa. Ela usa a abordagem O(n²) que é suficiente para polígonos com até algumas centenas de vértices. Nota: o código acima é intencionalmente didático. Em produção, você precisaria tratar casos degenerados com mais rigor e provavelmente migrar para uma biblioteca como Shapely ou CGAL se estiver lidando com polígonos complexos no mundo real. Vértices colineares: Se o seu polígono tiver três ou mais vértices colineares consecutivos, o hull simplificado vai mantê-los, mas isso gera arestas de comprimento zero ou quase zero. O produto vetorial para calcular distância fica instável. Remova vértices colineares antes de rodar o algoritmo.
Precisão numérica: Para polígonos com coordenadas muito grandes ou muito pequenas, use tipo float64. Float32 pode gerar erros de arredondamento que fazem o triângulo parecer menor do que realmente é, ou pior, gerar interseções em pontos completamente errados. Não confunda com triângulo circunscrito a uma circunferência: Se o que você quer é o triângulo cujo círculo circunscrito passa por três pontos dados, isso é outro problema completamente diferente — e muito mais simples, porque é puramente geométrico e tem solução analítica directa. O menor triângulo circunscrito a um polígono é um problema de optimização, não de construção geométrica pura. Se o seu polígono tem muitos vértices e você precisa de velocidade, a abordagem rotating calipers reduz para O(n). Mas ela exige uma implementação cuidadosa das três pinças que rotam simultaneamente. Para a maioria dos casos práticos, o O(n²) roda rápido o suficiente e é muito mais fácil de debugar quando algo dá errado.

Uma última coisa: se o seu objectivo é mesmo o menor triângulo em perímetro e não em área, o algoritmo muda. O perímetro mínimo não tem a mesma propriedade de colinearidade com arestas, e você precisa de uma formulação diferente. Já vi gente usar o código de área para perímetro e obter resultados visivelmente errados. Verifique sempre se a métrica que está a optimizar é a que você realmente precisa.
Galeria
-
Triangulo Inscrito Em Uma Circunferencia -
Circulo De Um Triangulo Quadro Decorativo Do Círculo Do Triângulo -
Triangulo Inscrito Resuelto:Los Catetos De Un Triángulo Rectángulo