¿Cuándo es preferible un quadtree sobre hashing espacial?

12

Estoy haciendo un juego de plataformas 2D con muchos objetos al mismo tiempo. Todos son colisión AABB detectada. Primero probé un quadtree para disminuir la cantidad de objetos a verificar, probé algunas configuraciones diferentes, pero no resultó tan efectivo como lo necesitaba. Implementé un hash espacial y es mucho más eficiente, el número de objetos para verificar cada colisión disminuyó drásticamente.

¿Hay algún caso en el que la detección de colisiones 2D con un árbol cuádruple sea preferible a la dispersión espacial? Según mis pruebas, ¿parece que el hashing espacial siempre termina con menos objetos para ser probados por colisión?

No he cronometrado los algoritmos, pero el hashing es simplemente muy costoso o difícil de implementar cuando, por ejemplo, está codificando en C? Vale la pena señalar que estoy escribiendo el juego en javascript, donde tienes hashing "gratis".

Aquí está la comparación, ¿pasé por alto algo? http://zufallsgenerator.github.io/2014/01/26/visually-comparing-algorithms/

Chris
fuente

Respuestas:

12

La principal ventaja de un árbol cuádruple es que le permite descartar grupos enteros de depósitos de manera muy rápida.

Por ejemplo, supongamos que tengo un árbol cuádruple con seis niveles. En su nivel más bajo, son 32x32 cajas; 1024 cajas que comprenden ese nivel inferior y más detallado. A modo de comparación, también consideraremos un "hash espacial": una cuadrícula plana que también contiene 32x32 cajas, 1024 cajas en total. (el árbol cuádruple tiene más de 1024 cajas en total, ya que también contiene cajas más grandes en sus niveles más altos)

Supongamos que no hay objetos colisionables en el sistema: todas las cajas de nuestro árbol cuádruple y nuestra cuadrícula plana están completamente vacías.

Si está probando las colisiones de algo que es lo suficientemente grande como para que su cuadro delimitador se cruza con todos esos cuadros, y está utilizando una cuadrícula plana, debe marcar cada uno de esos 1024 cuadros para ver si hay algo en ellos.

Pero si está utilizando un árbol cuádruple anidado, el nivel más alto puede decirle que no hay otros objetos en el sistema, por lo que solo tiene que mirar esa única casilla para saber que no encontrará colisiones. más profundo en el árbol: puede detener la prueba de inmediato.

Del mismo modo, si los objetos solo existen en ciertas regiones del árbol cuádruple, el árbol cuádruple naturalmente guiará su búsqueda a través de solo cuadros potencialmente relevantes, mientras que la cuadrícula requiere que marque cada cuadro intersectado, porque no tiene forma de saber de antemano qué cuadrículas tendrán objetos en ellas. Si gran parte de su árbol cuádruple está vacío y está haciendo consultas grandes y complicadas (por ejemplo, enormes frustums de cámara en lugar de rectángulos pequeños y simples), entonces puede encontrar que está iterando sobre muchas menos cajas en total si hace su prueba contra algo usando una estructura de árbol, en lugar de una cuadrícula plana. Y eso puede hacer una gran diferencia.

Todo lo cual no implica que una estructura de árbol sea siempre la opción correcta, por supuesto. Las cuadrículas planas son ideales para la situación que tiene en su ejemplo: densas nubes de objetos se extienden de manera uniforme en todas partes del mundo, y estamos haciendo pruebas de colisión simples y económicas. ¡Es probable que una cuadrícula sea el enfoque óptimo en ese caso!

Trevor Powell
fuente
55
Resumen lacónico, para los extremadamente perezosos: los Quadtrees manejan objetos de diferentes tamaños más rápido.
Anko
Gracias, esta es una excelente respuesta! El tamaño uniforme de los objetos era algo que sospechaba.
Chris
En realidad, normalmente tendrá que buscar a través de todos los niveles del árbol cuádruple para verificar si no hay objetos, ya que, en general, un nivel solo contiene información sobre los objetos que encajan completamente dentro de los límites de ese nivel y no encajan en un nivel inferior.
Malté
1
@malthe Si insiste en usar una implementación de árbol cuádruple que no puede comenzar en este tipo de consulta, entonces use absolutamente un hash espacial; ahorrará el 33% del costo de la memoria, y de todos modos no habría obtenido ningún beneficio. O, como alternativa, puede aflojar su pureza idealógica solo un poco y usar un árbol cuádruple que puede salir temprano, ya sea haciendo que cada nodo rastree el número de entidades en sus elementos secundarios, o bien usando un quadtree escaso de tal manera que los nodos vacíos sean desvinculado del árbol hasta que sean necesarios. Realmente. Más de cinco años después.
Trevor Powell
@TrevorPowell, por supuesto, tienes razón. Acabo de caer sobre su garantía de que solo tenía que mirar una sola caja. Esto simplemente no es cierto porque tendrás que perseguir esos cargos. Puedes encontrar colisiones más arriba y más abajo en el árbol hasta donde puedo ver.
malta