Was ist der einfachste Weg, um die Hauptkrümmung für ein Maschendreieck zu berechnen?

19

Ich habe ein Netz und möchte in der Region um jedes Dreieck eine Schätzung der Hauptkrümmungsrichtungen berechnen. Ich habe so etwas noch nie gemacht und Wikipedia hilft nicht viel. Können Sie mich mit einem einfachen Algorithmus beschreiben oder darauf hinweisen, der mir bei der Berechnung dieser Schätzung helfen kann?

Angenommen, ich kenne Positionen und Normalen aller Eckpunkte.

ap_
quelle

Antworten:

24

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)(p2-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:

Krümmungsformel, die auf zwei Punkte auf einem 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=rn1p2=rn2

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-p1=rn2-rn1=r(n2-n1)r=|p2-p1||n2-n1|Krümmung=1r=|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(p2-p1)|p2-p1|=(n2-n1)(p2-p1)/|p2-p1||p2-p1|=(n2-n1)(p2-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).

Nathan Reed
quelle
1
Zu Ihrer Information , wenn das wichtig ist, habe ich Ihre Antwort hier verwendet: blender.stackexchange.com/questions/146819/…, aber eine Gewichtung unter Verwendung des Winkels um p1 hinzugefügt. Weißt du nicht, ob du das wertvoll findest? Wie auch immer, zögern Sie nicht zu kommentieren. Vielen Dank.
Zitrone
19

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

                                         Bildbeschreibung hier eingeben

EIN(vich) kann einfach ein der Bereiche der Dreiecke sein, die diesen Ring bilden, und das angegebene ist einer der benachbarten Eckpunkte.13vj

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)

ΔSf(vich)=12EIN(vich)vjN1(vich)(cÖtαichj+cÖtβichj)(f(vj)-f(vich))

Wobei jeden Scheitelpunkt in der Ein-Ring-Nachbarschaft von .vjN1(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

H=12||ΔSv||

Nun wollen wir den Winkel alsθj

                                        Bildbeschreibung hier eingeben

Die Gaußsche Krümmung ist:

K=(2π-jθj)/EIN

Nach all diesen Schmerzen sind die diskreten Hauptkrümmungen gegeben durch:

k1=H+H2-K  und  k2=H-H2-K

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.

cifz
quelle
Beide Antworten sind wirklich gut, es war schwer für mich zu wählen. Da ich nach dem einfachsten Weg gefragt hatte, denke ich, dass Nathan den Kuchen nimmt.
ap_
2
K=(π-jθj)/EINmichxed
@teodron Haben Sie vielleicht Einblicke in die mittlere Krümmung von Randscheitelpunkten? Kann so etwas definiert werden?
Museful
vich
-1

@ 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?

Gabriel
quelle
3
Wenn Sie eine neue Frage haben, fragen Sie es bitte durch Klicken Frage stellen Taste. Fügen Sie einen Link zu dieser Frage hinzu, wenn dies zur Bereitstellung des Kontexts beiträgt. - Aus der Bewertung
Dragonseel