1

I have points in 3D space.

       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 

I have defined a plane through the points which should vertically divide these points, but it is not dividing them vertically or horizontally. The plane and the points are way apart while I'm plotting them.

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.

I need plane to pass through these points and should be in vertical direction. The blue plane should pass through cyan points and plane should be in vertical direction.

Upriser
  • 418
  • 2
  • 7
  • 23

1 Answers1

1

There are several things that might go wrong here:

  1. too small values

    Your normal is not normalized and its coordinates are very small magnitude (0.000???) so its possible that your plot is handling all the values as zero (as the plot on your image is of the plane Z=0 which has nothing to do with values you provided).

    From your feedback in chat This assumption of mine was right so to solve this problem just normalize your normal:

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

    And compute the d with this new values:

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

    where (x0,y0,z0) is any from the selected points.

  2. Wrongly selected points

    The 3 selected points should be not too close to each other and not on a single line. If they do the computed normal is invalid. Also if you select points containing big noise the accuracy is lowered by it...

    To improve this select 3 points randomly compute normal. Compute n such normals and average them together. The higher n the better accuracy.

  3. Fit

    To improve accuracy even more you can try to fit the normal and d. simply by using normal from #1 or #2 and fit its coordinates and d in near range to minimize the avg or max distance of all points to plane. However this is O(n.log^4(m)) where n is the number of used points and m relate to the fitted range of each parameter, but provides the best accuracy you can get.

    You can use binary search or Approximation search or what ever optimizer your environment have at disposal

Spektre
  • 49,595
  • 11
  • 110
  • 380