QuadTree: ¿almacenar solo puntos o regiones?


9

Estoy desarrollando un quadtree para realizar un seguimiento de los objetos en movimiento para la detección de colisiones. Cada objeto tiene una forma delimitadora, digamos que son todos círculos. (Es un juego 2D de arriba hacia abajo)

No estoy seguro de si almacenar solo la posición de cada objeto o toda la forma delimitadora.

Si trabaja con puntos, la inserción y subdivisión es fácil, porque los objetos nunca abarcarán múltiples nodos. Por otro lado, una consulta de proximidad para un objeto puede perder colisiones, ya que no tendrá en cuenta las dimensiones de los objetos. ¿Cómo calcular la región de consulta cuando solo tienes puntos?

Colisión entre objetos de nodos vecinos

Si trabaja con regiones, ¿cómo manejar un objeto que abarca varios nodos? ¿Debería insertarse en el nodo primario más cercano que lo contiene por completo, incluso si esto excede la capacidad del nodo?

¿Qué nodo debe contener el objeto rojo?

Gracias.

Respuestas:


4

Si almacena objetos extendidos (regiones) en un árbol cuádruple, se debe hacer referencia al objeto desde todos los nodos hoja que toca. No trataría de encontrar el antepasado menos común y almacenarlo allí, porque entonces, por ejemplo, un objeto pequeño que cruza un límite de alto nivel terminará en un nodo muy alto y debe probarse contra todo lo demás en ese gran , nodo de alto nivel cuando realiza consultas de colisión y similares.

Sin embargo, también debe tener cuidado porque los objetos grandes podrían terminar siendo referenciados desde muchos nodos, lo que los hace costosos de actualizar cuando se mueven y hace que se vuelvan a verificar muchas veces para detectar colisiones, etc. Dependiendo de su caso de uso, Puede valer la pena usar algún tipo de heurística para almacenar objetos grandes en un nivel superior en el árbol, pero esto complicaría los algoritmos, por lo que probablemente no me moleste a menos que establezca que realmente es un problema de rendimiento en su caso particular.

Del mismo modo, para consultar una región, la consulta debe mirar todos los nodos hoja que toca la región consultada.

Básicamente, utilizan el mismo algoritmo, que es comenzar con una región y empujarla hacia abajo a través del árbol para encontrar los nodos de hoja que toca. Es un recorrido de profundidad primero, pero en cada nodo puede podar a cualquier niño que no toque la región. Tendrá que mantener una pila para realizar un seguimiento de dónde se encuentra en el recorrido.


Gracias, esto tiene sentido. Claro, el procesamiento de objetos de nodo cruzado sería más lento que los objetos que están completamente dentro de un nodo, pero no puedo ver nada al respecto. Podría aumentar la capacidad del nodo para mantener baja la fragmentación, pero esto aumentaría el número de objetos incluidos en la detección de colisiones. Jugaré con eso para encontrar un buen equilibrio.
alekop

4

Debe almacenarlo en el nodo más pequeño que lo contenga por completo, incluso si esto excede la capacidad (use un contenedor redimensionable).


2

Agregaría esto como un comentario en respuesta a la respuesta de @Nathan Reed, excepto que es demasiado grande para ser un comentario, y quizás en cualquier caso sea digno de ser una respuesta separada.

Estábamos haciendo exactamente lo que se propuso en su respuesta, y de hecho hemos comentado en la fuente que enlaza con esta página. En su mayor parte, ha funcionado extremadamente bien, excepto que una vez cada dos o tres meses, hemos estado perdiendo un servidor al azar que no responde debido a la duración masiva de las consultas de búsqueda.

La causa raíz del problema me llamó la atención mientras hacía una verificación de rendimiento para tratar de averiguar qué estaba causando esto. Es probable que solo sea una preocupación si permite la superposición de objetos. En nuestro juego lo hacemos, y en el peor de los casos, ocasionalmente conduce a un pico de profundidad que mata el rendimiento.

Tuvimos un caso de borde donde cerca de 100 objetos, todos con discos delimitadores, se agruparon muy cerca. Eso condujo al problema de una espiga muy profunda en el árbol, porque llegamos al punto en que los objetos eran más grandes que el área cubierta por los nodos quadtree, por lo que cada nuevo objeto se mostraba en múltiples nodos, lo que conducía a una subdivisión masiva del árbol, por lo que el problema se descontrola.

La conclusión de esto es que si permite que las regiones de objetos se superpongan, vigile de cerca las cosas si obtiene grupos apretados de objetos, para asegurarse de que su árbol no sea demasiado profundo.

La solución que estoy investigando actualmente es almacenar objetos como puntos, y luego, al hacer una búsqueda, aumentar los límites del rectángulo de búsqueda en el radio máximo almacenado en el árbol. Eso debería funcionar para nosotros, ya que el árbol es una búsqueda de primer paso, luego hacemos una verificación de rango basada en un círculo verdadero, junto con algunas otras verificaciones de criterios, por lo que las alertas falsas adicionales se filtrarán.

Su kilometraje real puede variar.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.