如何从顶点和单纯形实例化scipy Delaunay三角剖分?
解决思路
方法一:手动填充Delaunay内部属性(需注意版本兼容性)
scipy的Delaunay类依赖若干核心属性实现find_simplex,可以手动构造这些属性来复用已有剖分,但这属于依赖内部实现的操作,后续scipy版本更新可能导致失效:
- 先通过顶点初始化一个临时
Delaunay实例,再覆盖核心属性:points: 你的顶点数组simplices: 已有的单纯形数组neighbors: 若没有邻接信息,可用-1填充同维度数组vertex_to_simplex: 可选的加速映射,每个顶点关联一个包含它的单纯形索引
- 示例代码:
import numpy as np from scipy.spatial import Delaunay vertices = np.array([[0,0], [1,0], [0,1], [1,1]]) simplices = np.array([[0,1,2], [1,2,3]]) # 初始化临时实例,之后覆盖属性 tri = Delaunay(vertices) tri.points = vertices tri.simplices = simplices # 填充邻接信息(无则用-1) tri.neighbors = np.full((len(simplices), 3), -1, dtype=int) # 手动设置顶点到单纯形的映射 tri.vertex_to_simplex = np.array([0,0,0,1], dtype=int) # 测试点定位 point = np.array([0.5, 0.2]) print(tri.find_simplex(point)) # 预期返回0
注意:部分内部属性(如transform)若未正确设置,可能导致find_simplex结果错误或崩溃。
方法二:自定义点定位逻辑
若不想依赖scipy内部结构,可自行实现点定位算法,或借助其他库:
- 小规模数据集可直接遍历单纯形,判断点是否在内部:
def point_in_simplex(point, vertices, simplex): # 2D三角形内点判断:计算重心坐标 v0, v1, v2 = vertices[simplex] v0v1 = v1 - v0 v0v2 = v2 - v0 v0p = point - v0 dot00 = np.dot(v0v1, v0v1) dot01 = np.dot(v0v1, v0v2) dot02 = np.dot(v0v1, v0p) dot11 = np.dot(v0v2, v0v2) dot12 = np.dot(v0v2, v0p) denom = dot00 * dot11 - dot01 * dot01 u = (dot11 * dot02 - dot01 * dot12) / denom v = (dot00 * dot12 - dot01 * dot02) / denom return (u >= 0) and (v >= 0) and (u + v <= 1) def custom_find_simplex(point, vertices, simplices): for idx, simplex in enumerate(simplices): if point_in_simplex(point, vertices, simplex): return idx return -1 # 使用示例 point = np.array([0.5, 0.2]) print(custom_find_simplex(point, vertices, simplices)) # 返回0
- 大规模数据集可使用
triangle等专业三角剖分库,支持导入已有剖分并提供高效点定位。
方法三:向scipy提交功能请求
若该需求具备普遍性,可在scipy的GitHub仓库提交Feature Request,提议添加from_vertices_and_simplices类方法,社区可能采纳并实现该功能。
内容的提问来源于stack exchange,提问作者Charles
相关产品推荐
相关产品推荐

