首页 文章

使用python在3D中通过点进行平面拟合

提问于
浏览
1

我在3D空间中有分数 .

X        Y       Z
0   0.61853 0.52390 0.26304
1   0.61843 0.52415 0.26297 
2   0.62292 0.52552 0.26108 
3   0.62681 0.51726 0.25622 
4   0.62772 0.51610 0.25903

我已经通过应该垂直划分这些点的点定义了一个平面,但它没有垂直或水平地划分它们 . 当我正在绘制它们时,飞机和点分开 .

def plane_equation(x1, y1, z1, x2, y2, z2, x3, y3, z3):
    a1 = x2 - x1 
    b1 = y2 - y1 
    c1 = z2 - z1 
    a2 = x3 - x1 
    b2 = y3 - y1 
    c2 = z3 - z1 
    a = b1 * c2 - b2 * c1 
    b = a2 * c1 - a1 * c2 
    c = a1 * b2 - b1 * a2 
    d = (- a * x1 - b * y1 - c * z1) 
    return a, b, c, d

# Finding the equation of the plane
a, b, c, d = plane_equation(x0, y0, z0, x1, y1, z1, x2, y2, z2)
print("equation of plane is ", a, "x +", b, "y +", c, "z +", d, "= 0.")

x = np.arange(0, 1, 0.1)
y = np.arange(0, 1, 0.1)

X,Y = np.meshgrid(x,y)
Z = a*X + b*Y + d

fig = plt.figure()
ax = fig.gca(projection='3d')
ax.scatter(df.x, df.y, df.z, color = 'c', marker = 'o', alpha = 0.5)
surf = ax.plot_surface(X, Y, Z)

equation of plane is  -0.0002496952000000007 x + 0.00036812320000000016 y + 0.0007697304000000002 z + -0.00024088567529317268 = 0.

我需要飞机穿过这些点,并且应该在垂直方向 . 蓝色平面应穿过青色点,平面应垂直方向 .

1 回答

  • 1

    这里有几件事可能会出错:

    • too small values

    您的 normal is not normalized 及其坐标的幅度非常小( 0.000??? ),因此您的绘图可能会将所有值都处理为零(因为图像上的绘图是与您提供的值无关的平面 Z=0 ) .

    从您的反馈in chat我的这个假设是正确的,所以解决这个问题只是规范你的正常:

    n(nx,ny,nz) /= sqrt(nx*nx + ny*ny +nz*nz)
    

    并使用以下新值计算 d

    d = nx*x0 + ny*y0 + nz*z0
    

    其中 (x0,y0,z0) 是所选点中的任何一个 .

    • Wrongly selected points

    3个选定的点应该彼此不太靠近而不能在一条线上 . 如果他们这样做,则计算的法线无效 . 此外,如果您选择包含大噪音的点,其精度会降低......

    为了改善这一点,选择3个点随机计算法线 . 计算 n 这样的法线并将它们平均在一起 . n 越高精度越高 .

    • Fit

    为了提高准确性,您可以尝试适应法线和 d . 只需使用 #1#2 中的法线并在近距离内拟合其坐标和 d ,以最小化所有点到平面的平均或最大距离 . 然而,这是 O(n.log^4(m)) ,其中 n 是使用点的数量, m 与每个参数的拟合范围相关,但提供了您可以获得的最佳精度 .

    您可以使用二进制搜索或Approximation search或您的环境可以使用的优化器

相关问题