python - 如何在 Python 中可视化 3D delaunay 三角剖分?

标签 python scipy vtk mayavi mplot3d

我有一组 3D 点,我使用 scipy.spatial.Delaunay 进行三角剖分/四面体化。我现在拥有一组所有四面体的独特面孔,并希望以 3D 形式可视化这些面孔。

是否有任何 Python 库(或带有 Python 包装器的库)可以做到这一点?

最佳答案

也可以使用matplotlib的三维绘图来完成(不需要mayavi包)。

以下代码是此类功能的初步简单实现。

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

def plot_tri_simple(ax, points, tri):
    for tr in tri.simplices:
        pts = points[tr, :]
        ax.plot3D(pts[[0,1],0], pts[[0,1],1], pts[[0,1],2], color='g', lw='0.1')
        ax.plot3D(pts[[0,2],0], pts[[0,2],1], pts[[0,2],2], color='g', lw='0.1')
        ax.plot3D(pts[[0,3],0], pts[[0,3],1], pts[[0,3],2], color='g', lw='0.1')
        ax.plot3D(pts[[1,2],0], pts[[1,2],1], pts[[1,2],2], color='g', lw='0.1')
        ax.plot3D(pts[[1,3],0], pts[[1,3],1], pts[[1,3],2], color='g', lw='0.1')
        ax.plot3D(pts[[2,3],0], pts[[2,3],1], pts[[2,3],2], color='g', lw='0.1')

    ax.scatter(points[:,0], points[:,1], points[:,2], color='b')

用下面的测试代码调用这个函数的结果如下图: enter image description here

np.random.seed(0)
x = 2.0 * np.random.rand(20) - 1.0
y = 2.0 * np.random.rand(20) - 1.0
z = 2.0 * np.random.rand(20) - 1.0
points = np.vstack([x, y, z]).T
tri = Delaunay(points)

fig = plt.figure()
ax = plt.axes(projection='3d')
plot_tri(ax, points, tri)

上面的代码很慢,因为绘图是在循环内完成的。此外,它单独作用于每个单纯形,因此边缘被渲染不止一次。 下面是一个更高效的实现,它利用辅助函数 collect_edges 使每条边只取一次,并使用 plot 函数中的 np.nan 值来绘制边段在单个绘图命令中。

使用新函数运行上面的测试代码的结果给出了相同的数字,但运行时间在我的机器上提高了 x80 倍(300 毫秒与 3.6 毫秒相比)。

def plot_tri_2(ax, points, tri):
    edges = collect_edges(tri)
    x = np.array([])
    y = np.array([])
    z = np.array([])
    for (i,j) in edges:
        x = np.append(x, [points[i, 0], points[j, 0], np.nan])      
        y = np.append(y, [points[i, 1], points[j, 1], np.nan])      
        z = np.append(z, [points[i, 2], points[j, 2], np.nan])
    ax.plot3D(x, y, z, color='g', lw='0.1')

    ax.scatter(points[:,0], points[:,1], points[:,2], color='b')


def collect_edges(tri):
    edges = set()

    def sorted_tuple(a,b):
        return (a,b) if a < b else (b,a)
    # Add edges of tetrahedron (sorted so we don't add an edge twice, even if it comes in reverse order).
    for (i0, i1, i2, i3) in tri.simplices:
        edges.add(sorted_tuple(i0,i1))
        edges.add(sorted_tuple(i0,i2))
        edges.add(sorted_tuple(i0,i3))
        edges.add(sorted_tuple(i1,i2))
        edges.add(sorted_tuple(i1,i3))
        edges.add(sorted_tuple(i2,i3))
    return edges

关于python - 如何在 Python 中可视化 3D delaunay 三角剖分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20025784/

相关文章:

python - 如何更改pandas数据框中多索引中的外层索引?

python - pandas 等同于 countifs

python - 设置对象实例变量的正确方法

python - 如何在 Python 中对数字进行分类和分类?

python - 如何为向量输入和观测值建立线性最小二乘回归模型

c++ - 如何使用 QT 在 C++ 中的 VTK 中转换过滤器的输出?

python-3.7 - vtkCommonCorePython 在 Ubuntu 20 上的 python3-paraview 中丢失错误

c++ - itk filereader 导致访问冲突异常

javascript - 如何使用 AJAX 与服务器通信并在服务器上运行代码?

python - 从曲线形状中获取均匀分布的点