如何找到线段上最近的点到任意点?

时间:2015-03-08 19:38:02

标签: python geometry

此函数应该接受一个点参数,该参数将用于查找位于线段对象上的最近点。在示例断言代码中,函数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

2 个答案:

答案 0 :(得分:3)

一般的答案是将点投射到线上。 查看它的一种方法是将点转换为由您的细分所定义的参考框架(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定义)内。

答案 1 :(得分:0)