Computando o diagrama Voronoi de uma região dentro de uma caixa


8

Estou enfrentando um problema da seguinte forma: Tenho uma caixa cheia de pontos com uma certa distribuição desconhecida e gostaria de calcular o diagrama de Voronoï. O problema é que o número de pontos é tão grande que isso pode ser impossível para a distribuição completa.

Portanto, planejei fazer isso apenas em uma região dentro da caixa, onde o número de pontos não fosse tão grande. Para fazer isso, preciso saber como calcular a região mínima que pode afetar o diagrama Voronoi de uma determinada região menor dentro dessa caixa.

Em outras palavras, eu gostaria de calcular o diagrama Voronoï dos pontos dentro do pequeno cubo da figura abaixo que se encaixa no diagrama Voronoï que teria os pontos da caixa cheia armazenando o menor diagrama Voronoï possível na memória.

Explicação do problema.


3
Eu tenho visto pessoas, especialmente em astrofísica, computando a avaliação de vários conjuntos de pontos. Veja o trabalho de Volker Springel. Por exemplo, existe até um código-fonte aberto aqui github.com/regonzar/paravt que pode ser útil para você. Veja também arxiv.org/abs/1601.06429
cfdlab

Eu ainda precisaria de alguma maneira de fazer isso usando a estratégia do cubo pequeno, mas muito obrigado. Vou dar uma olhada nisso.
Ccorbella

1
Desculpe, estou com problemas para entender essa frase "Gostaria de calcular o diagrama Voronoï dos pontos dentro do pequeno cubo da figura abaixo que se encaixa no diagrama Voronoï que teria os pontos da caixa cheia armazenando o menor diagrama Voronoï possível na memória ".
nicoguaro

Desculpe, só queria dizer que gostaria de calcular o diagrama Voronoï do cubo pequeno, levando em consideração que esse deve ser o mesmo nessa região que o diagrama que eu obteria se calculasse usando todos os pontos da caixa. Para fazer isso, espero precisar de mais pontos do que aqueles que estão dentro da caixa (caso contrário, não acredito que possa se encaixar em outro cubo se eu seguir a mesma estratégia), mas gostaria de armazenar o mínimo possível pontos.
Ccorbella

@ccorbella Não é uma resposta, mas com que ferramenta você forneceu essa boa figura, por favor? Talvez adicione uma legenda à ferramenta.
Jan Hackenberg

Respostas:


2

Para calcular o diagrama de Voronoi de conjuntos enormes (> 100 milhões) de pontos, você pode usar o seguinte algoritmo:

1) create a kd-tree with all the points
2) for each point p [in parallel optionally]
     N = 10
     while not finished
       compute the N nearest neighbors of the point p
       compute the intersection of the N half-spaces defined by p 
       and the neighbors
       if there is a neighbor further away than 
         twice the radius of the ball centered on p and 
         bounding the intersection, finished = true
       N = N * 1.5
  // when exiting the loop, the computed intersection 
  // corresponds to the Voronoi cell of p, because no other bisector
  // can contribute to the Voronoi cell.

O algoritmo é explicado com mais detalhes no meu artigo . Pode ser trivialmente paralelizado (basta adicionar "#pragma omp paralelo para" antes do loop principal), pois não há dependência de dados. Ele é implementado na minha biblioteca de programação GEOGRAM C ++ (junto com uma Kd-Tree com eficiência de memória que pode atingir mais de 100 milhões de pontos). Observe que no GEOGRAM também há uma implementação Delaunay / Voronoi padrão paralela que funciona bem com até 100 milhões de sites.

Com relação à implementação paralela do algoritmo clássico (Boywer-Watson), a implementação do GEOGRAM está documentada aqui (consulte também o arquivo de origem c ++ associado que possui comentários extensos). Não tenho artigo publicado sobre isso, escreverei um se o tempo permitir. A idéia principal é usar spinlocks associados ao tetraedro para garantir que apenas um thread individual possa modificar um tetraedro.


Primeiro de tudo, obrigado pela sua resposta. Lamento informar que seu artigo parece não ter mais sido carregado (pelo menos a versão completa da web que você vincula). Enfim, você poderia me explicar como implementaria o algoritmo do diagrama Voronoi em paralelo?
Ccorbella

Obrigado por notificar isso, eu corrigi o link (o novo link possui o PDF, clique no ícone PDF para obtê-lo). Também adicionei uma breve explicação / link para a implementação paralela de Delaunay.
precisa saber é o seguinte

Nota: funcionará bem desde que os pontos sejam distribuídos uniformemente (o desempenho pode cair se você tiver uma alta variação na densidade de pontos).
BrunoLevy 02/09

2

