如何在 python 中的常规 3D 网格上查找相邻线

How to find adjacent lines on a regular 3D grid in python

我有一堆点的坐标,想在 python 包中用它们创建曲面。我想在将数据导入包之前整理它们。点来自规则网格。首先,我根据点的位置创建线。在这一步中,我只定义哪些点编号创建我的线。我的输入数据是:

coord = np.array(
    [[0., 0., 2.], [0., 1., 3.], [0., 2., 2.], [1., 0., 1.], [1., 1., 3.], 
     [1., 2., 1.], [2., 0., 1.], [2., 1., 1.], [3., 0., 1.], [4., 0., 1.]])

下图显示了网格点数(灰色)和线条数(蓝色和红色)。

行是通过字典建模的,其中key是行号,value是一个包含起点和终点编号的元组:

In [906]: blue_line
Out[906]: {1: (1, 2), 2: (2, 3), 3: (4, 5), 4: (5, 6), 5: (7, 8)}

In [907]: red_line
Out[907]: 
{6: (1, 4),
 7: (2, 5),
 8: (3, 6),
 9: (4, 7),
 10: (5, 8),
 11: (7, 9),
 12: (9, 10)}

要了解有关线条生成方式的更多信息,请查看 。用于创建表面的线存储在列表中:

surfaces = [(1, 6, 3, 7), (2, 7, 4, 8), (3, 9, 5, 10)]

作为最后一步,我想找出在创建表面时未使用或已使用但比上图中的虚线限制更近的线数。同样,我有创建该虚线的两点的坐标:

coord_dash = [(2., 2., 2.), (5., 0., 1.)]
adjacency_threshold = 2

我想将这些相邻的行作为另一个列表(图中红色箭头所示):

adjacent_lines = [4, 10, 5, 11, 12]

我只有这个粗略的想法,不知道如何在 Python 中进行编码。我只能创建线号和表面,需要帮助才能找到那些紧密的线。

确定哪些行未被使用很简单(NumPy 的 setdiff1d 可以派上用场):

In [924]: all_line = {**blue_line, **red_line}

In [925]: lines = list(all_line.keys())

In [926]: lines
Out[926]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

In [927]: used_lines = np.ravel(surfaces)

In [928]: used_lines
Out[928]: array([ 1,  6,  3,  7,  2,  7,  4,  8,  3,  9,  5, 10])

In [929]: unused_lines = np.setdiff1d(lines, used_lines)

In [930]: unused_lines
Out[930]: array([11, 12])

相邻的行可以使用NumPy的linalg.norm得到:

In [954]: midpoints
Out[954]: 
{1: array([0. , 0.5, 2.5]),
 2: array([0. , 1.5, 2.5]),
 3: array([1. , 0.5, 2. ]),
 4: array([1. , 1.5, 2. ]),
 5: array([2. , 0.5, 1. ]),
 6: array([0.5, 0. , 1.5]),
 7: array([0.5, 1. , 3. ]),
 8: array([0.5, 2. , 1.5]),
 9: array([1.5, 0. , 1. ]),
 10: array([1.5, 1. , 2. ]),
 11: array([2.5, 0. , 1. ]),
 12: array([3.5, 0. , 1. ])}

In [955]: mid_dash = np.array(coord_dash).mean(axis=0)

In [956]: mid_dash
Out[956]: array([3.5, 1. , 1.5])

In [957]: adjacent_lines = []
     ...: for idx, point in midpoints.items():
     ...:     if np.linalg.norm(point - mid_dash) < adjacency_threshold:
     ...:         adjacent_lines.append(idx)

In [958]: adjacent_lines
Out[958]: [5, 11, 12]