我想在Python中使用Delaunay Triangulation在3D中插入点。
我拥有的是
# my array of points
points = [[1,2,3], [2,3,4], ...]
# my array of values
values = [7, 8, ...]
# an object with triangulation
tri = Delaunay(points)
# a set of points at which I want to interpolate
p = [[1.5, 2.5, 3.5], ...]
# this gets simplexes that contain given points
s = tri.find_simplex(p)
# this gets vertices for the simplexes
v = tri.vertices[s]
我只能在这里找到一个answer建议使用transform
方法进行插值,但不再具体。
我需要知道的是如何使用包含单纯形的顶点来获得线性插值的权重。让我们假设一般的n-dim情况,以便答案不依赖于维度。
编辑:我不想使用LinearNDInterpolator或类似的方法,因为我没有每个点的数字作为值,但更复杂(数组/函数)。
答案 0 :(得分:3)
您无需从头开始实现此功能,此功能已在scipy中内置支持:
答案 1 :(得分:3)
经过一些实验,解决方案看起来很简单(post非常有帮助):
# dimension of the problem (in this example I use 3D grid,
# but the method works for any dimension n>=2)
n = 3
# my array of grid points (array of n-dimensional coordinates)
points = [[1,2,3], [2,3,4], ...]
# each point has some assigned value that will be interpolated
# (e.g. a float, but it can be a function or anything else)
values = [7, 8, ...]
# a set of points at which I want to interpolate (it must be a NumPy array)
p = np.array([[1.5, 2.5, 3.5], [1.1, 2.2, 3.3], ...])
# create an object with triangulation
tri = Delaunay(points)
# find simplexes that contain interpolated points
s = tri.find_simplex(p)
# get the vertices for each simplex
v = tri.vertices[s]
# get transform matrices for each simplex (see explanation bellow)
m = tri.transform[s]
# for each interpolated point p, mutliply the transform matrix by
# vector p-r, where r=m[:,n,:] is one of the simplex vertices to which
# the matrix m is related to (again, see bellow)
b = np.einsum('ijk,ik->ij', m[:,:n,:n], p-m[:,n,:])
# get the weights for the vertices; `b` contains an n-dimensional vector
# with weights for all but the last vertices of the simplex
# (note that for n-D grid, each simplex consists of n+1 vertices);
# the remaining weight for the last vertex can be copmuted from
# the condition that sum of weights must be equal to 1
w = np.c_[b, 1-b.sum(axis=1)]
要理解的关键方法是transform,这是简要记录的文件,但是文档说明了所有需要说明的内容。对于每个单纯形,transform[:,:n,:n]
包含变换矩阵,transform[:,n,:]
包含矩阵与之相关的向量r。似乎r向量被选为单纯形的最后一个顶点。
另一个棘手的问题是如何获得b
,因为我想要做的就是
for i in range(len(p)): b[i] = m[i,:n,:n].dot(p[i]-m[i,n,:])
基本上,我需要一个点积的数组,而dot
给出两个数组的乘积。像上面这样的单个单循环的循环可以工作,但是它可以在一步中更快地完成,其中有numpy.einsum
:
b = np.einsum('ijk,ik->ij', m[:,:n,:n], p-m[:,n,:])
现在,v
包含每个单纯形的顶点指数,w
包含相应的权重。要在点集p_values
处获得插值p
,我们会这样做(注意:values
必须是NumPy数组):
values = np.array(values)
for i in range(len(p)): p_values[i] = np.inner(values[v[i]], w[i])
或者我们可以再一次使用`np.einsum'执行此操作:
p_values = np.einsum('ij,ij->i', values[v], w)
当某些插值点位于网格外时,必须注意某些情况。在这种情况下,find_simplex(p)
会为这些点返回-1
,然后您必须屏蔽它们(或许使用masked arrays)。
答案 2 :(得分:0)
您需要一个间隔和一个线性插值,即边缘的长度和插值点距起始顶点的距离。