【问题标题】:How to determine if two 2D line segments are overlap?如何确定两个二维线段是否重叠?
【发布时间】:2021-08-18 08:47:14
【问题描述】:

我正在处理一项任务(使用 python3),该任务需要检查 2 个线段是否重叠并可以返回 2 个端点。线段的坐标为(x1,y1,x2,y2)形式,其中(x1,y1)和(x2,y2)是其端点的坐标。 两条线彼此非常接近,但可能不平行。可以看图了解哪种情况称为重叠。我认为重叠定义可以说是“如果一个点的投影位于另一条线的两个端点之间” 示例:

overlap1 = numpy.array([[1,4,5,5], [7,7,3,5]])
overlap2 = numpy.array([[8,1,12,2], [9,2,11,3]])

non_overlap = numpy.array([[1,2,5,3], [6,3,9,4]])

我的目标是找到 4 个点中最远的 2 个点(如果它们重叠),如图中的红色圆圈所示。目前我的想法是:

  1. 计算到所有点的距离(AB、AC、AD、BC、BD、CD)和 检查以找到最大距离,称为 max_len
  2. 计算:test = len_AB + len_CD - max_len
  3. 如果 test > 0,它们是重叠的,否则它们不是

这个算法可以很好地检查重叠情况,但很难返回 2 个最多的端点。

你怎么看这个问题?谢谢。

【问题讨论】:

  • 从该图中看起来,“不重叠”部分中的第二个示例也是重叠(如果您扩展 B,它将位于 C 和 D 之间)。
  • 你能显示这些线的实际点吗?而不是 x1、y1 等,IOW,输入为有效元组,输出为有效元组
  • 我认为这听起来像是一道数学题,而不是 Python 编码程序。
  • @Selcuk 这是完整的线,我正在工作的是线段,受其两端的限制。因此,如果一个点的投影位于另一条线的 2 个点之间,则可以看到重叠。
  • @python_user 我已经包含了行示例。

标签: python geometry language-agnostic line


【解决方案1】:

感谢您阅读我的问题。我认为这是一个数学问题而不是编程问题,但过了一段时间,我找到了一个很好的简单算法来处理它。我的解决方案主要基于 python 中的 numpy 数组进行高效计算。我不确定是否有更好的数学方法,但希望这个解决方案在未来仍然有用。

这个想法是找到所有点组合的距离(从 4 个点有 6 个距离)。我创建了一个该组合的 numpy 数组,找到欧几里得距离,找到最大距离,并按条件检查重叠:len_AB + len_CD - max(distance)。

import numpy as np
def check_overlap(line1, line2):
    combination = np.array([line1,
                         line2,
                         [line1[0], line1[1], line2[0], line2[1]],
                         [line1[0], line1[1], line2[2], line2[3]],
                         [line1[2], line1[3], line2[0], line2[1]],
                         [line1[2], line1[3], line2[2], line2[3]]])
    distance = np.sqrt((combination[:,0] - combination[:,2])**2 + (combination[:,1] - combination[:,3])**2)
    max = np.amax(distance)
    overlap = distance[0] + distance[1] - max
    endpoint = combination[np.argmax(distance)]
    return (overlap >= 0), endpoint

【讨论】:

    【解决方案2】:

    考虑下一个代码,用于计算点(xp, yp)(x1y1-x2y2) 线段的投影的相对位置。它使用点(标量)积。

    当段确实是一个点时返回None

    当投影位于段内时返回参数0..1

    如果投影位于线段之外的线上,则返回此间隔之外的值。所以负值和> 1 是你的红圈点。

    (带有其他点名的图片)

    def proj(x1, y1, x2, y2, xp, yp):
        x12 = x2 - x1
        y12 = y2 - y1
        dotp = x12 * (xp - x1) + y12 * (yp - y1)
        dot12 = x12 * x12 + y12 * y12
        if dot12:
            return dotp / dot12
        else:
            return None
    

    【讨论】:

    • 谢谢。使用直线点投影是我的第一个想法,但我犹豫了,因为在极端情况下,我需要找到所有 4 个点的投影。我在下面的答案中发布了我的解决方案。如果你有时间,我希望你可以看看,如果有问题可以讨论。谢谢!
    【解决方案3】:

    看起来你只是使用x坐标,所以如果A

    【讨论】:

    • 也许使用 [0][0] 表示 A,[0][2] 表示 B [1][0] 表示 C 和 [1][2] 表示 D 并进行这些不等式比较
    • 谢谢!。这可以考虑,但我的问题似乎在垂直轴上有案例,所以我最好找到一种更通用的方法。
    猜你喜欢
    • 1970-01-01
    • 2010-09-23
    • 2017-06-28
    • 2016-02-14
    • 1970-01-01
    • 1970-01-01
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多