我在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.
我需要平面穿过这些点,并且应该在垂直方向上。蓝色平面应穿过青色点,且平面应垂直。
答案 0 :(得分:1)
这里有些事情可能会出错:
值太小
您的法线未规范化,并且其坐标的幅度很小(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)
是所选点中的任意一个。
错误选择的点
3个选定的点应该彼此不太靠近,并且不能位于一行上。如果这样做,则计算的法线无效。另外,如果您选择包含大噪声的点,则精度会因此降低...
要改善此效果,请选择3个点,随机计算法线。计算n
这样的法线并将其平均。 n
越高,准确性越好。
适合
要进一步提高准确性,您可以尝试拟合法线和d
。只需使用#1 或#2 中的法线,并使其坐标和d
位于附近范围内,以最小化所有点到平面的平均或最大距离。但是,这是O(n.log^4(m))
,其中n
是已使用的点数,m
与每个参数的拟合范围有关,但是可以提供最佳的精度。
您可以使用二进制搜索或Approximation search或您的环境可以使用的任何优化程序