Nota importante: Esta resposta não responde à pergunta real, mas foi deixada de ser anulada por solicitação. Embaraçosamente, confundi hexaédrico e hexagonal. A pergunta é sobre a classificação de pontos em células hexaédricas arbitrárias em 3D, enquanto essa solução classifica pontos em células hexagonais regulares em 2D, ou irregulares que correspondem a algum mosaico de Voronoi em qualquer dimensão. Este método é aplicável apenas se a malha foi gerada como um mosaico de Voronoi em primeiro lugar (o que parece ser uma abordagem usada ocasionalmente ).
Não sei ao certo o que você quer dizer com classificação aqui, mas presumo que você queira classificar o ponto em caixas hexagonais no avião.
O Mathematica é o que eu sei, então vou mostrar como fazer no Mathematica, mas o método pode ser portado para outros sistemas. A idéia é que uma rede hexagonal seja o dual de uma triangular: ela pode ser gerada como o diagrama de Voronoi de um ponto em arranjo triangular. Um ponto da nuvem pertence a um dado hexágono se estiver mais próximo do centro desse hexágono do que do centro de qualquer outro hexágono.
Este método também funcionará para malhas de diferentes formas, desde que possam ser geradas como o diagrama de Voronoi de algum arranjo de pontos. (Por exemplo, os hexágonos não precisam ser regulares.)
Vamos gerar a malha. Esta é uma estrutura 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]
Seu dual é o hexagonal em que estamos interessados:
DiagramPlot[points, LabelPoints -> False]
Isso cria uma função nf
que encontra o índice do centro do hexágono ao qual algum ponto da nuvem está mais próximo. É a chave do método:
nf = Nearest[N[points] -> Range@Length[points]];
Agora vamos gerar uma nuvem de 1000 pontos aleatórios e classificá-los com nf
:
cloud = RandomReal[{-1/2, 5}, {1000, 2}];
indices = First /@ nf /@ cloud;
indices
contém os índices dos centros aos quais cada ponto da nuvem está mais próximo. Esta é a informação que precisávamos. Agora podemos fazer um histograma com eles ...
Histogram[indices]
... ou colorir cada um deles ...
Show[
DiagramPlot[points, LabelPoints -> False],
Graphics@MapThread[{ColorData[3][#1], Point[#2]} &, {indices, cloud}],
PlotRange -> All, AspectRatio -> Automatic
]
... ou qualquer tipo de visualização sofisticada que desejamos.
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 - #] &)]
O ponto principal aqui foi a função que encontra o ponto mais próximo de algo ( Nearest
). O Mathematica possui isso, mas há uma chance de seu sistema não. Se for esse o caso, consulte esta pergunta sobre como implementar eficientemente essa função (ou apenas siga a ingênua implementação de tempo linear se você não tiver uma quantidade enorme de pontos a serem processados).