3D线的交点

时间:2020-03-16 14:40:55

标签: python numpy geometry

我编写了一个函数,该函数应计算一条线与赋予它的所有线之间的所有交点,并以3D形式进行计算。我将这些行参数化,因为这似乎是处理事物的最简单方法。问题是,当我将变量“ t1”和“ t2”重新输入到各行的函数中时,似乎存在一个误差太大,无法满足我所需要的东西。

t1是您想知道其所有交点的线的参数,因此以以下形式编写:

x = xo + t1 * dx
y = yo + t1 * dy
z = zo + t1 * dz

其中[xo,yo,zo]代表直线上我称为“原点”的点,[dx,dy,dz]代表那条线的方向。其他行以相同的形式给出,我编写的函数基本上可以解决以下方程:

xo1 + t1 * dx1 = xo2 + t2 * dx2
yo1 + t1 * dy1 = yo2 + t2 * dy2
zo1 + t1 * dz1 = zo2 + t2 * dz2

除了t1和t2之外,所有内容都给出了,这就是我在这里寻找的。但是,我不认为实际上找到t1和t2是问题,我确实有一种解决方案,可以提供某种结果。如前所述,问题实际上是,当我将t1和t2送回这些公式以获取实际的交点时,它们彼此之间略有不同。我说的是欧几里德距离之间的差异大多为0.005-0.05。但是在极端情况下,误差可能高达0.5。我知道大多数3D线都不相交,因此没有方程的解,但是对于我现在正在做的测试,我100%确信所有线都在同一平面内,但有些可能彼此平行。但是,这些错误在所有行中都会发生,我真的只是在寻找一种解决方案,当它们相交时可以准确地获取它。

这是我的代码:

def lineIntersection(self, lines):
    origins = np.zeros((len(lines), 3), dtype=np.float32)
    directions = np.zeros((len(lines), 3), dtype=np.float32)
    for i in range(0, len(lines)):
        origins[i] = lines[i].origin
        directions[i] = lines[i].direction

    ox = origins[:, 0]
    oy = origins[:, 1]
    dx = self.origin[0]
    dy = self.origin[1]
    x1 = directions[:, 0]
    y1 = directions[:, 1]
    x2 = self.direction[0]
    y2 = self.direction[1]
    t2 = np.divide((np.subtract(np.add(oy, np.multiply(np.divide(np.subtract(dx, ox), x1), y1)), dy)), np.subtract(y2, np.multiply(np.divide(x2, x1), y1)))
    t1 = np.divide((np.add(dx, np.subtract(np.multiply(t2, x2), ox))), x1)

    testx1 = np.add(ox, np.multiply(t1, x1))
    testx2 = np.add(dx, np.multiply(t2, x2))
    testy1 = np.add(oy, np.multiply(t1, y1))
    testy2 = np.add(dy, np.multiply(t2, y2))
    testz1 = np.add(origins[:, 2], np.multiply(t1, directions[:, 2]))
    testz2 = np.add(self.origin[2], np.multiply(t2, self.direction[2]))

    arr1 = np.array([testx1, testy1, testz1]).T
    arr2 = np.array([testx2, testy2, testz2]).T
    diff = np.linalg.norm(np.subtract(arr1, arr2), axis=1)
    narr = arr1[diff < 0.05] #Filtering out points that aren't actually intersecting
    nt2 = t2[diff < 0.05]

    return narr, nt2

此函数位于“线”类中,具有如前所述的原点和方向。输入的内容是“ Line”类中的对象数组。

因此,我要问的是,为什么这似乎不如我所希望的那样精确,以及如何解决。或者,如果有其他方法可以计算出真正准确的交点,我很想听听。

1 个答案:

答案 0 :(得分:0)

对于形成小角度的线的交点,通常会出现误差。
我没有检查您的算法正确性,但似乎您只是使用linalg求解器来求解三个方程组。
在几乎平行的线的情况下,中间值(行列式)可能很小,从而导致重大错误。
您是否尝试过更强大的数字算法,例如SVD?

但是也许您真的不需要它们:

请注意,当您确定所有线条都在同一平面上时,可以利用2D算法-只需检查dx,dy,dz的哪个分量的幅度最小(检查一些不同的直线),然后忽略相应的分量-这类似于将线投影到OXY或OXZ或OYZ平面上。 2D代码应为much simpler

对于真实的3D情况,有一种经过充分测试的矢量方法旨在查找两条倾斜线之间的距离(最短的线段)-相交线的长度仅为零。 Example here

请注意,det(行列式)量级也会被评估以检查平行(和几乎平行)线。

相关问题