【问题标题】:A special case of intersection of line and rectrangle直线与矩形相交的特例
【发布时间】:2019-07-23 13:32:00
【问题描述】:

如何检查一条线是否与矩形相交经常被问到,例如How to know if a line intersects a rectangle。解决方案的基本思想是检查是否

  • 矩形的四个线段中的任何一个都与这条线相交
  • 这个矩形包含这条线的起点和终点

但是这种方法无法处理特殊情况,这种情况在我的应用程序中不应被视为交集:

在这里,线通过角点,而整个 MBR 位于该线的一侧。那么,如何检查这种特殊情况呢?

【问题讨论】:

  • 你不告诉我们这是否被认为是一个交叉路口。
  • 这种情况不被视为交集@YvesDaoust
  • 所以似乎足以将比较r < 0 和类似的更改为r<=0 等等以排除侧端。

标签: algorithm geometry computational-geometry


【解决方案1】:

我设计了一个可行的解决方案来检查这种特殊情况。当整个 MBR 位于线的一侧时,会发生这种特殊情况。

我们需要一个辅助方法来获取一个点的位置:

# p is the query point, (a, b) is the line
def position(p, a, b):
    return np.sign((b.x - a.x) * (p.y - a.y) - (p.x - a.x) * (b.y - a.y))

然后我们得到四个角的所有位置:

# left_bottom ... are corners
# (start, end) is the line
f = lambda m: position(m, start, end)
vf = np.vectorize(f)
positions = vf(np.array([left_bottom, right_bottom, left_top, right_top]))

特殊情况发生在位置之一等于0,并且所有位置都为-1或1时:

if len(np.where(positions == 0)) == 1 and abs(np.sum(positions)) == 3:
    return False

【讨论】:

    【解决方案2】:

    如果坐标表示为浮点实数,由于截断错误,线段在拐角处的精确重合很少且有些随机。人们可能想知道,担心这些“极端情况”有什么好处。

    根据应用程序,处理退化的交叉点(即单点而不是线段)可能更尴尬而不是有用。

    需要更多上下文才能以有意义的方式回答您的问题。

    【讨论】:

      【解决方案3】:

      为方便起见,我们假设表示为OP 的段从原点开始。 (如果没有,翻译所有点。)

      线段OP的一个点由向量表达式给出

      t.P
      

      t[0, 1] 中。

      这样一个点在[X0, X1] x [Y0, Y1]时属于封闭矩形

      X0 ≤ Px.t ≤ X1
      Y0 ≤ Py.t ≤ Y1
      

      为了讨论这些不等式,我们必须根据PxPy 的符号来区分九种情况。

      让我们处理两个肯定的情况。然后我们写

      Py.X0 ≤ Px.Py.t ≤ Py.X1
      Px.Y0 ≤ Px.Py.t ≤ Px.Y1
      

      一起

      0 ≤ Px.Py.t ≤ Px.Py
      

      表示段的限制。

      那么条件下的解集不为空

      Max(Py.X0, Px.Y0, 0) ≤ Min(Py.X1, Px.Y1, Px.Py)
      

      其他情况可以类似处理。计算成本是

      6 initial subtractions
      2 3-way sign tests
      5 multiplications
      5 comparisons
      

      (当初始比较得出相等时,表达式会简化一点*并且成本更低)。

      请注意,为了提高效率,此公式避免了除法。正如我在另一个答案中所说,< 的相关性是值得商榷的(可能用区间算术处理)。


      *设Py=0,那么我们把不等式写成

      X0 ≤ Px.t ≤ X1
      Y0 ≤    0 ≤ Y1
       0 ≤ Px.t ≤ Px
      

      条件是

      Max(X0, 0) ≤ Min(X1, Px) and Y0 ≤ 0 ≤ Y1.
      

      显然,Px=Py=0 解决了

      X0 ≤ 0 ≤ X1 and Y0 ≤ 0 ≤ Y1.
      

      【讨论】:

        猜你喜欢
        • 2011-04-14
        • 1970-01-01
        • 2014-12-06
        • 1970-01-01
        • 2014-06-09
        • 1970-01-01
        • 2018-08-26
        • 2020-12-17
        • 2012-07-23
        相关资源
        最近更新 更多