Parece que os especialistas não estão respondendo à sua pergunta, então tentarei fornecer uma idéia. Porém, antes de fazer isso, sugiro fortemente que você procure na literatura alguns métodos sofisticados que já foram desenvolvidos. No entanto, sem garantir que seja uma sugestão boa, rápida ou eficiente, proponho a seguinte metodologia. Lembre-se de que eu cometi alguns erros, por isso não garanto que tudo esteja totalmente correto, mas espero que a idéia do método ofereça uma abordagem que o ajude a resolver seu problema.

Seja o conjunto dos seus pontos em todo o cubo "grande". Corrija seu cubo "pequeno" em algum lugar do cubo grande e deixe ser o conjunto de pontos contidos em , ou seja, Inicialmente, defina .C V C C V C = V C . V C = V CVCVCCVC=VC.VC=VC

Etapa 1: Gere o diagrama Voronoi . Para cada ponto denota por sua célula Voronoi, que é um poliedro convexo em três espaços. Além disso, denote por os vértices da célula de Voronoi centralizados em e por os vértices de todos os Voronoi células do diagrama de Voronoi .v V ' C V o r ( v ) W ( v ) v V « C W ( V ' C ) = v V « C W ( v ) V o R ( V C )Vor(VC)vVCVor(v)W(v)vVCW(VC)=vVCW(v)Vor(VC)

Etapa 2: todos os pontos de e todos os vértices de Voronoi branco. W ( V C )VCW(VC)

Etapa 3: para cada vértice de Voronoi desenhe a esfera de Delaunay centrada em , que é a esfera com centro e raio de distância entre e um dos pontos de cuja célula Voronoi possui como um vértice (não importa em que ponto, existem vários, mas o resultado é sempre o mesmo).w w w V C wwW(VC)wwwVCw

Caso 3.1. Se a esfera Delaunay de estiver contida no cubo , cor preto.C wwCw

Caso 3.2 Se a esfera de Delaunay não estiver contida no cubo mas não contiver nenhum ponto de em seu interior (aberto), preto o ponto .V wCVw

Caso 3.3. Se a esfera Delaunay de conter pontos de no seu interior (aberto), (1) adicionar os pontos de contido no interior da esfera para o conjunto e (2) manter a cor do ponto de branco . V V V C wwVVVCw

Etapa 4: para cada ponto verifique se todos os vértices Voronoi de sua célula Vornoi estão pretos. Se nem todos forem pretos, mantenha a cor branco. Se eles são pretos, cor preto. W ( v ) v vvVCW(v)vv

Etapa 5: verifique se todos os pontos do conjunto original são pretos.VC

Caso 5.1. Se eles são todos preto, o diagrama de Voronoi restrito ao cubo é a parte local da global de Voronoi diagrama restrito a . Fim.C V o R ( V ) CVor(VC)CVor(V)C

