用 Python 相交矩形

Posted

技术标签:

【中文标题】用 Python 相交矩形【英文标题】:Intersecting rectangles with Python 【发布时间】:2013-03-31 03:21:07 【问题描述】:

给定两个矩形 r1 和 r2,我尝试测试这两个矩形是否相交。 为什么以下两个函数不产生相同的输出?

功能1:

def separate_helper(r1, r2):
  r1_left, r1_top, r1_right, r1_bottom = r1
  r2_left, r2_top, r2_right, r2_bottom = r2

  if r1_right < r2_left:
    separate = True
  elif    r1_left > r2_right:
    separate = True
  elif r1_top > r2_bottom:
    separate = True
  elif r1_bottom < r2_top:
    separate = True
  elif contains(r1, r2):
    separate = False
  else:
    separate = False
  return separate

功能2:

def separate_helper2(r1, r2):
  r1_left, r1_top, r1_right, r1_bottom = r1
  r2_left, r2_top, r2_right, r2_bottom = r2

  separate = r1_right < r2_left or \
    r1_left > r2_right or \
    r1_top > r2_bottom or \
    r1_bottom < r2_top or \
    not contains(r1, r2)
  return separate

检查矩形 1 是否包含矩形 2 的函数:

def contains(r1, r2):
  r1_left, r1_top, r1_right, r1_bottom = r1
  r2_left, r2_top, r2_right, r2_bottom = r2
  return r1_right >= r2_right and  r1_left <= r2_left and  r1_top <= r2_top and  r1_bottom >= r2_bottom

这是一个失败的测试用例:

assert separate_helper([29, 35, 53, 90], [23, 47, 90, 86]) == separate_helper2([29, 35, 53, 90], [23, 47, 90, 86])

仅当矩形 1 包含矩形 2 时它才会失败,但我无法理解为什么。

编辑:

我正在使用 Python 和鼻子的快速检查来测试该功能。这是我正在使用的测试代码:

from qc import forall, lists, integers
from intersect import separate_helper, separate_helper2

@forall(tries=100, r1=lists(items=integers(), size=(4, 4)), r2=lists(items=integers(), size=(4, 4)))
def test_separate(r1, r2):
  assert separate_helper(r1, r2) == separate_helper2(r1, r2)

【问题讨论】:

失败是什么意思?崩溃或只是没有说他们相交? @DiegoNolan 如果你运行提供的代码,你会看到最后的相等返回 False 但不应该。 @DiegoNolan 断言失败。有关详细信息,请参阅更新的问题。 【参考方案1】:

看看你的第一个版本:

elif contains(r1, r2):
  separate = False
else:
  separate = False

假设您通过了所有正确的相交情况,无论r1 是否包含r2,这将返回False

但是在你的第二个版本中:

... or \
not contains(r1, r2)

这将返回Falser1 不包含r2,但True 否则。

因此,在“矩形 1 包含矩形 2”的情况下,他们正在做不同的事情。

作为一个附带问题:为什么包含r2r1 与包含r1r2 返回不同的结果?

【讨论】:

我想他只是想检查矩形的是否相交。 @Phoexo:我想你是在评论我的附带问题。如果你是对的,那么根本没有理由检查contains。如果你错了,他需要双向检查contains。无论哪种方式,我都看不出他为什么要检查一种方式而不是另一种。 感谢您的解释。完整的代码包含两个方向。我故意省略了它以显示一个最小的失败测试用例。 @mre:没问题;我只是想确保您没有忽略某些事情,更重要的是,我没有误解您的逻辑。 (这就是为什么它只是一个附带问题。)

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

poj1410(判断线段和矩形是否相交)

判断两个矩形相交以及求出相交的区域

两个矩形相交问题-判断是否相交

平面中判断线段与矩形是否相交

矩形相交判断

直线与矩形相交的特例