python - 如何找到线段上距离任意点最近的点?

标签 python geometry

该函数应该接受一个点参数,该参数将用于查找线段对象上与其最近的点。在示例断言代码中,函数 getClosestPoint(Point()) 采用 Point(10, 0) 作为参数,并应返回 Point(5,5) code> 作为距离 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

最佳答案

一般的答案是将点投影到线上。 查看它的一种方法是将点转换为由线段定义的引用系( 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 定义)最近的点。

关于python - 如何找到线段上距离任意点最近的点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28931007/

相关文章:

geometry - 通过横截面上的点找到椭圆上的法线 "N"

Javascript Canvas 如何从旋转物体进行 360* 拍摄

javascript - 如何在 Canvas 中绘制圆的下半部分

python - 在 Windows 上安装 pyquery

python - 在python中复制文件

linux - 使用 python 脚本搜索 json 文件

javascript - 确定一个二维向量是在另一个向量的右边还是左边

python - 以 ; 结尾的 Python 语句有什么区别?

python - 在 Gtk.PopoverMenu 中创建单选操作

c++ - 为什么要在 C++ 中的三角形之外生成点?