Determinando se a remoção de um voxel interromperá um grupo

8

Eu tenho a seguinte situação: Eu tenho uma grade 3d de voxels (ativado / desativado, o tamanho máximo é provavelmente 128x128x128). Sei de antemão que, dentro da rede, todos os voxels que estão ligados estão interconectados, formando um único grupo.

Agora eu preciso determinar: quando eu remover um voxel (desligá-lo), ele irá dividir o grupo?

Minha idéia inicial foi examinar os vizinhos do voxel que foram removidos e determinar se eles ainda estão interconectados através de outros voxels (veja minha outra pergunta: Algoritmo para verificar se dois voxels estão interconectados ). Mas pode haver outras / melhores maneiras de fazer isso.

Então, qual seria uma boa maneira de determinar se a remoção de um voxel interromperá o grupo do qual fazia parte?

Bram Vaessen
fonte

Respostas:

4

Eu cobri isso um pouco no meu outro comentário, mas acho que aqui você está pensando em classificação externa / interna. Ao remover um voxel, você está alterando os voxels ao seu redor para voxels 'de ponta' (se já não o foram). Isso deve se resumir a três casos reais (a simetria leva o resto deles) - no exemplo abaixo, os números são os IDs do grupo, o - é o voxel sendo removido

11      2    
1-     1-     1-2
  • O primeiro caso é trivial - é um canto, mas os voxels acima e à esquerda permanecem totalmente conectados pelo outro voxel.

  • O segundo caso: é um canto e o voxel removido desconectou os voxels acima e os esquerdos que estavam conectados anteriormente

  • O terceiro caso: é uma linha, e o voxel removido desconectou os voxels esquerdo e direito conectados anteriormente.

Se você identificar que os 2º ou 3º casos ocorreram, é necessário encontrar um caminho para verificar se 1 e 2 ainda estão conectados por outros voxels adjacentes.

Você pode obter alguma eficiência aqui, no entanto. Se um voxel é inteiramente interno a um grupo (ou seja, todos os 8 vizinhos fazem parte do mesmo grupo), ele pode ser descontado. Por quê? É uma coisa de topologia. Imagine o caso 2D - existem apenas duas possibilidades. Ou existe uma única aresta que, independentemente de como gira e gira, ainda forma um anel de voxels. Ou, existem dois anéis, um contendo um voxel e um contendo o outro. Por exemplo:

 xxx xxx
 x x-x x
 xxx xxx

ou

 xxxxxxx
 x     x
 xxx xxx
   x-x 
 xxx xxx

Isso também deve se estender para o 3D, exceto que, em vez de um anel de limite, você terá uma superfície de limite. Portanto, ao tentar determinar se os dois voxels desconectados recentemente ainda estão conectados, é possível excluir todos os voxels internos do percurso, porque, por definição, se um voxel está conectado a qualquer um dos voxels de limite de um grupo, também é conectado a todos os voxels internos nesse grupo.

É o efeito inverso dos voxels de hub de que falei na minha resposta à outra pergunta - você não precisa encontrar o caminho de todos os voxels para todos os outros voxels, apenas o caminho para os voxels interessantes .

MrCranky
fonte
Obrigado, apenas o uso dos voxels na superfície do volume parece uma otimização muito boa.
Bram Vaessen
3

Se você estiver usando A *, poderá utilizá-lo aqui.

Começando com uma lista dos voxels que estavam conectados ao voxel removido. Comece com o primeiro da lista, use A * para encontrar um caminho para o segundo na lista. Se existir um caminho, encontre um caminho do segundo ao terceiro, terceiro ao quarto e assim por diante.

A maioria dessas pesquisas será muito rápida, porque os voxels estarão próximos um do outro. Se houver algum caminho que falhe, significa que uma descontinuidade foi criada.

Isso deve ser muito fácil de implementar se você já tiver a funcionalidade A * implementada.

MichaelHouse
fonte