Ordenar una nube de puntos con respecto a una malla no estructurada de células hexaédricas

11

Pregunta

¿Cómo ordenaría una nube de puntos con respecto a una malla no estructurada de células hexaédricas?

Cada celda tiene un centro y una etiqueta única para representarlo. Básicamente, hay dos puntos de nube (nube de puntos original y una nube de puntos de los centros celulares), pero la información de geometría celular (cuadro delimitador) puede ser útil, no estoy seguro.

Resultados

He hecho algunas preguntas y busqué en la literatura:

Si la malla es hexaédrica y no estructurada, el problema se reduce a una búsqueda de rango ortogonal. Para este propósito, los árboles kd se usan con mayor frecuencia. Si la malla se refina en base a una estructura de datos de octree, el algoritmo de búsqueda de rango se puede construir a su alrededor. El objetivo es evitar tratar con la geometría de malla directa y concentrarse en la nube de puntos A - relación de la nube de puntos B. Nube de puntos A: puntos de consulta, nube de puntos B: centros de celdas de malla.

tmarico
fuente
¿Puedes aclarar lo que quieres decir cuando dices "ordenar con respecto a (cualquier tipo de) malla"? ¿Está buscando un algoritmo de agrupamiento (cuántos puntos hay en cada celda)?
Szabolcs
No entiendo su pregunta con bastante claridad, ¿cuál es el objetivo de ordenar los puntos? ¿Te gusta hacer la malla más regular?
Shuhao Cao
Hay una nube de puntos separada dispersa a través de la malla de volumen no estructurado. Necesito comunicar datos de los centros celulares a la nube de puntos y viceversa.
tmaric
1
@ tomislav-maric: ¿Podría escribir su solución como respuesta y luego aceptar su propia respuesta? Este procedimiento es generalmente la práctica aceptada para responder su propia pregunta de manera efectiva, en lugar de agregar la etiqueta "[SOLUCIONADO]" a la pregunta; Además, le dará más reputación, porque la gente puede votar su respuesta.
Geoff Oxberry

Respuestas:

8

Nota importante: esta respuesta no responde la pregunta real, pero se dejó sin recuperar por solicitud. Vergonzosamente confundí hexaédrica y hexagonal. La pregunta es sobre la clasificación de puntos en celdas hexaédricas arbitrarias en 3D, mientras que esta solución clasifica los puntos en celdas hexagonales regulares en 2D o irregulares que corresponden a alguna teselación de Voronoi en cualquier dimensión. Este método es aplicable solo si la malla se generó como una teselación de Voronoi en primer lugar (lo que parece ser un enfoque utilizado ocasionalmente ).


No estoy seguro de qué quieres decir con ordenar aquí, pero supongo que quieres ordenar el punto en contenedores hexagonales en el avión.

Mathematica es lo que sé, por lo que le mostraré cómo hacerlo en Mathematica, pero el método se puede transferir a otros sistemas. La idea es que una red hexagonal es la dual de una triangular: se puede generar como el diagrama de Voronoi de puntos en disposición triangular. Un punto de la nube pertenece a un hexágono dado si está más cerca del centro de ese hexágono que del centro de cualquier otro hexágono.

Este método también funcionará para mallas de diferentes formas, siempre que se puedan generar como el diagrama de Voronoi de algún arreglo de puntos. (Por ejemplo, los hexágonos no necesitan ser regulares).


Generemos la malla. Esta es una red triangular:

pts = Join @@ Table[{x, Sqrt[3] y}, {x, 0, 4}, {y, 0, 2}];

points = Join[pts, TranslationTransform[{1/2, Sqrt[3]/2}] /@ pts];

Needs["ComputationalGeometry`"]
PlanarGraphPlot[points, LabelPoints -> False]

Gráficos de Mathematica

Su dual es el hexagonal que nos interesa:

DiagramPlot[points, LabelPoints -> False]

Gráficos de Mathematica

Esto crea una función nfque encuentra el índice del centro del hexágono al que algún punto de la nube está más cercano. Es la clave del método:

nf = Nearest[N[points] -> Range@Length[points]];

Ahora generemos una nube de 1000 puntos aleatorios y ordénelos con nf:

cloud = RandomReal[{-1/2, 5}, {1000, 2}];

indices = First /@ nf /@ cloud;

indicescontiene los índices de los centros a los que cada punto de nube está más cercano. Esta es la información que necesitábamos. Ahora podemos hacer un histograma con ellos ...

Histogram[indices]

Gráficos de Mathematica

... o colorear cada uno de ellos ...

Show[
 DiagramPlot[points, LabelPoints -> False],
 Graphics@MapThread[{ColorData[3][#1], Point[#2]} &, {indices, cloud}],
 PlotRange -> All, AspectRatio -> Automatic
 ]

Gráficos de Mathematica

... o hacer cualquier tipo de visualización elegante que queramos.

tally = Tally[indices];

ListDensityPlot[Join[points, List /@ Sort[tally][[All, 2]], 2], 
 InterpolationOrder -> 0, 
 Epilog -> (Text[#2, points[[#1]]] & @@@ tally), 
 PlotRange -> {{-.5, 5}, {-.5, 5}}, Mesh -> All, 
 ColorFunction -> (ColorData["BeachColors"][1 - #] &)]

Gráficos de Mathematica


El punto clave aquí fue la función que encuentra el punto más cercano a algo ( Nearest). Mathematica tiene esto incorporado, pero existe la posibilidad de que su sistema no. Si este es el caso, vea esta pregunta sobre cómo implementar eficientemente dicha función (o simplemente siga con la ingenua implementación de tiempo lineal si no tiene una gran cantidad de puntos para procesar).

Szabolcs
fuente
¡Muchas gracias! Básicamente, lo que necesito es una relación que muestre una conexión entre cada punto y un "contenedor" como lo llamaste (caja hexaédrica tridimensional). Lo que sugieres parece muy interesante, pero estoy lidiando con mallas de millones de cajas y cientos de miles de puntos potencialmente. La pregunta es qué cuesta más: creación de doble malla o trabajar con cajas delimitadoras de los "contenedores" y usar un kd Árbol para buscar. Soy muy nuevo en este tema, así que realmente no quiero ir en la dirección equivocada.
tmaric
k
¡No lo elimines definitivamente, alguien puede encontrarlo útil! :) Puede ser que faneca sea la solución al problema, es solo que todavía no puedo aceptarlo hasta que lo lea.
tmaric
Y gracias por una respuesta tan detallada, si pudiera, ¡te daría más puntos! :)
tmaric
@ tomislav-maric Mirando los votos, me preocupa que mi respuesta disminuya la posibilidad de que obtenga una útil, o contribuya al malentendido. Creo que es más productivo si elimino.
Szabolcs