Quando è preferibile un quadrifoglio rispetto all'hashing spaziale?


12

Sto realizzando un platform 2d con molti oggetti contemporaneamente. Sono state rilevate tutte le collisioni AABB. Per prima cosa ho provato un quadrifoglio per ridurre il numero di oggetti da controllare, ho provato alcune configurazioni diverse, ma non si è rivelato efficace quanto mi serviva. Ho implementato un hash spaziale ed è molto più efficiente, il numero di oggetti da controllare per ogni collisione è diminuito drasticamente.

C'è un caso in cui è preferibile eseguire il rilevamento di collisioni in 2d usando un quadrifoglio rispetto all'hash spaziale? Secondo i miei test, sembra che l'hashing spaziale finisca sempre con meno oggetti da testare per la collisione?

Non ho fatto il cronometraggio sugli algoritmi, ma l'hashing è semplicemente molto costoso o difficile da implementare quando, ad esempio, stai codificando in C? Vale la pena notare che sto scrivendo il gioco in javascript, dove hai l'hashing "gratis".

Ecco il confronto, ho trascurato qualcosa? http://zufallsgenerator.github.io/2014/01/26/visually-comparing-algorithms/

Risposte:


12

Il principale vantaggio di un albero quad è che ti consente di scartare interi gruppi di secchi dalla considerazione molto rapidamente.

Ad esempio, supponiamo che io abbia un albero quad con sei livelli. Al suo livello più basso, sono 32x32 scatole; 1024 scatole che comprendono quel livello inferiore, il più dettagliato. Per confronto, considereremo anche un "hash spaziale" - una griglia piatta che contiene anche 32x32 scatole, 1024 scatole in totale. (l'albero dei quad ha più di 1024 scatole in totale, poiché contiene anche scatole più grandi ai suoi livelli più alti)

Supponiamo che non ci siano oggetti collezionabili nel sistema: tutte le scatole del nostro albero quad e la nostra griglia piatta sono completamente vuote.

Se stai testando le collisioni di qualcosa che è abbastanza grande da far sì che il riquadro di delimitazione intersechi tutte quelle caselle e utilizzi una griglia piatta, devi controllare ognuna di quelle 1024 caselle per vedere se c'è anche qualcosa dentro loro.

Ma se stai usando un albero quadruplo nidificato, il livello più alto può dirti che non ci sono altri oggetti nel sistema, e quindi devi solo guardare quella singola scatola per sapere che non troverai collisioni più in profondità nella struttura: puoi interrompere immediatamente i test.

Allo stesso modo, se gli oggetti esistono solo in determinate aree del quad tree, il quad tree guiderà naturalmente la tua ricerca attraverso solo caselle potenzialmente rilevanti, mentre la griglia richiede di controllare ogni singola casella intersecata, perché non hai modo di sapere in anticipo quali quadrati della griglia contengono oggetti. Se gran parte del tuo albero quad è vuoto e stai eseguendo query grandi e complicate (ad esempio, enormi frustum della fotocamera anziché piccoli rettangoli semplici), potresti scoprire che stai iterando su molte meno caselle in totale se fai il tuo mette alla prova qualcosa usando una struttura ad albero, piuttosto che una griglia piatta. E questo può fare una grande differenza.

Tutto ciò non implica che una struttura ad albero sia sempre la scelta giusta, ovviamente. Le griglie piatte sono ideali per la situazione che hai nel tuo esempio: nuvole dense di oggetti si diffondono praticamente in modo uniforme in tutto il mondo e stiamo eseguendo test di collisione semplici ed economici. Assolutamente una griglia è probabilmente l'approccio ottimale in quel caso!


5
Riepilogo laconico, per i più pigri: i Quadtrees gestiscono più velocemente oggetti di dimensioni diverse.
Anko,

Grazie, questa è un'ottima risposta! La dimensione uniforme degli oggetti era qualcosa che sospettavo.
Chris,

In realtà, in genere dovrai cercare in tutti i livelli dell'albero del quad per verificare se non ci sono oggetti poiché in generale, un livello contiene solo informazioni su oggetti che si adattano interamente all'interno dei limiti di quel livello e non si adattano a un livello inferiore.
malthe,

1
@malthe Se insisti nell'utilizzare un'implementazione del quad tree che non può iniziare in anticipo in questo tipo di query, usa invece un hash spaziale; risparmierai il 33% del costo della memoria e comunque non ne trarrai alcun vantaggio. O in alternativa, puoi sciogliere la tua purezza idealogica solo un smidge e usare un albero quad che può precedere, sia facendo in modo che ciascun nodo segua il numero di entità nei suoi figli, oppure usando un quadrilatero rado in modo tale che i nodi vuoti siano scollegato dall'albero fino a quando non sono necessari. In realtà. Più di cinque anni dopo.
Trevor Powell,

@TrevorPowell ovviamente, hai ragione. Ho appena perso la garanzia che dovevi solo guardare una singola scatola. Questo non è vero perché dovrai perseguire quei conteggi. Puoi trovare collisioni più in alto e più in basso dell'albero, per quanto posso dire.
malthe,
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.