KD-Tree completamente dinamico contro Quadtree?


11

Lavorando sul mio gioco, sono nel punto in cui devo rintracciare tutte le unità del mondo in modo da poter fare i controlli più vicini per il combattimento. Questo è un gioco simile a RTS, con potenzialmente migliaia di piccole unità automatizzate in movimento.

Ho studiato KD-Trees e Quadtrees (in particolare Point Quadtrees). Sto ancora cercando di imparare i dettagli di come funzionano, ma finora i Point Quadtrees hanno più senso per me. Tuttavia, ho l'impressione che gli alberi KD siano più veloci da cercare, il che è importante per il numero di punti che avrò nell'albero.

D'altra parte, nel mio caso, seguirò un numero enorme di unità che si muovono sempre . Di frame in frame, le loro posizioni saranno sempre diverse. I quadricre sono apparentemente più veloci da riequilibrare rispetto agli alberi KD, ma non so se ciò sia applicabile quando si riequilibrano tutti i punti dell'albero.

Mi chiedo se sarebbe meglio, in questo caso, eliminare l'albero da ogni frame e ricostruirlo da zero, piuttosto che cercare di riequilibrare ogni singolo punto dell'albero? Se un Quadtree è più veloce da riequilibrare, significa anche che è più veloce da costruire da zero? In tal caso, ciò potrebbe essere più importante per le prestazioni rispetto alla velocità di ricerca del KD-Tree, a seconda di quanto sia oneroso creare l'albero, ma non so ...

Risposte:


12

Gli alberi KD non sono assolutamente abbastanza dinamici per essere considerati, onestamente. Spostare alcune unità può facilmente richiedere di ricostruire l'intero KD-Tree. Inoltre, un albero KD è molto efficiente per le query, ma non tanto per la ricerca dei vicini.

Un quadtree è più flessibile nel tempo, poiché le modifiche vengono mantenute più localmente. Lo svantaggio è che se si hanno molte unità in un posto che si muovono spesso, potrebbe suddividere troppo e richiedere molti aggiornamenti a causa del movimento delle unità. È possibile impostare una soglia in base alla quale non possono verificarsi suddivisioni. Ma attenzione, ciò implica che molte unità potrebbero essere potenzialmente nello stesso quadrato delle foglie.

Se comunque sei interessato a trovare tutte le unità entro un raggio costante r , non hai bisogno di quadtree e kd-tree subito. Puoi semplicemente creare una matrice 2D di celle di lato di lunghezza re impilare le tue unità in ciascuna cella in base alla loro posizione. In questo modo, hai sempre nel peggiore dei casi 9 celle da cercare. Solo se la tua mappa è enorme , tale griglia sarebbe troppo grande per essere implementata.

Ci sono altre due strutture completamente diverse di cui non abbiamo parlato: AABB gerarchici e tabella hash sensibile al locale. Se l'origine di ciascun AABB gerarchico è descritta rispetto all'AABB principale, ha il vantaggio che se un grande gruppo di unità mantiene la sua formazione, non è necessario aggiornare gli AABB più piccoli poiché mantengono le stesse posizioni relative. Naturalmente, la rotazione della formazione potrebbe causare numerosi aggiornamenti, in tal caso l'utilizzo di altri volumi di delimitazione come sfere o scatole di delimitazione orientate (OBB) potrebbe essere più efficiente.

Le tabelle hash sensibili al locale offrono solo soluzioni approssimative in modo efficiente, quindi non mi preoccuperei.

Cosa farei ? Probabilmente inizierei con una griglia semplice, e quando ne ho bisogno, lo aggiornerei a un quadrifoglio e se ne ho bisogno, lo combinerò con una gerarchia di volumi limite sotto una certa soglia: i quadrifici funzionano bene a grandi scala, i volumi di delimitazione relativi funzionano bene su piccola scala. Facendolo gradualmente, non devo passare ore dall'inizio per ottenere immediatamente la migliore struttura di dati .


Grazie! Non avevo sentito parlare di AABB gerarchici e di tabelle hash sensibili al locale, li esaminerò per il futuro. Per ora vado con una griglia semplice e si espanderà se necessario, come hai detto. :)
Nairou,

4

I suggerimenti di Lærne sono fantastici, ma suggerirei anche un albero di volumi di limiti dinamico di AABB. Concettualmente l'albero dinamico del volume di delimitazione mantiene un albero bilanciato di nodi che può essere interrogato in qualsiasi momento per elementi vicini passando un AABB e recuperando una coppia sovrapposta. L'albero non viene ricostruito ogni fotogramma. Invece l'AABB di ciascun nodo viene leggermente gonfiato quando inserito nell'albero e l'albero viene ricostruito solo quando l'AABB effettivo del nodo non è più contenuto dall'AABB gonfiato. Lo uso nel mio motore fisico e funziona benissimo.

Il codice sorgente Box2D ne ha una grande implementazione.

https://github.com/erincatto/Box2D/blob/master/Box2D/Box2D/Collision/b2DynamicTree.h

Ecco una buona recensione della loro implementazione:

http://www.randygaul.net/2013/08/06/dynamic-aabb-tree/


Sì, questo è più o meno ciò che intendevo per AABB gerarchico, non ero molto preciso. Oh, e in unità RTSes sono spesso mobili, ma in formazioni. Pertanto, l'utilizzo delle coordinate relative al nodo AABB principale può essere abbastanza efficiente, con il margine di errore "inflazione".
Lærne,

Potresti aggiornare il link al codice di Google?
Kolenda,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.