Pyvoro输出格式解析、多面体还原及3D Voronoi可视化问询
Pyvoro 3D Voronoi剖分输出解读与可视化指南
一、输出核心字段解读
1. adjacency 字段含义
adjacency列表中的每个元素对应当前Voronoi胞体的一个面,值代表该面的相邻对象索引:
- 如果是非负整数,比如
1,表示当前胞体和索引为1的胞体共享这个面; - 如果是
-1,表示这个面是Voronoi胞体与你设定的边界框(即compute_voronoi的第二个参数[[0.0,10.0],...])的交界面。
2. 还原Voronoi多面体
Pyvoro的每个胞体通过vertices和faces两个字段完整定义多面体结构:
vertices:所有顶点的三维坐标列表,每个元素是[x,y,z],顶点从0开始按顺序编号;faces:每个面是一个字典,包含vertices和adjacency两个键:vertices:构成当前面的顶点索引列表,按顺序连接这些索引对应的坐标即可得到闭合的多边形面;adjacency:该面对应的相邻对象索引(和胞体根级的adjacency列表一一对应)。
提取单个胞体完整面数据的示例代码:
cell = cells[0] for face in cell['faces']: # 根据索引获取面的顶点坐标 face_vertices = [cell['vertices'][idx] for idx in face['vertices']] print("当前面的顶点坐标:", face_vertices)
二、3D可视化实现
方法1:Matplotlib 静态可视化
依赖安装:pip install matplotlib
示例代码:
import pyvoro import matplotlib.pyplot as plt from mpl_toolkits.mplot3d.art3d import Poly3DCollection # 计算Voronoi胞体 cells = pyvoro.compute_voronoi( [[1.0, 2.0, 3.0], [4.0, 5.5, 6.0]], [[0.0, 10.0], [0.0, 10.0], [0.0, 10.0]], 2.0, radii=[1.3, 1.4] ) # 创建3D画布 fig = plt.figure(figsize=(8,6)) ax = fig.add_subplot(111, projection='3d') # 遍历绘制每个胞体 colors = ['cyan', 'magenta'] for cell_idx, cell in enumerate(cells): face_list = [] for face in cell['faces']: face_verts = [cell['vertices'][vid] for vid in face['vertices']] face_list.append(face_verts) # 生成3D多边形集合并添加到画布 poly_collection = Poly3DCollection(face_list, facecolors=colors[cell_idx], alpha=0.5, edgecolors='black') ax.add_collection3d(poly_collection) # 设置坐标轴范围与标签 ax.set_xlim(0, 10) ax.set_ylim(0, 10) ax.set_zlim(0, 10) ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') plt.show()
方法2:Plotly 交互式可视化
依赖安装:pip install plotly
示例代码:
import pyvoro import plotly.graph_objects as go # 计算Voronoi胞体 cells = pyvoro.compute_voronoi( [[1.0, 2.0, 3.0], [4.0, 5.5, 6.0]], [[0.0, 10.0], [0.0, 10.0], [0.0, 10.0]], 2.0, radii=[1.3, 1.4] ) fig = go.Figure() # 绘制每个胞体的面 colors = ['rgba(0,255,255,0.5)', 'rgba(255,0,255,0.5)'] for cell_idx, cell in enumerate(cells): for face in cell['faces']: face_verts = [cell['vertices'][vid] for vid in face['vertices']] # 闭合面需要追加第一个顶点 face_verts.append(face_verts[0]) x, y, z = zip(*face_verts) fig.add_trace(go.Mesh3d( x=x, y=y, z=z, color=colors[cell_idx], opacity=0.5 )) # 绘制原始生成点 points = [[1.0,2.0,3.0], [4.0,5.5,6.0]] x_p, y_p, z_p = zip(*points) fig.add_trace(go.Scatter3d( x=x_p, y=y_p, z=z_p, mode='markers', marker=dict(size=6, color='black') )) # 设置场景范围 fig.update_layout(scene=dict( xaxis=dict(range=[0,10]), yaxis=dict(range=[0,10]), zaxis=dict(range=[0,10]) )) fig.show()
三、常见问题排查
你提到提取内容未得到预期多面体,可能的原因:
- 打乱了面顶点的顺序:Pyvoro输出的面顶点是按闭合多边形的顺序排列的,直接按索引取坐标连接即可,不要随意调整顺序;
- 遗漏了边界面:
adjacency为-1的面是胞体与边界框的交界,属于多面体的一部分,不能忽略。
内容的提问来源于stack exchange,提问作者Mr Thomas Anderson
相关产品推荐
相关产品推荐

