如何检查所有给定点(空间中)是否位于同一条线上?

问题描述 投票:0回答:1

我需要实现一个函数,将任意数量的点的坐标作为输入数据,并根据这些点是否位于同一条线上返回TrueFalse

我使用Python来解决这个问题,现在我有以下实现:

def are_colinear(points, tolerance): # variable "points" is list of lists with points coordinates
    for i in range(2, len(points)):
        if (points[i][0] - points[i-2][0])/(points[i-1][0] - points[i-2][0]) - (points[i][1] - points[i-2][1])/(points[i-1][1] - points[i-2][1]) < tolerance and \
           (points[i][1] - points[i-2][1])/(points[i-1][1] - points[i-2][1]) - (points[i][2] - points[i-2][2])/(points[i-1][2] - points[i-2][2]) < tolerance:
            continue
        else:
            return False
    return True

该方法基于穿过两点的直线方程:

这种方法的缺点是,如果您想检查属于同一平面的点,它会引发错误(在这种情况下,三个坐标之一始终等于零,因此分母之一为零)。我需要更好的实施。预先感谢您!

python arrays algorithm math geometry
1个回答
0
投票

您可以使用下一个方法:
-以参数形式通过前两个点画一条线
-使用标量(点)积查找其他点在这条线上的垂直投影的长度
-比较投影长度与公差

def are_colinear(points, tolerance):
    dx01 = points[1][0]-points[0][0]
    dy01 = points[1][1]-points[0][1]
    dz01 = points[1][2]-points[0][2]
    mult = 1.0 / (dx01*dx01+dy01*dy01+dz01*dz01)
    for i in range(2, len(points)):
        cdx = points[i][0] - points[0][0]
        cdy = points[i][1] - points[0][1]
        cdz = points[i][2] - points[0][2]
        t = (cdx*dx01+cdy*dy01+cdz*dz01) * mult
        perplen = math.sqrt((t*dx01-cdx)**2+ (t*dy01-cdy)**2 +(t*dz01-cdz)**2)
        if perplen > tolerance:
            return False
    return True

 print(are_colinear([[0,0,0],[2,2,2],[1,0.9999999,1.0000001]], 1e-6))
 print(are_colinear([[0,0,0],[2,2,2],[1,0.9999,1.00001]], 1e-6))
© www.soinside.com 2019 - 2024. All rights reserved.