直线与矩形相交的特例

Posted

技术标签:

【中文标题】直线与矩形相交的特例【英文标题】: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 等等以排除侧端。 【参考方案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.

【讨论】:

以上是关于直线与矩形相交的特例的主要内容,如果未能解决你的问题,请参考以下文章

可以与单条直线相交的最大可能矩形数

如何找到直线和矩形的交点?

C++编程,求俩矩形重叠面积的代码

Save Money for Your Company 最小矩形覆盖(非计算几何)/找出N条直线相交点的边缘点/ find the dominating points of N lines

Save Money for Your Company 最小矩形覆盖(非计算几何)/找出N条直线相交点的边缘点/ find the dominating points of N lines

POJ 2318 TOYS 叉积