Determining and storing Voronoi Cell Adjacency

耗尽温柔 提交于 2019-12-03 08:45:06

Although this is an old question, I was searching for same and thought that the answer might still be helpful for somebody. One can use Delaunay from scipy module.

from scipy.spatial import Delaunay
from collections import defaultdict
import itertools

points=[[0.0, 0.0], [0.0, 1.0], [0.2, 0.5], [0.3, 0.6], [0.4, 0.5], [0.6, 0.3], [0.6, 0.5], [1.0, 0.0], [1.0, 1.0]]
tri = Delaunay(points)
neiList=defaultdict(set)
for p in tri.vertices:
    for i,j in itertools.combinations(p,2):
        neiList[i].add(j)
        neiList[j].add(i)

for key in sorted(neiList.iterkeys()):
    print("%d:%s" % (key,','.join([str(i) for i in neiList[key]])))

0:1,2,5,7
1:0,8,2,3
2:0,1,3,4,5
3:8,1,2,4,6
4:2,3,5,6
5:0,2,4,6,7
6:8,3,4,5,7
7:8,0,5,6
8:1,3,6,7

# This is for visualization
from scipy.spatial import Voronoi, voronoi_plot_2d
import matplotlib.pyplot as plt
vor = Voronoi(points)
voronoi_plot_2d(vor)
for i,p in enumerate(x):
    plt.text(p[0], p[1], '#%d' % i, ha='center')
plt.show()

A possible algorithm is available here which uses a Linear Programming approach.

PuLP can generate MPS or LP files and call GLPK, COIN, CPLEX, and GUROBI to solve linear problems.

PuLP is an LP modeler written in Python and could be used to model this linear program in Python and then solve using GLPK.

You could do this in a few different ways.

If you just have access to the Voronoi diagram, you could look for shared edge segments between cells. If you find two cells that share a Voronoi edge segment it means that they are adjacent. An efficient way to build up the adjacency information for the whole data-set is to build a hash table of edges by scanning the list of Voronoi cells.

for (all cells in voronoi diagram)
    for (all edges in current cell)
        if (matching edge found in hash table)
            // the current cell is adjacent to the cell that added
            // the matching edge segment to the hash table
        else
            // push current edge segment onto hash table and mark with 
            // current cell index
        endif
    endfor
endfor

There are many good existing packages that can be used to calculate the Voronoi diagram/Delaunay triangulation for a point-set. Since it's a computationally expensive and numerically sensitive operation I'd recommend sticking with an existing library. The Triangle and QHull packages are widely used.

Hope this helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!