代码之家  ›  专栏  ›  技术社区  ›  Jivan

在NumPy中检测潜在的线段交点(布尔值)

  •  1
  • Jivan  · 技术社区  · 5 年前

    我有两个numpy数组,由几个线段组成,格式如下 [x1, y1, x2, y2] :

    foo = np.array([
        [2, 3, 2, 1],
        [6, 3, 5, 4],
        [5, 6, 8, 2],
        [5, 2, 6, 5]
    ])
    
    bar = np.array([
        [4, 2, 7, 8],
        [2, 1, 6, 9]
    ])
    

    我的最终目标是检查 foo 针对每个细分市场 bar 并验证交叉口。不需要交点,我只想知道两段是否相交(真/假)。

    实际上,有几十亿行 foo 还有几百行 酒吧 所以我想在跳到一个更复杂的方法之前,我会先执行一个更简单的检查,以验证以下内容:

    # two segments are potentially intersecting if and only if
    xFmin <= xBmax && xBmin <= xFmax     # x overlap
    &&
    yFmin <= yBmax && yBmin <= yFmax     # y overlap
    

    这个想法是,如果两条线段不能一起满足这个测试,那么它们就不可能相交。我试图用numpy实现这个测试,但到目前为止运气不佳。我想到了几个问题:

    • 如何确定例如。 yFmin yFmax (可通过预先订购坐标完成一次)
    • 如何正确地对两个数组进行切片和广播,以进行上述比较
    • 是否有可能在一次操作中对所有分段进行整体比较?

    该测试应给出类似于以下内容的最终输出:

    result = np.array([
        [True, False, False, True],   # all segments in Foo against the first segment in Bar
        [False, False, True, True]    # all segments in Foo against the second segment in Bar
    ])
    
    1 回复  |  直到 5 年前
        1
  •  1
  •   aerobiomat    5 年前

    不久前,我解决了一个类似的问题,实现了中描述的扫描线算法:

    迈克尔·沙莫斯,丹·霍伊(1976)。几何交点问题。 https://doi.org/10.1109/SFCS.1976.16

    它将问题从O(N)转换为O(N log N)。

    在Jivan的评论后添加:

    对于一个集合中的片段与第二个集合中片段的比较,您可以尝试以下方法:

    Chan(1994),一种用于报告红/蓝段相交的简单梯形扫描算法。 https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.44.4227

    免责声明:我还没有实现这个。

        2
  •  0
  •   Igor Rivin    5 年前

    如果你有数十亿个片段,我建议你使用这样的库: https://github.com/Permafacture/python-computational-geometry ,它允许您批量计算。

        3
  •  0
  •   casellimarco    5 年前

    对于第一个问题,我建议只循环遍历所有分段,并通过比较两个X极值和两个Y极值来对条目进行排序,将分段表示设置为类似

    [x_min, y_min, x_max, y_max]
    

    (这种表示方式应该减少您需要在每个段上执行的操作数量,最多两次交换) 然后存储结果。

    然后,您可以循环浏览bar中的分段(应该更有效,因为分段更少),并使用您的过滤条件。您可以按列写入条件,因此第一个将是

    x_min_bools = foo[:,0] <= x_bar_min
    

    你对其他三个也有同样的看法。然后,您可以使用np.local_and()组合布尔数组,得到结果行。

    推荐文章