Algoritmo para ver si dos voxels están interconectados

11

Estoy buscando un buen algoritmo para el siguiente problema: dada una cuadrícula 3D de vóxeles (que puede estar vacía o llena), si elijo dos vóxeles no adyacentes, quiero saber si están conectados entre sí por otros vóxeles

Por ejemplo (para ilustrar la situación en 2D), donde # es un cuadrado relleno:

  1 2 3
a # # #
b # #
c # # #

Si elijo a3 y c3, quiero determinar lo más rápido posible si están conectados; si hay una ruta entre a3 y c3 a través de píxeles rellenos. (La situación real está en una cuadrícula de vóxeles 3D, por supuesto).

He analizado los algoritmos de inundación y los algoritmos de búsqueda de rutas, pero no estoy seguro de cuál elegir. Ambos realizan un trabajo innecesario: el relleno de inundación intenta llenar todos los vóxeles, pero esto no es necesario. Los algoritmos de búsqueda de ruta generalmente se ocupan de encontrar la ruta más corta, que tampoco es necesaria. Sólo necesito saber si hay es un camino.

¿Qué algoritmo debería usar?

Editar: según los comentarios, creo que debería agregar lo siguiente: el contenido de los vóxeles no se conoce de antemano, y también, el algoritmo es necesario para detectar si la eliminación (vaciado) de un vóxel podría romper el grupo de vóxeles en dos o más grupos más pequeños.

Bram Vaessen
fuente
En el ejemplo sería una ruta válida de A3 a c3 ser la siguiente: c3->c2->b2->a2->a3?
eso es correcto
Bram Vaessen

Respuestas:

12

A * funcionaría bien. Encontrar la ruta es lo que desea, encontrar la ruta más corta es tan rápido (o más rápido) que encontrar cualquier ruta. En esta situación, A * es probablemente el más adecuado dado que tiene un punto de inicio y finalización. Esto significa que tiene la heurística adicional para acelerar la búsqueda.

Con A *, generalmente, la primera ruta que encuentra es la más corta, por lo que no está haciendo un trabajo adicional después de que ya haya encontrado una ruta.

ingrese la descripción de la imagen aquí

Para algunas optimizaciones, mira mi respuesta aquí .

MichaelHouse
fuente
parece que realmente dispara hacia adelante hasta que golpea esa pared y luego se arrastra
GameDev-er
1
@ GameDev-er Sí, eso se debe a la heurística. Si no hubiera obstáculo, sería una búsqueda muy rápida, casi una línea recta.
MichaelHouse
Con una mejor clasificación de los nodos, esto expandiría primero la ruta más cercana al nodo final. Si tiene una estructura de datos rápida para ordenar los nodos, ordénelos por distancia al objetivo para la ruta más directa.
MichaelHouse
9

Si está preparado para hacer un preprocesamiento y reducir el costo de almacenamiento, entonces la división de los vóxeles en grupos conectados en el momento de la compilación da una respuesta obvia a '¿hay algún camino?' Hay un camino entre dos vóxeles si están en el mismo grupo. El problema con eso obviamente es que tiene que almacenar información de grupo en algún lugar, y eso depende de su diseño de datos. Si está almacenando una lista simple, puede dividirla en varias listas, una para cada grupo espacialmente conectado. Si se está organizando en algún tipo de BVH, entonces probablemente podría obtener algunas eficiencias razonablemente buenas si puede decir "todos los vóxeles en este nodo y debajo pertenecen al grupo X".

Alternativamente, podría hacer un pre-partición espacial y almacenar un conjunto más pequeño de vóxeles 'hub' para cada grupo conectado. A continuación, puede buscar rutas desde los vóxeles de origen y destino al vóxel del centro más cercano, que debería ser una ruta mucho más corta / más barata de calcular. Si puede encontrar una ruta desde un voxel a un hub voxel, entonces el voxel es parte del grupo del hub voxel. Con la selección inteligente de esos vóxeles de concentrador, puede minimizar el número de recorridos de ruta. Por ejemplo, una esfera puede tener un solo voxel hub en su centro, pero un grupo largo y delgado puede tener un voxel hub cada X voxels a lo largo de su longitud. Si los vóxeles de origen y destino están en cualquiera de los extremos de la longitud, solo tienen que ir a la mayoría de los vóxeles X para encontrar un centro, y aunque puede haber una gran cantidad de vóxeles entre el inicio y el final de la longitud,

Todo depende de cuán patológicos sean sus grupos de voxel: si espera una gran cantidad de grupos desconectados pequeños, el aumento en el costo de almacenamiento va a superar enormemente el impacto en el rendimiento de solo encontrar rutas. Si espera relativamente pocos grupos conectados pero con topologías extrañas, entonces la búsqueda ingenua de rutas puede ser enormemente costosa y el costo de almacenamiento y la búsqueda mínima de rutas es una opción mucho más barata.

MrCranky
fuente
1
Esta es la respuesta correcta, pero para implementarla eficientemente, no debe almacenarse como una lista. Agregue un puntero a cada vóxel que apunte a su "vóxel representativo", que configura mediante el algoritmo de búsqueda de unión. Este es un costo de almacenamiento constante por vóxel, y básicamente lineal en el número de bordes para el costo computacional.
Neil G
Ideas interesantes, pero hay dos cosas que pueden complicar la situación. El primero es que el contenido de la cuadrícula de voxel no se conoce de antemano, por lo que para hacer voxels hub, también necesitaría un algoritmo que pueda determinar qué voxels deberían ser hubs.
Bram Vaessen
1
El segundo problema es que el algoritmo es necesario justo después de la eliminación de un vóxel, para determinar si el grupo del que forma parte se divide en grupos más pequeños debido a la eliminación de ese vóxel.
Bram Vaessen
@BramVaessen Si está buscando todas las relaciones de interconectividad por pares, y en particular, si los grupos se `` separan '', entonces ese es un asunto algo diferente a la simple accesibilidad (aunque la accesibilidad es la forma más fácil de hacerlo); Recomiendo agregar más detalles sobre lo que buscas específicamente a la pregunta original, ya que puede permitir mejores respuestas al 'problema detrás de la pregunta'.
Steven Stadnicki
Para mantenerlo limpio, he preguntado mi problema inicial en una pregunta diferente aquí gamedev.stackexchange.com/questions/50953/…
Bram Vaessen
4

No estoy muy familiarizado con los vóxeles, pero me imagino que podría obtener un rendimiento bastante bueno utilizando el mejor algoritmo de búsqueda como A *. El problema con el uso de A * en este caso es que la heurística que usaría normalmente está diseñada para priorizar la búsqueda del camino más corto y no 'cualquier camino' lo más rápido posible.

Es posible que tenga suerte usando una heurística alternativa que expande menos nodos como

f (p) = g (p) + w (p) * h (p)

donde w> = 1. disminuye el valor de 'w' cuanto más se acerca a la meta, dando así una mayor prioridad al costo de la ruta 'g' cuanto más se acerca al vóxel que está buscando.

¡Espero que esto ayude!

Matthew R.
fuente