我想制作一个函数来获取任意两条线之间的最近/最短距离(假设它们不相交)。我知道有几篇关于点和线之间最短距离的帖子,但我找不到两条线。
我咨询了几个数学和矢量学习网站,并设法破解了下面的算法。它给出了答案,但不是正确的答案。例如,当找到以下之间的最短距离时:
l1 = [(5,6),(5,10)]
l2 = [(0,0),(10,10)]
print _line2line(l1,l2)
...它给出的答案是...
5.75223741636
从两条线的图中可以看出(它显示了一个 10x10 帧,每 1 个单位带有刻度线),理论上讲,点 (6,5) 和 (5, 5)。
所以我想知道是否有人能在我的代码中发现我做错了什么?(如果可能的话,我还想知道如何获得两条线最接近的实际点......)
下面代码的注释:L1 和 L2 代表 line1 和 line2,x/y1 vs x/y2 分别是每条线的起点和终点。后缀 dx 和 dy 代表 delta 或 x 和 y,即如果其原点位于 0,0 的向量。
def _line2line(line1, line2):
"""
- line1 is a list of two xy tuples
- line2 is a list of two xy tuples
References consulted:
http://mathforum.org/library/drmath/view/51980.html
and http://mathforum.org/library/drmath/view/51926.html
and https://answers.yahoo.com/question/index?qid=20110507163534AAgvfQF
"""
import math
#step1: cross prod the two lines to find common perp vector
(L1x1,L1y1),(L1x2,L1y2) = line1
(L2x1,L2y1),(L2x2,L2y2) = line2
L1dx,L1dy = L1x2-L1x1,L1y2-L1y1
L2dx,L2dy = L2x2-L2x1,L2y2-L2y1
commonperp_dx,commonperp_dy = (L1dy - L2dy, L2dx-L1dx)
#step2: normalized_perp = perp vector / distance of common perp
commonperp_length = math.hypot(commonperp_dx,commonperp_dy)
commonperp_normalized_dx = commonperp_dx/float(commonperp_length)
commonperp_normalized_dy = commonperp_dy/float(commonperp_length)
#step3: length of (pointonline1-pointonline2 dotprod normalized_perp).
# Note: According to the first link above, it's sufficient to
# "Take any point m on line 1 and any point n on line 2."
# Here I chose the startpoint of both lines
shortestvector_dx = (L1x1-L2x1)*commonperp_normalized_dx
shortestvector_dy = (L1y1-L2y1)*commonperp_normalized_dy
mindist = math.hypot(shortestvector_dx,shortestvector_dy)
#return results
result = mindist
return result