如何在Matplotlib 3D中填充多边形间的实体区域(带孔洞梁截面)
带孔洞3D梁截面的实体填充解决方案
问题:拥有带孔洞的3D梁截面,初始数据为2D外轮廓多边形与内部孔洞多边形。基于梁长添加Z坐标后,当前仅能填充孔洞区域,需修改
verts参数以填充外轮廓与孔洞之间的实体部分。
核心修改思路
- 端面填充逻辑:使用嵌套多边形结构,外轮廓作为外环、孔洞作为内环(注意内外环缠绕方向需相反,确保Matplotlib正确识别挖空区域)
- 侧壁生成修正:重新实现外轮廓与孔洞的侧壁生成逻辑,连接两端对应顶点形成完整侧壁
- 填充对象整合:将外轮廓侧壁、孔洞侧壁、带孔端面统一加入
Poly3DCollection,实现实体区域填充
修改后的完整代码
import numpy as np from mpl_toolkits.mplot3d import Axes3D from mpl_toolkits.mplot3d.art3d import Poly3DCollection import matplotlib.pyplot as plt # 2D截面数据 shell = [(-500,0), (500,0), (400,500), (-400,500), (-500,0)] # 外轮廓(顺时针) hole1 = [(-200,100), (-300,400), (300,400), (200,100), (-200,100)] # 内孔洞(逆时针,与外轮廓方向相反) length = 20000 ex = np.array(shell) int_ = np.array(hole1) # 为2D多边形添加Z坐标,生成两端的3D多边形 polye1 = np.insert(ex, 2, 0, axis=1) # 外轮廓Z=0端 polye2 = np.insert(ex, 2, length, axis=1) # 外轮廓Z=length端 polyi1 = np.insert(int_, 2, 0, axis=1) # 孔洞Z=0端 polyi2 = np.insert(int_, 2, length, axis=1)# 孔洞Z=length端 # 生成外轮廓的侧壁多边形 outer_walls = [] for i in range(len(polye1)-1): # 连接外轮廓两端的相邻顶点,形成四边形侧壁 outer_walls.append(np.array([polye1[i], polye1[i+1], polye2[i+1], polye2[i]])) # 闭合最后一个侧壁 outer_walls.append(np.array([polye1[-1], polye1[0], polye2[0], polye2[-1]])) # 生成孔洞的侧壁多边形 inner_walls = [] for i in range(len(polyi1)-1): inner_walls.append(np.array([polyi1[i], polyi1[i+1], polyi2[i+1], polyi2[i]])) inner_walls.append(np.array([polyi1[-1], polyi1[0], polyi2[0], polyi2[-1]])) # 生成带孔的端面多边形:外轮廓为外环,孔洞为内环(嵌套结构) end_face1 = [polye1.tolist(), polyi1.tolist()] end_face2 = [polye2.tolist(), polyi2.tolist()] # 整合所有需要填充的多边形 all_polygons = outer_walls + inner_walls + [end_face1, end_face2] # 3D绘图 fig = plt.figure() ax = Axes3D(fig, auto_add_to_figure=False) ax.set_box_aspect([1, 1, 1]) fig.add_axes(ax) # 绘制所有多边形的边缘线(可选) for poly in outer_walls + [polye1, polye2]: x, y, z = zip(*poly) ax.plot(x, z, y, 'b') for poly in inner_walls + [polyi1, polyi2]: x, y, z = zip(*poly) ax.plot(x, z, y, 'r') # 添加3D填充集合 collection = Poly3DCollection(all_polygons, facecolors='cyan', linewidths=1, edgecolors='b', alpha=.25) ax.add_collection3d(collection) # 设置坐标轴标签和视角 ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('z') ax.view_init(30, 120) plt.show()
关键细节说明
- 缠绕方向调整:将孔洞多边形顶点顺序改为逆时针(外轮廓为顺时针),Matplotlib会依据相反的缠绕方向自动识别挖空区域,生成正确的带孔端面
- 端面嵌套结构:
end_face1采用[外轮廓顶点列表, 孔洞顶点列表]的嵌套格式,Poly3DCollection可直接解析该结构实现挖空填充 - 侧壁闭合逻辑:循环遍历顶点生成侧壁后,额外添加首尾顶点的连接多边形,确保侧壁完整闭合
内容的提问来源于stack exchange,提问作者SW84
相关产品推荐
相关产品推荐

