私は自分でそれを理解したので、これに混乱している将来の人のためにここに説明があります。
例として、コードで使用していた単純なポイントのラティスを使用してみましょう。これは次のように生成されます。
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
ここでの詳細はそれほど重要ではありません。ある点とその6つの最近傍のいずれかとの間の距離が1である規則的な三角格子を生成すると言えば十分です。
それをプロットするには
plt.plot(*np.transpose(lattice), marker = 'o', ls = '')
axes().set_aspect('equal')
次に、三角形分割を計算します。
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]])
単純で、上に示した格子内の9つのポイントすべての配列です。どのように見てみましょう:
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)
この配列では、各行は三角形分割の1つのシンプレックス(三角形)を表します。各行の3つのエントリは、先ほど見たポイント配列内のそのシンプレックスの頂点のインデックスです。したがって、たとえば、この配列の最初のシンプレックス[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
'''
#now we just have to strip out all the dulicate indices and return the neighbors list:
return list(set(neighbors))
以上です!上記の関数は、いくつかの最適化で実行できると確信しています。これは、私が数分で思いついたものです。誰か提案があれば、遠慮なく投稿してください。うまくいけば、これは私と同じようにこれについて混乱している将来の誰かを助けるでしょう。