我想创建一个函数来获得任意两条线之间的最近/最短距离(假设它们不相交)。我知道有一些关于点和线之间最短距离的帖子,但我找不到任何两条线。
我咨询过几个数学和矢量学习网站,并设法破解下面的算法。它给出了答案,但不是正确答案。例如,当找到以下之间的最短距离时:
l1 = [(5,6),(5,10)]
l2 = [(0,0),(10,10)]
print _line2line(l1,l2)
......它给出了答案......
5.75223741636
从两条线的图中可以看出(它显示了一个10x10帧,每1个单位有一个刻度标记),从理论上讲,点(6,5)之间的距离应该小得多,大约为1。 (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