Mir wurde gesagt, dass ein Quad-Baum die ideale Datenstruktur für mein Spiel ist, aber ich habe Probleme zu verstehen, wie genau Formen in Quad-Bäumen funktionieren.
Ich mache das in JavaScript, aber ich denke, diese Fragen könnten für Quad-Bäume in jeder Sprache gelten.
Ich denke, ich verstehe meistens, wie grundlegende (x, y) Punkte und das Einfügen von Punkten in Quad-Bäumen funktionieren und dass ich es auf Papier tun könnte.
Hier ist eine JSfiddle meines Experimentierens mit Punkten.
Abgesehen von einem Fall funktionieren meine Tests mit Punkten wie erwartet.
Aber meine Verwirrung beginnt, wenn es um Formen wie Rechtecke geht. Überprüft es beim Abrufen von einem Quad-Baum mit Formen jeden Punkt der Form und in welche Knoten fallen sie? Und wie funktionieren Formeinfügungen überhaupt, wenn sie Parameter (x, y, Breite, Höhe) für jede Form akzeptieren? Verwendet es die Breite / Höhe vom Startpunkt aus, um andere Eckpunkte zu berechnen, die dann in geeignete Knoten verteilt werden? Wenn sich eine eingefügte Form in vier Knoten erstreckt, werden die Daten dieser Form in allen vier Knoten gespeichert?
Und wenn eine Abrufmethode eine Form als Parameter akzeptiert (x, y, Breite, Höhe), was ist dann tatsächlich los? Wird zuerst angezeigt, auf welche Knoten sich die Form erstrecken würde, wenn sie eingefügt würde, und dann alle Objekte dieser Knoten abgerufen?
Ich habe eine JSfiddle, die mit Formen arbeitet , aber ich bin völlig verwirrt über die Ergebnisse meiner Tests. Ich erhalte doppelte Objekte, die zurückgegeben werden!
Das rote Quadrat entspricht beispielsweise den Parametern, die ich in meine Abrufmethode eingebe. Ich würde denken, da dieses rote Quadrat alle vier Knoten überspannt, sollte es jedes Objekt im Quad-Baum zurückgeben! Aber das tut es nicht und ich habe Probleme zu rationalisieren, was es zurückgibt. Ich habe eine Reihe anderer Tests, die derzeit auskommentiert sind, aber Sie können sie auskommentieren und ausführen, um verwirrendere Ergebnisse zu sehen!
Wie würde ich das tun, wenn ich alle Punkte in einem Quad-Baum zurückgeben möchte? Eine Abrufmethode unter Verwendung einer Form über die gesamte Größe der Grenzen? Beispiel: Abrufen (0, 0, canvas.width, canvas.height)?
Auf die von mir verwendete JavaScript QuadTree-Bibliothek wurde von verschiedenen anderen Quellen verwiesen, daher gehe ich davon aus, dass die tatsächliche Implementierung korrekt und seriös ist.
Ich denke, ein Großteil meiner Verwirrung kann auf ein Missverständnis der Quad-Tree-Terminologie zurückzuführen sein. Warum sagen sie Grenzen statt Bemaßungen, wenn ein "Punkt" auch Breiten- / Höhenparameter hat? Ist es eine Frage der Konvention / Kurzschrift oder sind es völlig andere Konzepte?
Vielen Dank für Ihre Zeit!
quelle
_stuckChildren
Feld im Code. Sie können dies auch im Beispiel "Abrufen von Elementen mit Grenzen" sehen. Es hebt immer die Knoten rot hervor, die sich über die Ränder der Knoten erstrecken, auf die Sie geklickt haben, bis zum Stammknoten.Antworten:
Quadtrees speichern und rufen normalerweise Rechtecke ab. Ein Punkt ist ein spezieller Fall, in dem Breite und Höhe Null sind. Die folgende Logik wird verwendet, um nach neuen Rechtecken im Baum zu suchen, beginnend mit dem Stammknoten:
Beachten Sie, dass Rechtecke in jeder Tiefe gespeichert werden können. Es muss sich nicht um ein Blattquad handeln. Wenn das Rechteck die Grenze direkt auf der Wurzelebene überspannt, speichert das Wurzelquad das Rechteck.
Beim Abfragen des Quadtree werden nur Rechtecke zurückgegeben, die in der Abfrage enthalten sind. In Ihrem Beispiel erzwingen Sie, dass jedes der 4 untergeordneten Quads genauer betrachtet wird, da das rote Abfrage-Rechteck jedes untergeordnete Quad schneidet. Da die Kinder keine weiteren Kinder haben, wird jedes der Rechtecke in diesen untergeordneten Quads mit dem roten Rechteck verglichen. Da keines der Rechtecke im Baum mit dem roten Abfragerechteck kollidiert, sollte nichts zurückgegeben werden.
Sie sehen wirklich Vorteile von Quadtrees, wenn Sie viele Objekte haben und im Vergleich zu den Abfragebereichen viel Platz für die Objekte vorhanden ist. In diesen Fällen kann ein kleiner Abfragebereich schnell große Teile des Quad-Baums aus der Betrachtung entfernen. Nur Quads, die sich mit dem Abfrage-Rechteck überschneiden, werden jemals genauer betrachtet.
BEARBEITEN
Das Abrufen erfolgt normalerweise wie folgt:
In Ihrer Bibliothek scheint es jedoch nicht zu prüfen, ob sich die zurückgegebenen Rechtecke mit der Abfrage überschneiden. Sie müssen diese also selbst hinzufügen.
quelle
retrieve
Methode eine Logik hinzuzufügen , um die Liste zu bereinigen. Sie können hier etwas deutlicher sehen, was es tut: mikechambers.com/html5/javascript/QuadTree/examples/…