2009-08-23 14 views
12

Tengo una nube de puntos 3D y me gustaría consultar eficientemente todos los puntos dentro de la distancia d desde un punto arbitrario p (que no es necesariamente parte de la nube de puntos almacenado)cuya estructura de datos es adecuada para consultar "todos los puntos dentro de la distancia d desde el punto p"

la consulta sería algo como

Pointcloud getAllPoints(Point p, float d); 

lo accelerationstructure sería apropiado para esto? Un árbol de rango parece ser apropiado solo para consultar volúmenes rectangulares, no volúmenes esféricos (por supuesto, podría consultar el cuadro delimitador de la esfera y luego ordenar todos los vértices que tengan una distancia mayor que d, pero tal vez haya una mejor manera de hacerlo esto ??)

gracias!

acuerdo con Novelocrats sugerencia, trato de definir las funciones deseadas de la estructura:

SearchStructure Create(Set<Point> cloud) 
Set<Point> Query(SearchStructure S, Point p, float maxDistance) 
SearchStructure Remove(Point p) 
SearchStructure Insert(Point p) 
SearchStructure Displace(Set<Point> displacement) //where each value describes an offsetVector to the currently present points 

Por lo general, después de n consultas, los puntos quedan desplazados y unos pocos (no muchos!) Se hacen inserciones y deleciones . los vectores de desplazamiento son muy pequeños en comparación con el cuadro delimitador de todos los puntos

+0

Creo que la creación de tiempo lineal podría estar pidiendo demasiado, y podría desalentar a las personas a proporcionar buenas respuestas a la pregunta principal. ¿Constantemente estás consultando nuevas nubes puntuales también? Si los nuevos puntos son el resultado de cambios en el existente, la modificación de la estructura puede ser más económica. – Novelocrat

+1

"Query" tiene solo una 'r'. Sugiero arreglar eso para la posteridad. – Novelocrat

+0

Novelocrat: tienes razón: los nuevos puntos son modificaciones de los antiguos, pero bastante difíciles (todos los puntos se mueven, cada uno en otra dirección, también se pueden agregar nuevos puntos que no estaban presentes antes) así que recreé el mapa cada vez será el mejor. habrá aproximadamente n tales consultas para un mapa que contenga n puntos, antes de que la nube de puntos se mueva –

Respuesta

0

Un mapa con una clave igual a la distancia y el valor del Punto en sí mismo le permitiría consultar todos los puntos a menos de una distancia determinada o dentro de un rango determinado.

+0

la distancia no puede ser clave, ya que p es un punto arbitrario (por lo tanto p es un argumento de la querry - no era lo suficientemente específico en eso) –

+0

Una vez que especifique el punto, rellene la estructura de datos. Cambia el punto, repobla. Creo que todavía funciona – duffymo

+0

el punto es diferente en cada consulta. actualizar todas las distancias al punto p ya necesitaría O (n) tiempo –

0

Bueno, depende de qué otros usos necesite para la estructura de datos.

Puede tener una lista de distancias del punto p a otros puntos, ordenadas por distancia, y asignar estas listas a los puntos con un hashmap.

map: 
p1 -> [{p2, d12}, {p4, d14}, {p3, d13}] 
p2 -> ... 
... 

Puede buscar el punto en el mapa e iterar la lista hasta que la distancia sea más alta que la requerida.

6

Lo que quiere es una estructura que descompone el espacio para que las regiones particulares se puedan encontrar de manera eficiente. Una descomposición octree o kD-tree debería permitirle hacerlo bien, ya que solo 'abrirá' la sección del árbol que contiene su punto p para buscar puntos cercanos. Esto debería permitirle poner un límite asintótico bastante bajo sobre la cantidad de puntos extra que necesita para comparar la distancia (sabiendo que debajo de cierto nivel de descomposición, todos los puntos están lo suficientemente cerca). Desafortunadamente, no conozco la literatura en esta área lo suficientemente bien como para dar indicaciones más detalladas. Mi encuentro con estas cosas proviene del algoritmo de simulación Barnes-Hut n-Body.

Aquí está another question estrechamente relacionado con este. y another. Y a third, mencionando una estructura de datos (Hilbert R-Trees) de la que no había oído hablar anteriormente.

+0

Pienso en el octárbol pero parece que no es apropiado, ya que hay dos puntos que están dentro del rango d, que se encuentran en otra sección distinta de p. así que uno debería consultar todas las secciones que se cruzan con la esfera definida por p y d –

+0

. Ese es un buen punto. Si hubiera alguna variante del árbol de rango de octrees, entonces estarías dorado. – Novelocrat

+1

SciPy tiene una implementación de KDTree, y tiene una función llamada [query_ball_point] (http://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.KDTree.query_ball_point.html) que hace exactamente esto. – sffc

1

No entiendo su API, puede redondear todos los puntos en un PointCloud que se encuentran dentro de una esfera arbitraria, pero también dice que las nubes de puntos están almacenadas? En ese caso, ¿no debería obtener una lista de PointClouds que se encuentra dentro de la esfera dada? De lo contrario, ¿cuál es el punto (excusa del juego de palabras) para almacenar PointClouds?

En lugar de tratar de definir la API de antemano, defínala cuando la necesites. No es necesario implementar algo que nunca se utilizará, y mucho menos optimizar una función que nunca se llamará (a menos que sea por diversión, por supuesto :)).

Creo que debería implementar el sacrificio de caja delimitadora, seguido de la búsqueda de esfera más detallada como primera implementación. Tal vez no sea un cuello de botella como piensas, y tal vez tengas cuellos de botella mucho más serios que considerar. Siempre es posible optimizarlo más tarde cuando realmente vea que tiene todo funcionando en conjunto como lo planeó.

Cuestiones relacionadas