2010-02-19 2 views
5

Ich habe ein Mesh, mit bestimmten Arten von Elementen (z. B. dreieckig, Tetra). Für jedes Element, das ich kenne, werden alle seine Ecken, d. H. Ein dreieckiges 2D-Element, 3 Eckpunkte v1, v2 und v3 haben, deren x-, y-, z-Koordinaten bekannt sind.Algorithmus zum Finden von Kanten mit Vertices (2D und 3D) in einem Netz

Frage 1

ich für einen Algorithmus suchen, der alle Kanten zurück ... in diesem Fall:

Rand (v1, v2), Kante (v1, v3), Rand (v2, v3). Basierend auf der Anzahl der Knoten, die jedes Element hat, sollte der Algorithmus die Kanten effizient bestimmen.

Frage 2

ich C++ verwenden, so wird das sein, was der effizienteste Weg, um die Informationen über die Kanten durch den obigen Algorithmus zurück zu speichern? Beispiel, alles, was mich interessiert, ist ein Tupel (v1, v2), das ich für einige Berechnungen verwenden möchte und es dann vergesse.

Danke

Antwort

7

Sie die Struktur Halbranddaten verwenden können.


Grundsätzlich hat Ihr Mesh auch eine Liste von Kanten, und es gibt eine Kantenstruktur pro Paar Verts in jeder Richtung. Das heißt, wenn Sie A und B verraten haben, dann sind irgendwo zwei Kantenstrukturen gespeichert, eine für A-> B und eine für B-> A. Jede Kante hat 3 Zeiger, einen vorhergehenden, einen nächsten und einen Zwilling. Mit dem nächsten und vorherigen Zeiger können Sie die Kanten des Dreiecks oder Polygons im Netz durchlaufen. Wenn Sie twin aufrufen, gelangen Sie zur benachbarten Kante des benachbarten Polygons oder Dreiecks. (Sehen Sie sich die Pfeile im Bild an) Dies ist die nützlichste und ausführlichste Edge-Datenstruktur, die ich kenne. Ich habe es benutzt, um Meshes zu glätten, indem ich neue Kanten erstelle und die Zeiger aktualisiere. Übrigens sollte jede Kante auch auf einen Eckpunkt zeigen, damit sie weiß, wo sie im Raum ist.

5

Es gibt wirklich drei Teile auf Ihre Frage, nicht zwei:

  • Welche Datenstrukturen sollten verwendet werden, um das Netz darzustellen?
  • Welchen Algorithmus sollte ich verwenden, um Kanten aus den Netzdatenstrukturen zu extrahieren?
  • Wie sollte der resultierende Kantensatz dargestellt werden?

Sie müssen zusätzliche Fragen stellen, um passende Antworten zu finden.

Welche Datenstrukturen sollten zur Darstellung des Netzes verwendet werden?

Welche Elementtypen müssen Sie handhaben?

Wenn Sie nur Polygone (geschlossene Schleifen) und Simplicials behandeln müssen (jeder Knoten ist mit jedem anderen Knoten im Element verbunden, z. B. einem Tetraeder), dann ist eine geordnete Knotenliste ausreichend, da Kanten von der Liste der Knoten. Wenn Sie andererseits mit Elementtypen wie Hexaedern, Prismen oder allgemeinen Polyedern umgehen müssen, benötigen Sie weitere Informationen zur Elementtopologie. Eine einfache Anordnung von Kantenzuordnungen ist oft ausreichend. Es ist nur ein Array [] [2] von Indizes in der Knotenliste des Elements, das Ihnen sagt, wie Sie die Punkte für einen gegebenen Elementtyp verbinden.

Die von Chris beschriebene Halbkantenstruktur ist eine gute Wahl nur für 2D. In 3D kann eine beliebige Anzahl von Elementen an jeder Kante angebracht sein, nicht nur zwei. Es gibt eine 3D-Erweiterung für die Half-Edge-Darstellung, die ich als Pinwheel-Struktur bezeichne.

Wenn Sie willkürliche Elementtypen unterstützen müssen, bevorzuge ich eine vollständigere Datenstruktur, um die Elementtopologie darzustellen. Eine gängige Option ist die Verwendung von Kanten und Kanten. Es gibt eine Kantenstruktur für jedes Paar verbundener Knoten und eine Nebenkante für jede Verwendung dieser Kante in einem Element. Es ist ähnlich wie bei der Nadelradmethode, aber etwas expliziter.

Welchen Algorithmus soll ich verwenden, um Kanten aus den Elementen zu extrahieren?

Wie wichtig ist Geschwindigkeit oder Speicher? Sollte das Ergebnis jede Kante einmal pro Element oder nur einmal enthalten, egal wie viele Elemente es verwenden? Kommt es auf die Reihenfolge der Kanten im Ergebnis an? Ist die Reihenfolge der Knoten jeder Kante wichtig?

Es ist ziemlich schwierig, einen Algorithmus für beliebige Elementtypen zu finden, der nur einmal jede Kante besucht. Um sicherzustellen, dass jede Kante nur einmal angezeigt wird, können Sie entweder das Ergebnis filtern, oder Sie können ein bisschen hackisch sein und ein "besuchtes" Bit an jeder Kante behalten, um sicherzustellen, dass Sie es nicht zweimal im Ergebnis festhalten.

Wie soll ich die Ergebnisse darstellen?

Was ist wichtig, wie ich das Ergebnis verwenden werde?

Wenn Sie das Ergebnis in einer rechenintensiven Berechnung verwenden, ist möglicherweise eine große Anzahl von Koordinaten die beste Option. Sie möchten die Knotenkoordinaten während Ihrer Berechnung nicht immer wieder abrufen. Wenn Sie jedoch die Ergebnisse filtern, um doppelte Kanten zu entfernen, ist der Vergleich von Koordinaten (6 Doppelpunkte für ein Knotenpaar) nicht der richtige Weg. Wenn Sie filtern, generieren Sie zuerst eine Liste mit Zeigern zu Kantenstrukturen, dann filtern Sie die Duplikate heraus, und dann generieren Sie Ihre Koordinatenliste. Sie können diesen Ansatz auch mit Knotenpaaren verwenden, aber dann müssen Sie für beide möglichen Knotenreihenfolgen pro Kante filtern, um die Zeit zu verdoppeln, die zum Filtern benötigt wird.

Eine Liste der Kantenzeiger ist auch der Weg zu gehen, wenn Speicher mehr als Leistung zählt. Anstatt Ihre Kantenliste in eine Koordinatenliste zu konvertieren, suchen Sie jedoch während der Berechnung nach Koordinaten. Knotenkoordinaten zu erhalten, ist auf diese Weise langsamer, aber Sie vermeiden es, eine riesige Liste von Koordinaten zu erstellen - Sie speichern einen einzelnen Zeiger pro Kante anstelle von 6 Doppelpunkten pro Kante.

Viele Netzanwendungen speichern alle Koordinaten in einem großen globalen Array, wobei jeder Knoten einen Index in das Array hat. Wenn dies der Fall ist, wandeln Sie Ihre Kantenliste in ein Koordinatenfeld um, indem Sie sie in eine Liste von Indizes in das globale Koordinatenfeld konvertieren. Die Leistung sollte von einem lokalen Koordinaten-Array nicht viel abweichen, aber ohne den Speicher- und Populations-Overhead.

Verwandte Themen