【问题标题】:How to pair line numbers making surfaces in a regular grid如何配对线号在规则网格中制作曲面
【发布时间】:2021-04-03 16:07:00
【问题描述】:

我在 3D 空间中有一堆由线连接的点。我想通过检测哪些线可以创建这样的曲面来创建 4 面。

我有我的点的坐标、编号的线以及创建线的点对。我上传了一张图来可视化它:

它以红色显示点位置及其编号,以蓝色显示线及其编号。我的积分分布在常规的xy 网格中,但是是3 维的。

下面是对应的数据:

coordinates=np.array([[1.,1.,1.], [1.,2.,1.1], [1.,3.,0.9], [1.,4.,1.2],\
                      [2.,2.,1.2], [2.,3.,1.],[2.,4.,1.1],\
                      [3.,2.,1.1], [3.,3.,0.95],\
                      [4.,3.,1.], [4.,4.,1.05]])
y_lines=np.arange(17,24)
point_to_y_lines=[(1,2), (2,3), (3,4), (5,6), (6,7), (8,9), (10,11)]
x_lines=np.arange(24,30)
point_to_x_lines=[(2,5), (3,6), (4,7), (5,8), (6,9), (9,10)]

关于我的绘图:行号 18252024 创建第一个表面。

我正在尝试的算法

要查找曲面,我认为比较线的中心是一种合乎逻辑的方法。我的意思是从行号17 开始,我想检查哪些线的中心距离这条线的中心比限制更近(中心用黑色十字表示)。

我根据x 坐标中的分辨率选择限制,例如1.3 看起来不错。只有行号24 比行中心17 的限制更近。所以17 不能创建任何表面。

下一行是行号18,五行的中心距离它更近:171925202417 应该被忽略,因为它的值小于 18(第一条规则)。 19 也应该被忽略,因为它只比 18 大一个数字,并且其中心的 x 值与行号的中心 18 相同(第二条规则)。

那么,行号19的中心附近的中心是18(将被删除,因为它小于19(第一条规则)),262125

下一行是20,并且很多行的中心距离它更近:18(第一条规则,已删除)、252421、@987654356 @、2227。行号2524 将被忽略,因为它们中心的x 值小于20 中心的x 值(第三条规则),即我在x 中前进坐标,不包括传递的x 坐标。

行号 21 将被删除,因为它是唯一大于 20 的值,并且其 x 与行号 20 相同(第二条规则)。

由于上述规则,下一行(212223,我一直到 y_lines 的最后一行)无法创建任何表面。

期望的输出

表面应该作为元组列表输出:

[(18, 25, 20, 24), (19, 26, 21, 25), (20, 28, 22, 27)]

我非常感谢在 python 中编写这样一个算法的任何帮助。

【问题讨论】:

  • 要找到的表面是否总是 4 的元组?或者它可能是 6、8、... 取决于缺失的边缘?例如,如果边 20 和 25 都不存在,是否会有表面?
  • 线条总是垂直还是水平,并且大小 = 1?或者可以有更长的线,可能不是垂直或水平的?
  • 亲爱的@trincot,我的表面总是由四行组成。幸运的是,我的箱子并没有那么乱,形状不规则,它们总是正方形或长方形。 x 和 y 中的网格大小可以改变,并不总是 1,但在两个方向上都是固定的。例如,垂直尺寸可以是 1,水平尺寸可以是 1.5。我的线条也总是垂直和水平的。
  • 还有z值。我的图显示了 2d 视图,但 z 也很重要,但从一点到另一点并没有太大变化。这就是为什么像 1.3 这样的限制对于挑选线来说是安全的。像 x 方向分辨率的平方根 + y 方向的分辨率这样的值似乎很好。
  • 因此,由于 z 坐标,找到的表面很少是平坦的,即矩形的 4 个点不会总是在一个平面上,对吧?

标签: python list algorithm numpy geometry


【解决方案1】:

正如cmets所显示的,有很多事情需要澄清,所以我的回答可能仍然不是你所需要的。

我对这个问题做了几个假设:

  • z 坐标与定位正方形无关
  • 只有横线和竖线
  • 水平线始终将 x 坐标较小的点排在第一位,将另一个 x 坐标较大的点排在第二位。垂直线也一样...
  • 线不相交,除了端点。
  • 要找到的表面总是有 4 个边。
  • 一个点最多有 4 个邻居(在北、东、南和西方向)

这个问题是一个图问题,在其中找到 4 个循环。

我建议建立一个邻接表,其中每个顶点有 4 个按顺时针顺序(北、东、南、西)的邻居引用,其中一些可以是None。当不是None时,邻居由行号和相连顶点的编号来描述。

该算法实际上并不需要知道坐标,因为描述线条的数据结构中已经存在大量信息。

这里是代码(我省略了numpy):

y_lines = list(range(17, 24))
point_to_y_lines=[(1,2), (2,3), (3,4), (5,6), (6,7), (8,9), (10,11)]
x_lines = list(range(24,30))
point_to_x_lines=[(2,5), (3,6), (4,7), (5,8), (6,9), (9,10)]

from collections import defaultdict

# Create the empty adjacency list, prepared for lists of 4 entries per vertex
adj = defaultdict(lambda: [None]*4)

# Add vertical lines in the slots for north (0) and south (2)
for line, (a, b) in zip(y_lines, point_to_y_lines):
    adj[a][0] = (line, b)
    adj[b][2] = (line, a)  # also store the line in opposite direction

# Add horizontal lines in the slots for east (1) and west (3)
for line, (a, b) in zip(x_lines, point_to_x_lines):
    adj[a][1] = (line, b)
    adj[b][3] = (line, a)

# Main algorithm: find the rectangles
results = []
for corner in adj:  # for each vertex with at least one edge
    rect = []
    for direction in range(4):  # make a 90° turn at each next corner
        neighbor = adj[corner][direction]
        if not neighbor:  # Oops, no line in that direction. Give up.
            break
        line, corner = neighbor
        rect.append(line)
    else:  # We closed a rectangle
        results.append(tuple(rect))

print(results)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多