问题描述
我尝试绘制一个表示环的 3d 实体。我使用了 scipy 模块和 delaunay 来进行计算。 不幸的是,该图显示的是 3d 圆柱体而不是环面。有人知道如何修改代码吗? scipy 是正确的模块吗?我可以使用具有矩形形状的 delaunay 吗? 提前致谢!
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from scipy.spatial import delaunay
points = 50
theta = np.linspace(0,2*np.pi,points)
radius_middle = 7.5
radius_inner = 7
radius_outer = 8
x_m_cartesian = radius_middle * np.cos(theta)
y_m_cartesian = radius_middle * np.sin(theta)
z_m_cartesian = np.zeros(points)
M_m = np.c_[x_m_cartesian,y_m_cartesian,z_m_cartesian]
x_i_cartesian = radius_inner * np.cos(theta)
y_i_cartesian = radius_inner * np.sin(theta)
z_i_cartesian = np.zeros(points)
M_i = np.c_[x_i_cartesian,y_i_cartesian,z_i_cartesian]
x1_m_cartesian = radius_middle * np.cos(theta)
y1_m_cartesian = radius_middle * np.sin(theta)
z1_m_cartesian = np.ones(points)
M1_m = np.c_[x1_m_cartesian,y1_m_cartesian,z1_m_cartesian]
x2_i_cartesian = radius_inner * np.cos(theta)
y2_i_cartesian = radius_inner * np.sin(theta)
z2_i_cartesian = np.ones(points)
M2_i = np.c_[x2_i_cartesian,y2_i_cartesian,z2_i_cartesian]
M = np.vstack((M_m,M_i,M1_m,M2_i))
# delaunay
CH = delaunay(M).convex_hull
x,y,z = M[:,0],M[:,1],2]
fig = plt.figure(figsize=(12,8))
ax = fig.add_subplot(111,projection='3d')
#ax.scatter(x[:,y[:,z[:,2])
ax.plot_trisurf(x,z,triangles=CH,shade=False,color='lightblue',lw=1,edgecolor='k')
plt.show()
解决方法
如评论中所述,凸包是凸形,因此不能表示环。但是,concave hull
(也称为 alpha-shape
)的概念可能适合您的需要。基本上,alpha 形状从 Delaunay 三角剖分中删除了圆周半径大于某个值(由 alpha
参数定义)的三角形(在 3D 情况下为四面体)。
This answer 为 3D 点提供了 alpha 形状表面(即外边界)的实现。使用该答案中的 alpha_shape_3D
函数,alpha 值为 3,得到下图。
代码中的以下两行(替换 CH
的赋值和 plot 函数)完成工作。
vertices,edges,facets = alpha_shape_3D(pos=M,alpha=3.)
ax.plot_trisurf(x,y,z,triangles=facets,shade=False,color='lightblue',lw=1,edgecolor='k')