Qual é a maneira mais simples de calcular a curvatura principal de um triângulo de malha?

19

Eu tenho uma malha e, na região em torno de cada triângulo, quero calcular uma estimativa das principais direções da curvatura. Eu nunca fiz esse tipo de coisa antes e a Wikipedia não ajuda muito. Você pode descrever ou apontar para um algoritmo simples que pode me ajudar a calcular essa estimativa?

Suponha que eu conheça posições e normais de todos os vértices.

ap_
fonte

Respostas:

24

Quando eu precisava de uma estimativa da curvatura da malha para um shader de pele, o algoritmo em que acabei decidindo foi o seguinte:

Primeiro, calculei uma curvatura escalar para cada aresta da malha. Se a aresta tem as posições p1,p2 e normais n1,n2 , calculei sua curvatura como:

curvature=(n2n1)(p2p1)|p2p1|2

Isso calcula a diferença nas normais, projetadas ao longo da borda, como uma fração do comprimento da borda. (Veja abaixo como criei esta fórmula.)

Então, para cada vértice, observei as curvaturas de todas as arestas que o tocavam. No meu caso, eu só queria uma estimativa escalar de "curvatura média", então acabei tomando a média geométrica dos valores absolutos de todas as curvaturas de arestas em cada vértice. Para o seu caso, você pode encontrar as curvaturas mínima e máxima e considerar essas arestas como as principais direções da curvatura (talvez ortogonalizá-las com o vértice normal). Isso é um pouco difícil, mas pode fornecer um resultado bom o suficiente para o que você deseja fazer.


A motivação para esta fórmula é observar o que acontece em 2D quando aplicado a um círculo:

fórmula de curvatura aplicada a dois pontos em um círculo

Suponha que você tenha um círculo de raio (então sua curvatura é 1 / r ) e você tenha dois pontos no círculo, com suas normais n 1 , n 2 . As posições dos pontos, em relação ao centro do círculo, vai ser p 1 = r n 1 e p 2 = r n 2 , devido à propriedade que um círculo ou esfera normais sempre apontar directamente para fora a partir do seu centro.r1/rn1,n2p1=rn1p2=rn2

Portanto, você pode recuperar o raio como ou | p 2 | / | n 2 | . Mas, em geral, as posições dos vértices não serão relativas ao centro do círculo. Podemos contornar isso subtraindo os dois: p 2 - p 1r=|p1|/|n1||p2|/|n2|

p2p1=rn2rn1=r(n2n1)r=|p2p1||n2n1|curvature=1r=|n2n1||p2p1|

O resultado é exato apenas para círculos e esferas. No entanto, podemos estendê-lo para torná-lo um pouco mais "tolerante" e usá-lo em malhas 3D arbitrárias, e parece funcionar razoavelmente bem. Podemos tornar a fórmula mais "tolerante" projetando primeiro o vetor na direção da aresta, p 2 - p 1 . Isso permite que esses dois vetores não sejam exatamente paralelos (como estão na caixa do círculo); projetaremos qualquer componente que não seja paralelo. Podemos fazer isso pontilhando o vetor de aresta normalizado: curvaturan2n1p2p1

curvature=(n2n1)normalize(p2p1)|p2p1|=(n2n1)(p2p1)/|p2p1||p2p1|=(n2n1)(p2p1)|p2p1|2

Et voilà, existe a fórmula que apareceu no topo desta resposta. A propósito, um bom benefício lateral do uso da projeção assinada (o produto escalar) é que a fórmula fornece uma curvatura assinada: positiva para superfícies convexas e negativa para superfícies côncavas.


Outra abordagem que posso imaginar usando, mas ainda não tentei, seria estimar a segunda forma fundamental da superfície em cada vértice. Isso pode ser feito configurando uma base tangente no vértice, convertendo todos os vértices vizinhos nesse espaço tangente e usando os mínimos quadrados para encontrar a matriz 2FF mais adequada. Então, as principais direções de curvatura seriam os autovetores dessa matriz. Isso parece interessante, pois pode permitir que você encontre as direções da curvatura "implícitas" pelos vértices vizinhos, sem arestas explicitamente apontadas para essas direções, mas, por outro lado, há muito mais código, mais computação e talvez menos numericamente robusto.

Um artigo que adota essa abordagem é Rusinkiewicz, "Estimando curvas e suas derivadas em malhas triangulares" . Ele funciona estimando a matriz 2FF de melhor ajuste por triângulo e, em seguida, calculando a média das matrizes por vértice (semelhante à forma como as normais suaves são calculadas).

Nathan Reed
fonte
1
Para sua informação, se isso importa, usei sua resposta aqui blender.stackexchange.com/questions/146819/…, mas adicionei uma ponderação usando o ângulo em torno de p1. Não sei se você acha isso valioso? De qualquer forma, sinta-se livre para comentar. Obrigado.
lemon
19

Apenas para adicionar outra maneira à excelente resposta @NathanReed, você pode usar a curvatura média e gaussiana que pode ser obtida com um discreto Laplace-Beltrami.

vi

                                         insira a descrição da imagem aqui

A(vi)13vj

f(vi)

ΔSf(vi)=12A(vi)vjN1(vi)(cotαij+cotβij)(f(vj)f(vi))

vjN1(vi)vi

v

H=12||ΔSv||

θj

                                        insira a descrição da imagem aqui

A curvatura gaussiana é:

K=(2πjθj)/A

Depois de toda essa dor, as principais curvaturas discretas são dadas por:

k1=H+H2K  and  k2=HH2K

Se você está interessado no assunto (e para adicionar alguma referência a este post), uma excelente leitura é: Operadores de Geometria Diferencial Discreta para 2-Manifolds Triangulares [Meyer et al. 2003].

Pelas imagens, agradeço ao meu ex-professor Niloy Mitra por encontrá-las em algumas anotações que tomei para suas palestras.

cifz
fonte
Ambas as respostas são realmente boas, foi difícil para mim escolher. Desde que eu perguntei sobre a maneira mais simples, acho que Nathan pega o bolo.
ap_ 17/11/2015
2
K=(π-jθj)/UMAmEuxed
Teodron 28/05
@teodron Você tem alguma ideia da curvatura média dos vértices da borda? Uma coisa dessas pode ser definida?
Museful
vEu . Há trabalhos mais recentes sobre curvaturas discretas, no entanto ..
teodron
-1

@ Nathan-Reed: Apenas uma pergunta à resposta de Nathan-Reed: por que você usou a média geométrica? Isso foi porque é "modelado" após a curvatura gaussiana?

Gabriel
fonte
3
Se você tiver uma nova pergunta, faça-o clicando no botão Fazer pergunta . Inclua um link para esta pergunta se ela ajudar a fornecer contexto. - Da avaliação
Dragonseel 20/11