Cuando necesitaba una estimación de la curvatura de la malla para un sombreador de piel, el algoritmo en el que terminé estableciéndome fue este:
Primero, calculé una curvatura escalar para cada borde en la malla. Si el borde tiene posiciones y normales n 1 , n 2 , entonces calculé su curvatura como:p1,p2n1,n2
curvature=(n2−n1)⋅(p2−p1)|p2−p1|2
Esto calcula la diferencia en las normales, proyectadas a lo largo del borde, como una fracción de la longitud del borde. (Vea a continuación cómo se me ocurrió esta fórmula).
Luego, para cada vértice, miré las curvaturas de todos los bordes que lo tocaban. En mi caso, solo quería una estimación escalar de la "curvatura promedio", así que terminé tomando la media geométrica de los valores absolutos de todas las curvaturas de los bordes en cada vértice. Para su caso, puede encontrar las curvaturas mínimas y máximas, y tomar esos bordes como las direcciones de curvatura principales (tal vez ortonormalizándolos con el vértice normal). Eso es un poco difícil, pero podría darte un resultado lo suficientemente bueno para lo que quieres hacer.
La motivación para esta fórmula es observar lo que sucede en 2D cuando se aplica a un círculo:
Suponga que tiene un círculo de radio (por lo que su curvatura es 1 / r ), y tiene dos puntos en el círculo, con sus normales n 1 , n 2 . Las posiciones de los puntos, en relación con el centro del círculo, seránr1 / rnorte1, n2 y p 2 = r n 2 , debido a la propiedad de que las normales de un círculo o esfera siempre apuntan directamente desde su centro.pag1= r n1pag2= r n2
Por lo tanto, puede recuperar el radio como o | p 2 | / | n 2 | . Pero, en general, las posiciones de los vértices no serán relativas al centro del círculo. Podemos solucionar esto restando los dos:
p 2 - p 1r = | pag1El | / | norte1El |El | pag2El | / | norte2El |
pag2- p1rcurvatura = 1r= r n2- r n1= r ( n2- n1)= | pag2- p1El |El | norte2- n1El |= | norte2- n1El |El | pag2- p1El |
El resultado es exacto solo para círculos y esferas. Sin embargo, podemos extenderlo para hacerlo un poco más "tolerante", y usarlo en mallas 3D arbitrarias, y parece funcionar razonablemente bien. Podemos hacer que la fórmula sea más "tolerante" proyectando primero el vector norte2- n1 en la dirección del borde, . Esto permite que estos dos vectores no sean exactamente paralelos (como lo están en el caso del círculo); simplemente proyectaremos cualquier componente que no sea paralelo. Podemos hacer esto punteando con el vector de borde normalizado:
curvaturapag2- p1
curvatura= ( n2- n1) ⋅ normalizar ( p2- p1)El | pag2- p1El |= ( n2- n1) ⋅ ( p2- p1) / | pag2- p1El |El | pag2- p1El |= ( n2- n1) ⋅ ( p2- p1)El | pag2- p1El |2
Et voilà, está la fórmula que apareció en la parte superior de esta respuesta. Por cierto, un buen beneficio adicional de usar la proyección con signo (el producto de puntos) es que la fórmula proporciona una curvatura con signo: positivo para convexo y negativo para superficies cóncavas.
Otro enfoque que puedo imaginar usando, pero que no he probado, sería estimar la segunda forma fundamental de la superficie en cada vértice. Esto se puede hacer estableciendo una base tangente en el vértice, luego convirtiendo todos los vértices vecinos en ese espacio tangente y utilizando mínimos cuadrados para encontrar la matriz 2FF que mejor se ajuste. Entonces, las principales direcciones de curvatura serían los vectores propios de esa matriz. Esto parece interesante ya que podría permitirle encontrar direcciones de curvatura "implicadas" por los vértices vecinos sin ningún borde que apunte explícitamente en esas direcciones, pero, por otro lado, hay mucho más código, más cómputo y quizás menos robusto numéricamente.
Un artículo que adopta este enfoque es Rusinkiewicz, "Estimación de curvaturas y sus derivados en mallas triangulares" . Funciona estimando la matriz 2FF de mejor ajuste por triángulo, luego promediando las matrices por vértice (similar a cómo se calculan las normales suaves).