三角剖分平滑狄洛尼

Beginner

This tutorial is from open-source community. Access the source code

简介

本教程演示如何使用 Matplotlib 生成高分辨率的三角剖分等值线图。三角剖分等值线是一种用于在非结构化三角形网格上表示数据的技术。当数据是在不规则间隔的点上收集时,或者当数据本质上是三角形时,经常会用到它。本教程将展示如何生成一组随机点,对这些点进行 Delaunay 三角剖分,屏蔽网格中的一些三角形,细化和插值数据,最后使用 Matplotlib 的 tricontour 函数绘制细化后的数据。

虚拟机使用提示

虚拟机启动完成后,点击左上角切换到 笔记本 标签页,以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作的验证无法自动化。

如果你在学习过程中遇到问题,随时向 Labby 提问。课程结束后提供反馈,我们会及时为你解决问题。

导入所需库

第一步是导入所需的库。本教程将使用 NumPy 和 Matplotlib。

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.tri import TriAnalyzer, Triangulation, UniformTriRefiner

定义测试函数

接下来,我们定义一个表示实验结果的函数。这个函数将用于生成测试数据点。

def experiment_res(x, y):
    """An analytic function representing experiment results."""
    x = 2 * x
    r1 = np.sqrt((0.5 - x)**2 + (0.5 - y)**2)
    theta1 = np.arctan2(0.5 - x, 0.5 - y)
    r2 = np.sqrt((-x - 0.2)**2 + (-y - 0.2)**2)
    theta2 = np.arctan2(-x - 0.2, -y - 0.2)
    z = (4 * (np.exp((r1/10)**2) - 1) * 30 * np.cos(3 * theta1) +
         (np.exp((r2/10)**2) - 1) * 30 * np.cos(5 * theta2) +
         2 * (x**2 + y**2))
    return (np.max(z) - z) / (np.max(z) - np.min(z))

生成测试数据点

我们生成一组随机的测试数据点,其 x 和 y 值在 -1 到 1 之间。我们还使用步骤 2 中定义的 experiment_res 函数生成相应的一组 z 值。

## User parameters for data test points

## Number of test data points, tested from 3 to 5000 for subdiv=3
n_test = 200

## Random points
random_gen = np.random.RandomState(seed=19680801)
x_test = random_gen.uniform(-1., 1., size=n_test)
y_test = random_gen.uniform(-1., 1., size=n_test)
z_test = experiment_res(x_test, y_test)

执行 Delaunay 三角剖分

我们使用 matplotlib.tri 模块中的 Triangulation 函数对测试数据点执行 Delaunay 三角剖分。

## meshing with Delaunay triangulation
tri = Triangulation(x_test, y_test)
ntri = tri.triangles.shape[0]

屏蔽一些三角形

我们在网格中屏蔽一些三角形,以模拟无效数据。我们根据 init_mask_frac 参数随机选择三角形的一个子集。

## Some invalid data are masked out
mask_init = np.zeros(ntri, dtype=bool)
masked_tri = random_gen.randint(0, ntri, int(ntri * init_mask_frac))
mask_init[masked_tri] = True
tri.set_mask(mask_init)

改进三角剖分

我们使用 TriAnalyzer 通过移除三角剖分边界处形状不佳(扁平)的三角形来改进三角剖分。然后我们使用 set_mask 将掩码应用于三角剖分。

## masking badly shaped triangles at the border of the triangular mesh.
mask = TriAnalyzer(tri).get_flat_tri_mask(min_circle_ratio)
tri.set_mask(mask)

细化和插值数据

我们使用 UniformTriRefiner 来细化和插值数据。

## refining the data
refiner = UniformTriRefiner(tri)
tri_refi, z_test_refi = refiner.refine_field(z_test, subdiv=subdiv)

绘制数据

我们使用 Matplotlib 的 tricontour 函数绘制细化后的数据。

## Graphical options for tricontouring
levels = np.arange(0., 1., 0.025)

fig, ax = plt.subplots()
ax.set_aspect('equal')
ax.set_title("Filtering a Delaunay mesh\n"
             "(application to high-resolution tricontouring)")

## plot of the refined (computed) data contours:
ax.tricontour(tri_refi, z_test_refi, levels=levels, cmap='Blues',
              linewidths=[2.0, 0.5, 1.0, 0.5])

plt.show()

总结

本教程演示了如何使用 Matplotlib 生成高分辨率的三角剖分等值线图。我们首先生成了一组随机测试数据点,对这些点进行了 Delaunay 三角剖分,屏蔽了网格中的一些三角形,细化并插值了数据,最后使用 Matplotlib 的 tricontour 函数绘制了细化后的数据。