如何找到一个线段到任意点的最近点?(How to find the closest point on

2019-10-22 05:00发布

此功能应该采取哪些将被用来找到最接近点它,就在于线段对象上的点参数。 在该示例中断言码函数getClosestPoint(Point())Point(10, 0)作为参数,并且应该返回Point(5,5)是最接近的点至Point(10, 0)即上的线l1 = Line(Point(5,5), Point(20,35))随着终点为A Point(5,5), B Point(20,35)我不知道如何去解决这个问题。 我目前的解决方案将返回(4,3),这是不是就行了段,但就行了。

 from point import Point
 import math
 class Line:
    def __init__(self,aPoint=Point(), bPoint=Point()):
        self.firstPoint = aPoint
        self.secondPoint = bPoint

    def getClosestPoint(self,point=Point()):

        m1 = self.getSlope()
        m2 = -1 / float(m1)
        b1 = self.p1.y - m1 * self.p1.x
        b2 = point.y - m2 * point.x
        x = float(b2 - b1) / float(m1 - m2)
        y = m1 * x + b1
        return Point(x, y)

    if __name__ == "__main__":
         p1 = Point(5,5)
         p2 = Point(20,35)
         l1 = Line(p1,p2)
         assert l1.getClosestPoint(Point(10,0)) == Point(5,5)
         assert l2.getClosestPoint(Point(25/2,25/2)


 class Point: 
    def __init__(self,x=0,y=0):
       self.x = x
       self.y = y

Answer 1:

一般的答案是投影点到线。 看到它的一种方式是在点变换到由你的段限定的参考帧( p1是新的原点(0, 0) p2的新(1, 0) 然后,你摆脱了新的y协调(这就是实际投影时),改造新点(x, 0)回到原始帧。

具体而言,你必须找到变革。 第二个,从全新的空间到原来的空间很容易写(只画在纸上,你会看到):

x = (x2 - x1) * nx + (y2 - y1) * ny + x1
y = (y1 - y2) * nx + (x2 - x1) * ny + y1

但是你可以颠倒这些方程找到(nx, ny)对应于一个点(x, y)

当你这样做,并假设我们都没有犯任何错误,也没有错字,你应该得到的东西,如:

dx = x2 - x1
dy = y2 - y1
d2 = dx*dx + dy*dy
nx = ((x3-x1)*dx + (y3-y1)*dy) / d2
return (dx*nx + x1, dy*nx + y1)

编辑:如果你确实有找上了 ,而不是线上的最近点,很容易因为发现如果投影落在段内,你有0 <= nx <= 1 (这是一个充分必要条件) 。 return语句之前,你可以强制nx留在这个区间:

nx = min(1, max(0, nx))

重新编辑:上面的语句等价于:

if nx<0:
    nx = 0
if nx>1:
    nx = 1

以这种方式,上线(其可以是外段)的点的投影得到的链段(由定义内推回0 <= nx <= 1在最近的点)。



Answer 2:

见保罗·伯克这个漂亮的描述 。





文章来源: How to find the closest point on a line segment to an arbitrary point?