Caso 5.2. Se houver vértices brancos em , volte para a Etapa 1. Na Etapa 1, ao gerar o novo diagrama de Voronoi , as células de Voronoi mantêm as células pretas em torno dos pontos pretos de iguais, mantendo todas as pretas Voronoi vértices de e faz alteração apenas em relação aos brancos. V o R ( V ' C ) V ' C W ( V ' C )VCVor(VC)VCW(VC)

Eu espero que isso ajude.


1

A maneira mais simples de fazer isso é cercar sua caixa inerte com uma caixa maior que contenha pelo menos todos os vizinhos mais próximos dos pontos dentro de sua caixa interna. Observe que haverá um problema quando a caixa interna estiver próxima à borda da caixa de dados abrangente: você não possui pontos externos.

Calcular um mosaico de Voronoi / Delaunay pode ser mais sutil do que você imagina. Uma das questões é como decidir com precisão se um ponto está de um lado ou de outro de um plano / linha de mosaico.

Existe a biblioteca C ++ "CGAL" muito completa para fazer isso em http://www.cgal.org/ . Meus colegas e eu usamos isso em vários trabalhos publicados em astrofísica: parece ser sólido em lidar com todas as armadilhas potenciais na criação desses mosaicos.


Muito obrigado pela sua resposta. Então, minha pergunta deve ser reescrita, se você quiser, como "como encontrar os pontos vizinhos mais próximos daqueles que estão dentro do cubo fazendo o menor número de cálculos". Meu problema era basicamente esse. Você conhece alguma maneira de fazer isso?
Ccorbella

Como alguém decide o tamanho da caixa externa? Se não for grande o suficiente, talvez você não consiga restringir o diagrama completo à caixa pequena original. Eu acho que a decisão certa de resistir a um vértice de uma célula de voronoi a partir do diagrama local é um vértice do diagrama global, ou seja, um vértice que não será alterado por qualquer recálculo futuro do diagrama de voronoi local, se baseia no interior da esfera delaunay correspondente contém quaisquer pontos do conjunto total de pontos ou não. Essa é exatamente a definição de uma célula delaynay, que é dupla para uma célula voronoi.
precisa

@ConradCorbellaBagot Para o cálculo dos vizinhos mais próximos em um grande conjunto de dados n-dim, existe um algoritmo muito eficiente . Talvez você queira declarar o que realmente está interessado.
Bort

As pavimentações Voronoi / Delaunay estão bem definidas tanto em um conjunto de pontos infinitos quanto em um conjunto de pontos delimitado, mas não em um subconjunto de pontos de um conjunto maior. Para esses subconjuntos, você precisa tomar uma decisão de compromisso arbitrária. Na cosmologia, onde temos uma caixa finita em um universo infinito, escolhemos condições de contorno periódicas. Ao fazer uma análise de imagem em parte de uma imagem, eu "visto" o limite com os primeiros vizinhos mais próximos dos pontos que definem o limite (há complicações a serem consideradas). Acho que ir ao próximo vizinho mais próximo tem relativamente pouco ganho.
JonesTheAstronomer

Há uma apresentação detalhada de parte disso em adsabs.harvard.edu/abs/2011MNRAS.416.2494P, que pode ser baixada gratuitamente do jornal e do arXiv. Ele também discute a reconstrução não linear de Kriging de um campo de densidade usando esses mosaicos. A fonte de dados aqui é astronômica, mas a discussão é bastante genérica (para conjuntos de dados tridimensionais).
JonesTheAstronomer

1

Entendo sua pergunta como: Quero desenhar o diagrama de Voronoi para um subconjunto de pontos, de modo que seja o mesmo que é obtido quando se considera o conjunto completo de pontos. Os diagramas de Voronoi são desenhados juntando-se primeiro aos pontos vizinhos e depois desenhando um plano perpendicular à linha no ponto médio. Você faz isso para todos os vizinhos mais próximos e possui um diagrama de voronoi na vizinhança de um ponto. Faça isso para todos os pontos e você terá um diagrama voronoi para todos os pontos. Veja bem, os diagramas de voronoi são definidos localmente. Não há segundo segundo vizinho mais próximo ou terceiro efeito de vizinho mais próximo. Apenas o primeiro efeito vizinho mais próximo. Então, tudo o que você precisa fazer para obter um diagrama de voronoi com um subconjunto de pontos é identificar os pontos na sub-região de interesse, conectá-los a todos os respectivos vizinhos mais próximos, e desenhe um plano passando pelos pontos médios desse segmento de linha e perpendicular ao segmento de linha. Este diagrama será o mesmo para uma região local, independentemente de você considerar uma sub-região ou uma região completa.


Duas questões. Antes de tudo, "Há o segundo vizinho mais próximo ou o terceiro efeito de vizinho mais próximo" deve ser "Não há ...", certo?
Ccorbella

Sim. Obrigado por apontar isso. Atualizarei a resposta.Qual é a segunda pergunta?
Kaustubh Kaluskar

Desculpe, eu estava editando o comentário xDD E o outro, eu sei que os diagramas de Voronoi são definidos localmente (sob outras condições, minha pergunta não teria resposta). Minha pergunta deve ser reescrita, se você desejar, como "como encontrar os pontos vizinhos mais próximos daqueles que estão dentro do cubo fazendo o menor número de cálculos". Você conhece alguma maneira de fazer isso? De qualquer forma, muito obrigado pelo seu tempo.
Ccorbella

1
Eu uso a função knnsearch no MATLAB. Meu conjunto de dados típico é de cerca de 1,5 milhão de pontos e faço no meu laptop. No site da Mathworks: 'IDX = knnsearch (X, Y) localiza o vizinho mais próximo em X para cada ponto em Y. IDX é um vetor de coluna com minhas linhas. Cada linha no IDX contém o índice do vizinho mais próximo em X para a linha correspondente em Y. ' Aqui X seria seu conjunto de dados completo e Y são pontos dentro do cubo.
Kaustubh Kaluskar

Antes de tudo, muito obrigado mais uma vez. Vou tentar com firmeza Não tenho certeza se sou capaz de executar um algoritmo como uma árvore kd em um número tão grande de pontos, pois diz que "Para dimensões grandes (20 já é grande), não espere que isso aconteça. executar significativamente mais rápido do que a força bruta alta-dimensional vizinho mais próximo consultas são um problema em aberto substancial em ciência da computação ".....
ccorbella

-2

Sugiro que você tenha uma abordagem visual e intuitiva usando o Grasshopper for Rhinoceros3D. Embora o Rhinoceros seja um pacote CAD comercial e o Grasshopper seja um plug-in para ele, você pode executar plug-ins gratuitamente, sem limitações e fazer seus experimentos (o Rhino3D sem licença limita apenas o salvamento dos arquivos Rhino). O Grasshopper inclui um grande número de funções matemáticas usadas em uma tela, e os diagramas de Voronoi 3D são um deles. um cubo Voronoi feito com Grasshopper3D no Rhino3D


2
O link é interessante, mas isso não responde à pergunta.
precisa saber é o seguinte

Não era o que eu estava pedindo, mas obrigado pela ferramenta.
Ccorbella
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.