Algorithmus, um zu sehen, ob zwei Voxel miteinander verbunden sind

11

Ich suche nach guten Algorithmen für das folgende Problem: Wenn ich bei einem 3D-Raster von Voxeln (die entweder leer oder gefüllt sein können) zwei nicht benachbarte Voxel auswähle, möchte ich wissen, ob sie durch miteinander verbunden sind andere Voxel.

Zum Beispiel (um die Situation in 2D zu veranschaulichen), wobei # ein gefülltes Quadrat ist:

  1 2 3
a # # #
b # #
c # # #

Wenn ich a3 und c3 auswähle, möchte ich so schnell wie möglich feststellen, ob sie verbunden sind. wenn es einen Pfad zwischen a3 und c3 durch gefüllte Pixel gibt. (Die reale Situation ist natürlich in einem 3D-Voxelgitter.)

Ich habe mir Floodfill-Algorithmen und Pfadfindungsalgorithmen angesehen, bin mir aber nicht sicher, welche ich wählen soll. Beide erledigen unnötige Arbeit: Flood Fill versucht, alle Voxel zu füllen, dies ist jedoch nicht erforderlich. Pfadfindungsalgorithmen befassen sich normalerweise mit dem Finden des kürzesten Pfades, was ebenfalls nicht erforderlich ist. Ich muss nur wissen , ob es ist ein Weg.

Welchen Algorithmus soll ich verwenden?

Bearbeiten: Basierend auf den Kommentaren sollte ich Folgendes hinzufügen: Der Inhalt der Voxel ist nicht im Voraus bekannt, und der Algorithmus wird benötigt, um zu erkennen, ob das Entfernen (Entleeren) eines Voxels dazu führen würde, dass die Gruppe der Voxel bricht in zwei oder mehr kleinere Gruppen.

Bram Vaessen
quelle
In Ihrem Beispiel wäre ein gültiger Pfad von a3 nach c3 der folgende : c3->c2->b2->a2->a3?
das ist richtig
Bram Vaessen

Antworten:

12

Ein * würde gut funktionieren. Das Finden von Pfaden ist das, was Sie wollen. Das Finden des kürzesten Pfades ist genauso schnell (oder schneller) wie das Finden eines Pfades überhaupt. In dieser Situation ist A * wahrscheinlich am besten geeignet, wenn Sie einen Start- und einen Endpunkt haben. Dies bedeutet, dass Sie die zusätzliche Heuristik haben, um die Suche zu beschleunigen.

Bei A * ist normalerweise der erste Pfad, den Sie finden, der kürzeste, sodass keine zusätzliche Arbeit geleistet wird, nachdem bereits ein Pfad gefunden wurde.

Geben Sie hier die Bildbeschreibung ein

Weitere Optimierungen finden Sie in meiner Antwort hier .

MichaelHouse
quelle
Es sieht so aus, als würde es wirklich nach vorne schießen, bis es gegen diese Wand stößt, dann kriecht es irgendwie
GameDev-er
1
@ GameDev-er Ja, das liegt an der Heuristik. Wenn es kein Hindernis gäbe, wäre es eine sehr schnelle Suche, fast eine gerade Linie.
MichaelHouse
Bei einer besseren Sortierung der Knoten würde dies den Pfad erweitern, der dem endgültigen Knoten am nächsten liegt. Wenn Sie eine schnelle Datenstruktur zum Ordnen der Knoten haben, sortieren Sie diese nach Entfernung zum Ziel, um den direktesten Pfad zu erhalten.
MichaelHouse
9

Wenn Sie bereit sind, eine Vorverarbeitung durchzuführen und die Speicherkosten zu verbrauchen, gibt die Partitionierung von Voxeln in verbundene Gruppen zur Erstellungszeit eine offensichtliche Antwort auf "Gibt es überhaupt einen Pfad". Es gibt einen Pfad zwischen zwei Voxeln, wenn sie sich in derselben Gruppe befinden. Das Problem dabei ist natürlich, dass Sie Gruppeninformationen irgendwo speichern müssen, und das hängt von Ihrem Datenlayout ab. Wenn Sie eine einfache Liste speichern, können Sie diese einfach in mehrere Listen aufteilen, eine für jede räumlich verbundene Gruppe. Wenn Sie in einer Art BVH organisieren, können Sie wahrscheinlich einigermaßen gute Wirkungsgrade erzielen, wenn Sie sagen können, dass "alle Voxel in diesem Knoten und darunter zur Gruppe X gehören".

