Delaunay三角剖分后如何生成边索引并按长度阈值过滤后绘图
Delaunay三角剖分边过滤实现方案
1. 实现逻辑说明
我们先从生成的Delaunay三角剖分结果中提取所有无重复边,计算每条边的欧氏长度,再按设定阈值过滤,最后绘制处理后的结果。
2. 分步实现代码
2.1 提取边并计算长度
你要求的边索引格式可以通过以下代码生成:
import numpy as np from scipy.spatial import Delaunay # 原始数据和Delaunay生成代码 points = np.array([[0, 0], [0, 1.1], [1, 0], [1, 1], [1.5, 0.6], [1.2, 0.5], [1.7, 0.9], [1.1, 0.1]]) tri = Delaunay(points) # 提取所有不重复的边 edges = set() for tri_idx in tri.simplices: # 遍历单个三角形的三条边 for i, j in [(0,1), (1,2), (2,0)]: # 对边的两个顶点索引排序,避免(1,0)和(0,1)被识别为不同边 edge = tuple(sorted((tri_idx[i], tri_idx[j]))) edges.add(edge) # 生成要求格式的边列表 edge_list = [] for e_id, (p1_idx, p2_idx) in enumerate(edges, start=1): p1 = points[p1_idx] p2 = points[p2_idx] # 计算欧氏距离作为边长度 length = np.linalg.norm(p1 - p2) edge_list.append([f'e{e_id}', tuple(p1), tuple(p2), length])
运行后edge_list的格式和你给出的示例完全一致。
2.2 按阈值过滤边
设定长度阈值,保留符合要求的边:
# 示例:保留长度小于0.8的边,可根据需求调整阈值和判断条件 threshold = 0.8 filtered_edges = [e for e in edge_list if e[3] < threshold]
2.3 绘制处理后的结果
用matplotlib绘制过滤后的三角剖分结果:
import matplotlib.pyplot as plt # 绘制原始点 plt.scatter(points[:, 0], points[:, 1], c='red', s=40, zorder=2) # 绘制过滤后的边 for e in filtered_edges: (x1, y1), (x2, y2) = e[1], e[2] plt.plot([x1, x2], [y1, y2], c='steelblue', zorder=1) plt.axis('equal') plt.xlabel('X坐标') plt.ylabel('Y坐标') plt.title(f'过滤后Delaunay三角剖分(长度阈值={threshold})') plt.show()
3. 完整可运行代码
import numpy as np from scipy.spatial import Delaunay import matplotlib.pyplot as plt # 1. 生成Delaunay三角剖分 points = np.array([[0, 0], [0, 1.1], [1, 0], [1, 1], [1.5, 0.6], [1.2, 0.5], [1.7, 0.9], [1.1, 0.1]]) tri = Delaunay(points) # 2. 提取边并计算长度 edges = set() for tri_idx in tri.simplices: for i, j in [(0,1), (1,2), (2,0)]: edge = tuple(sorted((tri_idx[i], tri_idx[j]))) edges.add(edge) edge_list = [] for e_id, (p1_idx, p2_idx) in enumerate(edges, start=1): p1 = points[p1_idx] p2 = points[p2_idx] length = np.linalg.norm(p1 - p2) edge_list.append([f'e{e_id}', tuple(p1), tuple(p2), length]) # 3. 按阈值过滤边 threshold = 0.8 filtered_edges = [e for e in edge_list if e[3] < threshold] # 4. 绘制结果 plt.scatter(points[:, 0], points[:, 1], c='red', s=40, zorder=2) for e in filtered_edges: (x1, y1), (x2, y2) = e[1], e[2] plt.plot([x1, x2], [y1, y2], c='steelblue', zorder=1) plt.axis('equal') plt.xlabel('X坐标') plt.ylabel('Y坐标') plt.title(f'过滤后Delaunay三角剖分(长度阈值={threshold})') plt.show()
内容的提问来源于stack exchange,提问作者Drizzle
相关产品推荐
相关产品推荐

