我有以下两组位置,每组位对应于开始和结束位置:
line T: t1-t2 (t1 = start_pos, t2 = end_pos)
line S: s1-s2 (s1 = start_pos, t2 = end_pos)
我想用Python编写算法来检查T是否与S相交。
示例1:
t1-t2=55-122 and s1-s2=58-97
s1------------s2
t1-----------------t2
This should return True
示例2:
t1-t2=4-66 / t1-t2=143-166 and s1-s2=80-141
s1----s2
t1--t2 t1---t2
Both instances of T should return False
但为什么这段代码失败了:
def is_overlap(pos, dompos):
"""docstring for is_overlap"""
t1,t2 = [int(x) for x in pos.split("-")]
s1,s2 = [int(x) for x in dompos.split("-")]
# Here we define the instance of overlapness
if (t1 >= s1 and t2 >= s2) or \
(t1 >= s1 and t2 <= s2) or \
(t1 <= s1 and t2 >= s2) or \
(t1 <= s1 and t2 <= s2):
return True
else:
return False
输出:
In [2]: is_overlap('55-122', '58-97')
Out[2]: True
In [3]: is_overlap('4-66', '80-141')
Out[3]: True
In [4]: is_overlap('143-166', '80-141')
Out[4]: True
这样做的正确方法是什么?
答案 0 :(得分:7)
考虑范围[a, b]
和另一范围[x, y]
。它们要么重叠,要么是分开的。
如果它们是分开的,那么两件事中的一件必须是真的:
[a, b]
位于[x, y]
左侧,或[x, y]
位于[a, b]
。如果[a, b]
位于[x, y]
左侧,我们会b < x
。
如果[x, y]
位于[a, b]
左侧,我们会y < a
。
如果这些都不属实,则跨度不能分开。它们必须重叠。
此逻辑在以下函数中实现。
def are_separate(r, s): # r and s are ordered pairs
(a, b) = r
(x, y) = s
if b < x or y < a:
return True
else:
return False
更简洁:
def are_separate(r, s):
(a, b) = r
(x, y) = s
return b < x or y < a
更简洁:
def are_separate(r, s):
return r[1] < s[0] or s[1] < r[0]
如果你想要相反的函数are_overlapping
,只需否定表达式:
def are_overlapping(r, s):
return not(r[1] < s[0] or s[1] < r[0])
这在逻辑上等同于:
def are_overlapping(r, s):
return r[1] >= s[0] and s[1] >= r[0]
答案 1 :(得分:1)
你的条件错了;再次检查它们。例如,第一个条件意味着(t_1, t_2) = (100, 200)
和(s_1, s_2) = (50, 60)
是一组有效的重叠线。但显然,他们不是。
您可能想要考虑的其他事情是用户是否向后输入坐标。如果他输入类似'80-30'
的内容怎么办?
答案 2 :(得分:1)
对于那些想要在二维中使用两行的人来说,@ michael的答案是不够的。以下代码基于在代码上方列出的Wikipedia页面中找到的等式,以及一些毕达哥拉斯来检查适当点之间的交点。 https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
x1, y1, x2, y2 = 200, 200, 300, 300
x3, y3, x4, y4 = 200, 150, 300, 350
px = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / \
((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4))
py = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / \
((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4))
if ((x1 - px) ** 2 + (y1 - py) ** 2) ** 0.5 + ((x2 - px) ** 2 + (y2 - py) ** 2) ** 0.5 == \
((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5 and \
((x3 - px) ** 2 + (y3 - py) ** 2) ** 0.5 + ((x4 - px) ** 2 + (y4 - py) ** 2) ** 0.5 == \
((x3 - x4) ** 2 + (y3 - y4) ** 2) ** 0.5:
print("Overlap at point: (%s, %s)" % (px, py))
else:
print("No overlap.")