3D convex hull from point cloud

2019-02-10 00:46发布

I need to plot a 3D point cloud (number of points: N), then a convex hull (actually a polyhedron with N vertices) from the points. I made a script in python with scipy.spatial ConvexHull for plot 8 points and plot a cube, the plot of the point cloud is ok, but the cube is not ok, because the code puts two lines going across the diagonal face of the cube in addition to the edge lines. I don't understand why plot lines across faces.

The script:

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from scipy.spatial import ConvexHull  

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

points= np.array([[0,0,0],
            [4,0,0],
            [4,4,0],
            [0,4,0],
            [0,0,4],
            [4,0,4],
            [4,4,4],
            [0,4,4]])

hull=ConvexHull(points)

edges= zip(*points)

for i in hull.simplices:
    plt.plot(points[i,0], points[i,1], points[i,2], 'r-')

ax.plot(edges[0],edges[1],edges[2],'bo') 

ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')

ax.set_xlim3d(-5,5)
ax.set_ylim3d(-5,5)
ax.set_zlim3d(-5,5)

plt.show()

Result of the script:

enter image description here

标签: python plot 3d
1条回答
贪生不怕死
2楼-- · 2019-02-10 01:21

I know this is old, but I came here from Google so I think others might too.

The problem is only in the plotting method you use. One simplex is a nD triangle defined by 3 points. But the plotting function must cycle back to the last point, otherwise only 2 of 3 simplex edges are drawn.

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from scipy.spatial import ConvexHull


# 8 points defining the cube corners
pts = np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0],
                [0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1], ])

hull = ConvexHull(pts)

fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")

# Plot defining corner points
ax.plot(pts.T[0], pts.T[1], pts.T[2], "ko")

# 12 = 2 * 6 faces are the simplices (2 simplices per square face)
for s in hull.simplices:
    s = np.append(s, s[0])  # Here we cycle back to the first coordinate
    ax.plot(pts[s, 0], pts[s, 1], pts[s, 2], "r-")

# Make axis label
for i in ["x", "y", "z"]:
    [enter image description here][1]eval("ax.set_{:s}label('{:s}')".format(i, i))

plt.show()
查看更多
登录 后发表回答