我自己解决了这个问题,所以这里给任何未来迷惑的人一个解释。
作为例子,让我们使用我在代码中使用的简单点格子,我是这样生成它的:
import numpy as np
import itertools as it
from matplotlib import pyplot as plt
import scipy as sp
inputs = list(it.product([0,1,2],[0,1,2]))
i = 0
lattice = range(0,len(inputs))
for pair in inputs:
lattice[i] = mksite(pair[0], pair[1])
i = i +1
细节并不重要,可以简单地说它生成了一个正三角形的晶格,在这个晶格中,一个点与其六个最近邻点之间的距离为1。
要绘制它:
plt.plot(*np.transpose(lattice), marker = 'o', ls = '')
axes().set_aspect('equal')
![enter image description here](https://istack.dev59.com/xJFev.webp)
现在计算三角剖分:
dela = sp.spatial.Delaunay
triang = dela(lattice)
让我们看看这给我们带来了什么。
triang.points
输出:
array([[ 0. , 0. ],
[ 0.5 , 0.8660254 ],
[ 1. , 1.73205081],
[ 1. , 0. ],
[ 1.5 , 0.8660254 ],
[ 2. , 1.73205081],
[ 2. , 0. ],
[ 2.5 , 0.8660254 ],
[ 3. , 1.73205081]])
简单来说,只是上面所示晶格中所有九个点的数组。现在让我们看一下:
triang.vertices
输出:
array([[4, 3, 6],
[5, 4, 2],
[1, 3, 0],
[1, 4, 2],
[1, 4, 3],
[7, 4, 6],
[7, 5, 8],
[7, 5, 4]], dtype=int32)
在这个数组中,每一行代表三角剖分中的一个单纯形(三角形)。每一行中的三个条目是我们刚刚看到的点数组中该单纯形的顶点的索引。因此,例如,这个数组中的第一个单纯形
[4, 3, 6]
由以下点组成:
[ 1.5 , 0.8660254 ]
[ 1. , 0. ]
[ 2. , 0. ]
很容易在纸上绘制晶格,根据其索引标记每个点,然后通过
triang.vertices
中的每一行进行跟踪,就可以看到这一点。
这是我们编写我在问题中指定的函数所需的所有信息。
它看起来像这样:
def find_neighbors(pindex, triang):
neighbors = list()
for simplex in triang.vertices:
if pindex in simplex:
neighbors.extend([simplex[i] for i in range(len(simplex)) if simplex[i] != pindex])
'''
this is a one liner for if a simplex contains the point we`re interested in,
extend the neighbors list by appending all the *other* point indices in the simplex
'''
return list(set(neighbors))
就是这样!我相信上面的函数可能需要一些优化,这只是我在几分钟内想出来的。如果有人有任何建议,请随意发布。希望这能帮助将来像我一样困惑的人。