python 中的平面交集

Plane-plane intersection in python

我需要以 AX+BY+CZ+D=0 的形式计算两个平面的交点,并以两个 (x,y,z) 点的形式得到一条直线。我知道如何计算,但我想避免发明自行车并使用有效且经过测试的东西。是否有任何图书馆已经实现了这个?尝试搜索 opencv 和 google,但没有成功。

这是通过基本向量计算解决的,substantial/useful 不足以值得库实现。使用 Numpy 计算数学。

直线方向由两个法向量(A、B、C)的叉积给出,找到一个点就足够了,比如两个给定平面的交点和垂直于线方向并通过原点(通过求解 3x3 系统)。


对于平行平面计算当然会失败,对于几乎平行的平面在数值上不稳定,但我认为您无能为力。

最后,我通过将 Ax+By+Cz+D=0 方程转换为 (n,pt) 公式,重用了 sympy 库:

def planeCoeffToPoint(n,d):
    nabs = [abs(i) for i in n]
    i=nabs.index(max(nabs))
    r=[0,0,0]
    r[i]=-d/n[i]
    return r

import sympy as sp
n1=(A1,B1,C1)
D1=...
n2=(A2,B2,C2)
D2=...
pt1=planeCoeffToPoint(n1,D1)
pt2=planeCoeffToPoint(n2,D2)
pl1 = sp.Plane(pt1, normal_vector=n1)
pl2 = sp.Plane(pt2, normal_vector=n2)
r=pl1.intersection(pl2)
rp1=r[0].points[0]
rp2=r[0].points[1]
[float(rp1[0]), float(rp1[1]), float(rp1[2])] # first point on line
[float(rp2[0]), float(rp2[1]), float(rp2[2])] # second point on line

您必须显式调用 float(),因为 sympy 可能 return 零或 Rational 对象,代表浮点数。

我的numpy解决方案:

def plane_intersect(a, b):
    """
    a, b   4-tuples/lists
           Ax + By +Cz + D = 0
           A,B,C,D in order  

    output: 2 points on line of intersection, np.arrays, shape (3,)
    """
    a_vec, b_vec = np.array(a[:3]), np.array(b[:3])

    aXb_vec = np.cross(a_vec, b_vec)

    A = np.array([a_vec, b_vec, aXb_vec])
    d = np.array([-a[3], -b[3], 0.]).reshape(3,1)

# could add np.linalg.det(A) == 0 test to prevent linalg.solve throwing error

    p_inter = np.linalg.solve(A, d).T

    return p_inter[0], (p_inter + aXb_vec)[0]


a, b = (1, -1, 0, 2), (-1, -1, 1, 3)
plane_intersect(a, b)

Out[583]: (array([ 0.,  2., -1.]), array([-1.,  1., -3.]))

一个测试,subs 点回来:

p1, p2 = plane_intersect(a, b)
a_vec, b_vec = np.array(a[:3]), np.array(b[:3])

(np.dot(p1, a_vec), np.dot(p2, a_vec), np.dot(p1, b_vec), np.dot(p2, b_vec))
Out[585]: (-2.0, -2.0, -3.0, -3.0)