Alternativ können Sie eine räumliche Vorpartitionierung durchführen und für jede verbundene Gruppe einen kleineren Satz von Hub-Voxeln speichern. Dann können Sie den Pfad von Ihren Quell- und Ziel-Voxeln zum nächstgelegenen Hub-Voxel finden, was für die Berechnung des Pfads viel kürzer / billiger sein sollte. Wenn Sie einen Pfad von einem Voxel zu einem Hub-Voxel finden, ist das Voxel Teil der Gruppe des Hub-Voxels. Mit der intelligenten Auswahl dieser Hub-Voxel können Sie die Anzahl der Pfadüberquerungen minimieren. Beispielsweise könnte eine Kugel nur ein Nabenvoxel in ihrer Mitte haben, aber eine lange dünne Gruppe könnte alle X Voxel entlang ihrer Länge ein Nabenvoxel haben. Wenn sich Ihre Quell- und Zielvoxel an einem Ende der Länge befinden, müssen sie höchstens X Voxel verwenden, um einen Hub zu finden, und obwohl sich zwischen dem Anfang und dem Ende der Länge möglicherweise eine große Anzahl von Voxeln befindet,

Es hängt alles davon ab, wie pathologisch Ihre Voxelgruppen sind: Wenn Sie eine große Anzahl kleiner, nicht verbundener Gruppen erwarten, wird der Anstieg der Speicherkosten den Leistungseinbruch der Pfadfindung massiv überwiegen. Wenn Sie relativ wenige verbundene Gruppen mit ungeraden Topologien erwarten, ist die naive Pfadfindung möglicherweise sehr teuer, und die Speicherkosten und die minimale Pfadfindung sind eine viel billigere Option.

MrCranky
quelle
1
Dies ist die richtige Antwort, aber um sie effizient zu implementieren, sollte sie nicht als Liste gespeichert werden. Fügen Sie jedem Voxel einen Zeiger hinzu, der auf sein "repräsentatives Voxel" zeigt, das Sie mithilfe des Union-Find-Algorithmus festlegen. Dies sind konstante Speicherkosten pro Voxel und im Wesentlichen linear in der Anzahl der Kanten für die Berechnungskosten.
Neil G
Interessante Ideen, aber es gibt zwei Dinge, die die Situation komplizieren könnten. Das erste ist, dass der Inhalt des Voxel-Gitters nicht im Voraus bekannt ist. Um Hub-Voxel zu erstellen, würde ich auch einen Algorithmus benötigen, der bestimmen kann, welche Voxel Hubs sein sollen.
Bram Vaessen
1
Das zweite Problem besteht darin, dass der Algorithmus direkt nach dem Entfernen eines Voxels benötigt wird, um festzustellen, ob die Gruppe, zu der er gehört, aufgrund des Entfernens dieses Voxels in kleinere Gruppen aufgeteilt wird.
Bram Vaessen
@BramVaessen Wenn Sie nach allen paarweisen Interkonnektivitätsbeziehungen suchen - und insbesondere, ob Gruppen sich auflösen -, ist dies eine etwas andere Sache als nur die Erreichbarkeit (obwohl die Erreichbarkeit der einfachste Weg ist, dies zu tun). Ich würde empfehlen, der ursprünglichen Frage weitere Details zu dem hinzuzufügen, wonach Sie suchen, da dies möglicherweise bessere Antworten auf das „Problem hinter der Frage“ ermöglicht.
Steven Stadnicki
Um es sauber zu halten, habe ich mein anfängliches Problem in einer anderen Frage hier gestellt gamedev.stackexchange.com/questions/50953/…
Bram Vaessen
4

Ich bin mit Voxeln nicht sehr vertraut, aber ich würde mir vorstellen, dass Sie mit einem Best-First-Suchalgorithmus wie A * eine recht gute Leistung erzielen können. Das Problem bei der Verwendung von A * in diesem Fall besteht darin, dass die normalerweise verwendete Heuristik darauf ausgelegt ist, das Finden des kürzesten Pfades und nicht nur eines beliebigen Pfads so schnell wie möglich zu priorisieren.

Möglicherweise haben Sie etwas Glück, wenn Sie eine alternative Heuristik verwenden, die weniger Knoten erweitert, z

f (p) = g (p) + w (p) · h (p)

Dabei ist w> = 1. Sie verringern den Wert von 'w', je näher Sie dem Ziel kommen, und geben den Pfadkosten 'g' eine höhere Priorität, je näher Sie dem gesuchten Voxel kommen.

Ich hoffe das hilft!

Matthew R.
quelle