【发布时间】:2013-03-08 15:33:46
【问题描述】:
考虑以下交叉线示例:
l1 = ((20,5),(40,20))
l2 = ((20,20),(40,5))
l3 = ((30,30),(30,5)) # vertical line
我开发了以下代码来计算交叉点的 x,y(参见理论细节)
def gradient(l):
"""Returns gradient 'm' of a line"""
m = None
# Ensure that the line is not vertical
if l[0][0] != l[1][0]:
m = (1./(l[0][0]-l[1][0]))*(l[0][1] - l[1][1])
return m
def parallel(l1,l2):
if gradient(l1) != gradient(l2):
return False
return True
def intersect(l):
"""Returns intersect (b) of a line using the equation of
a line in slope and intercepet form (y = mx+b)"""
return l[0][1] - (gradient(l)*l[0][0])
def line_intersection(l1,l2):
"""Returns the intersection point (x,y) of two line segments. Returns False
for parallel lines"""
# Not parallel
if not parallel(l1,l2):
if gradient(l1) is not None and gradient(l2) is not None:
x = (1./(gradient(l1) - gradient(l2))) * (intersect(l2) - intersect(l1))
y = (gradient(l1)*x) + intersect(l1)
else:
if gradient(l1) is None:
x = l1[0][0]
y = (gradient(l2)*x) + intersect(l2)
elif gradient(l2) is None:
x = l2[0][0]
y = (gradient(l1)*x) + intersect(l1)
return (x,y)
else:
return False
示例会话:
>>> line_intersection(l1,l2)
(30.0, 12.5)
>>> line_intersection(l2,l3)
(30, 12.5)
我希望在长度有限的线段的情况下以一种有效的方式改进我的代码,并且它们实际上可能不相交。
l1 = ((4,4),(10,10))
l2 = ((11,5),(5,11))
l3 = ((11,5),(9,7))
line_intersection(l1,l2) #valid
(8.0, 8.0)
line_intersection(l1,l3) # they don't cross each other
(8.0, 8.0)
line_intersection(l2,l3) #line parallel
False
我的 inelegant 解决方案如下。
def crosses(l1,l2):
if not parallel(l1,l2):
x = line_intersection(l1,l2)[0]
xranges = [max(min(l1[0][0],l1[1][0]),min(l2[0][0],l2[1][0])),min(max(l1[0][0],l1[1][0]),max(l2[0][0],l2[1][0]))]
if min(xranges) <= x <= max(xranges):
return True
else:
return False
else:
return False
crosses(l1,l2)
True
crosses(l2,l3)
False
我正在寻找是否可以改进我在 python 中的函数样式
【问题讨论】:
-
由于您只处理直线结构,因此检查交点是否在其中一条线的 x 坐标内就足够了。
-
谢谢@WaleedKhan。我需要找到一个保存编码功能
-
只是一个提示.. 不要使用斜率/相交。以参数形式写出你的行 x1 = p11 (1-a)/2 + p12 (1+a)/2 x2 = p21 (1-b)/2+p22(1+b)/2 求解 a,b 和检查 a,b 是否都在 -1,1 范围内。这样您就不需要将垂直线视为特殊情况。
-
这个问题要么离题(应该在codereview.stackexchange.com上),要么与stackoverflow.com/questions/3838329/…重复,这取决于你如何看待它。
标签: python coding-style geometry line