Chr*_*s H 7 voronoi scipy python-2.7 qhull
我在Python 2.7中使用Scipy 0.13.0来计算3d中的一组Voronoi单元.我需要获得每个单元的体积以(de)加权专有模拟的输出.有没有简单的方法这样做 - 当然这是一个常见的问题或Voronoi细胞的常见用途,但我找不到任何东西.运行以下代码,并转储scipy.spatial.Voronoi手册所知道的所有内容.
from scipy.spatial import Voronoi
x=[0,1,0,1,0,1,0,1,0,1]
y=[0,0,1,1,2,2,3,3.5,4,4.5]
z=[0,0,0,0,0,1,1,1,1,1]
points=zip(x,y,z)
print points
vor=Voronoi(points)
print vor.regions
print vor.vertices
print vor.ridge_points
print vor.ridge_vertices
print vor.points
print vor.point_region
Run Code Online (Sandbox Code Playgroud)
如评论中所述,您可以计算每个Voronoi单元的ConvexHull。由于Voronoi细胞是凸的,您将获得适当的体积。
def voronoi_volumes(points):
v = Voronoi(points)
vol = np.zeros(v.npoints)
for i, reg_num in enumerate(v.point_region):
indices = v.regions[reg_num]
if -1 in indices: # some regions can be opened
vol[i] = np.inf
else:
vol[i] = ConvexHull(v.vertices[indices]).volume
return vol
Run Code Online (Sandbox Code Playgroud)
此方法适用于任何尺寸
我想我已经破解了它。我的方法如下:
我确信会有错误和糟糕的编码 - 我将寻找前者,欢迎对后者发表评论 - 特别是因为我对 Python 还很陌生。我仍在检查一些事情 - 有时给出 -1 的顶点索引,根据 scipy 手册“指示 Voronoi 图之外的顶点”,但此外,生成的顶点的坐标远远超出原始数据(插入numpy.random.seed(42)
并检查点7的区域坐标,它们转到~(7,-14,6),点49类似。所以我需要弄清楚为什么有时会发生这种情况,有时我得到索引-1。
from scipy.spatial import Voronoi,Delaunay
import numpy as np
import matplotlib.pyplot as plt
def tetravol(a,b,c,d):
'''Calculates the volume of a tetrahedron, given vertices a,b,c and d (triplets)'''
tetravol=abs(np.dot((a-d),np.cross((b-d),(c-d))))/6
return tetravol
def vol(vor,p):
'''Calculate volume of 3d Voronoi cell based on point p. Voronoi diagram is passed in v.'''
dpoints=[]
vol=0
for v in vor.regions[vor.point_region[p]]:
dpoints.append(list(vor.vertices[v]))
tri=Delaunay(np.array(dpoints))
for simplex in tri.simplices:
vol+=tetravol(np.array(dpoints[simplex[0]]),np.array(dpoints[simplex[1]]),np.array(dpoints[simplex[2]]),np.array(dpoints[simplex[3]]))
return vol
x= [np.random.random() for i in xrange(50)]
y= [np.random.random() for i in xrange(50)]
z= [np.random.random() for i in xrange(50)]
dpoints=[]
points=zip(x,y,z)
vor=Voronoi(points)
vtot=0
for i,p in enumerate(vor.points):
out=False
for v in vor.regions[vor.point_region[i]]:
if v<=-1: #a point index of -1 is returned if the vertex is outside the Vornoi diagram, in this application these should be ignorable edge-cases
out=True
else:
if not out:
pvol=vol(vor,i)
vtot+=pvol
print "point "+str(i)+" with coordinates "+str(p)+" has volume "+str(pvol)
print "total volume= "+str(vtot)
#oddly, some vertices outside the boundary of the original data are returned, meaning that the total volume can be greater than the volume of the original.
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7448 次 |
最近记录: |