Als ich eine Schätzung der Netzkrümmung für einen Skin-Shader benötigte, lautete der Algorithmus, auf den ich mich festgelegt habe, wie folgt:
Zuerst habe ich für jede Kante im Netz eine skalare Krümmung berechnet. Wenn die Kante die Positionen und die Normalen , dann habe ich ihre Krümmung wie geschätzt:p1, p2n1, n2
Krümmung = ( n2- n1) ⋅ ( S.2- p1)| p2- p1|2
Dies berechnet die Differenz der Normalen, die entlang der Kante projiziert werden, als Bruchteil der Kantenlänge. (Siehe unten, wie ich auf diese Formel gekommen bin.)
Dann betrachtete ich für jeden Scheitelpunkt die Krümmungen aller Kanten, die ihn berührten. In meinem Fall wollte ich nur eine skalare Schätzung der "durchschnittlichen Krümmung", also habe ich den geometrischen Mittelwert der absoluten Werte aller Kantenkrümmungen an jedem Scheitelpunkt genommen. In Ihrem Fall können Sie die minimale und maximale Krümmung finden und diese Kanten als Hauptkrümmungsrichtung annehmen (möglicherweise orthonormieren Sie sie mit der Scheitelpunktnormalen). Das ist ein bisschen rau, aber es gibt Ihnen möglicherweise ein ausreichend gutes Ergebnis für das, was Sie tun möchten.
Die Motivation für diese Formel ist die Betrachtung dessen, was in 2D geschieht, wenn es auf einen Kreis angewendet wird:
Angenommen, Sie haben einen Kreis mit dem Radius (dessen Krümmung ist also ) und Sie haben zwei Punkte auf dem Kreis mit ihren Normalen . Die Positionen der Punkte in Bezug auf den Mittelpunkt des Kreises sind und , da die Normalen eines Kreises oder einer Kugel immer direkt von dessen Mittelpunkt ausgehen.1 / r n 1 , n 2 p 1 = r n 1 p 2 = r n 2r1 / rn1, n2p1= r n1p2= r n2
Daher können Sie den Radius als wiederherstellen oder. Im Allgemeinen sind die Scheitelpunktpositionen jedoch nicht relativ zum Mittelpunkt des Kreises. Wir können das wir die beiden folgenden subtrahieren:
| p 2 | / | n 2 | p 2 - p 1r = | p1|/ | n1||p2| / |n2|
p2- p1rKrümmung = 1r= r n2- r n1= r ( n2- n1)= | p2- p1|| n2- n1|= | n2- n1|| p2- p1|
Das Ergebnis ist nur für Kreise und Kugeln genau. Wir können es jedoch erweitern, um es etwas "toleranter" zu machen, und es für beliebige 3D-Netze verwenden, und es scheint einigermaßen gut zu funktionieren. Wir können die Formel "toleranter" machen, indem wir zuerst den Vektor auf die Richtung der Kante projizieren . Dies ermöglicht, dass diese beiden Vektoren nicht genau parallel sind (wie im Kreisfall); Wir projizieren einfach alle Komponenten weg, die nicht parallel sind. Wir können dies tun, indem wir mit dem normalisierten Kantenvektor punktieren:
p 2 - p 1 Krümmungn2- n1p2- p1
Krümmung= ( n2- n1) ⋅ normalisieren ( S.2- p1)| p2- p1|= ( n2- n1) ⋅ (p2- p1) / | p2- p1|| p2- p1|= ( n2- n1) ⋅ ( S.2- p1)| p2-p1|2
Et voilà, es gibt die Formel, die oben in dieser Antwort auftaucht. Übrigens ist ein netter Nebeneffekt der Verwendung der vorzeichenbehafteten Projektion (des Skalarprodukts), dass die Formel dann eine vorzeichenbehaftete Krümmung ergibt: positiv für konvexe und negativ für konkave Oberflächen.
Ein weiterer Ansatz, den ich mir vorstellen kann, aber noch nicht ausprobiert habe, ist die Schätzung der zweiten Grundform der Oberfläche an jedem Scheitelpunkt. Dies könnte erreicht werden, indem eine Tangentenbasis am Scheitelpunkt erstellt wird, dann alle benachbarten Scheitelpunkte in diesen Tangentenraum konvertiert werden und mithilfe der kleinsten Quadrate die am besten passende 2FF-Matrix ermittelt wird. Dann wären die Hauptkrümmungsrichtungen die Eigenvektoren dieser Matrix. Dies scheint interessant zu sein, da Sie damit Krümmungsrichtungen finden können, die von den benachbarten Scheitelpunkten "impliziert" werden, ohne dass Kanten explizit in diese Richtungen weisen. Andererseits ist dies viel mehr Code, mehr Berechnung und möglicherweise weniger numerisch robust.
Ein Papier, das diesen Ansatz verfolgt, ist Rusinkiewicz, "Estimating Curvatures and Their Derivatives on Triangle Meshes" . Es funktioniert durch Schätzen der am besten passenden 2FF-Matrix pro Dreieck und anschließendes Mitteln der Matrizen pro Scheitelpunkt (ähnlich wie bei der Berechnung von glatten Normalen).
Nur um einen anderen Weg zur exzellenten @ NathanReed-Antwort hinzuzufügen, können Sie die mittlere und Gaußsche Krümmung verwenden, die mit einer diskreten Laplace-Beltrami erhalten werden kann.
Nehmen wir also an, dass die 1-Ring-Nachbarschaft von in Ihrem Netz so aussiehtvich
Rufen wir nun die von Ihrem Netz definierte Funktion (muss eine differenzierbare Mannigfaltigkeit sein) an einem bestimmten Punkt. Die beliebteste Diskretisierung des Laplace-Beltrami-Operators, die ich kenne, ist die Kotangens-Diskretisierung und wird gegeben durch:f(vich)
Wobei jeden Scheitelpunkt in der Ein-Ring-Nachbarschaft von .vj∈ N1( vich) vich
Damit ist es ziemlich einfach, die mittlere Krümmung zu berechnen (der Einfachheit halber bezeichnen wir die Funktion Ihres Netzes am interessierenden Scheitelpunkt einfach als )v
Nun wollen wir den Winkel alsθj
Die Gaußsche Krümmung ist:
Nach all diesen Schmerzen sind die diskreten Hauptkrümmungen gegeben durch:
Wenn Sie sich für das Thema interessieren (und einen Verweis auf diesen Beitrag hinzufügen möchten), ist dies eine hervorragende Lektüre: Diskrete Differentialgeometrieoperatoren für dreieckige 2-Mannigfaltigkeiten [Meyer et al. 2003].
Für die Bilder danke ich meinem Ex-Professor Niloy Mitra, der sie in einigen Notizen für seine Vorlesungen gefunden hat.
quelle
@ Nathan-Reed: Nur eine Frage zu Nathan-Reeds Antwort: Warum hast du den geometrischen Mittelwert verwendet? War das, weil es nach der Gaußschen Krümmung "modelliert" ist?
quelle