How to create a delaunayTriangulation object from an existing triangulation in MATLAB
我有一个现有的三角剖分(顶点 x 和 y 以及连接矩阵 tri),我想在这个现有的三角剖分上应用 delaunayTriangulation 类的 PointLocation 方法(很像过时的tsearch 旧版本 MATLAB 中的函数)。
然而,PointLocation 方法显然需要一个 delaunayTriangulation 实例作为输入。 delaunayTriangulation 类似乎总是执行它自己的三角测量过程,这导致与现有的 tri 矩阵不同的连接矩阵,给定顶点 x 和 y.
有没有办法将 PointLocation(或类似 tsearch)应用于我现有的三角测量?我有 Matlab 2013a。
把一个 triangulation 变成一个 delaunayTriangulation:
-
对于所有 triangulation 来说当然不可能,因为它们不满足 Delaunay 属性。
-
如果您的 trep 表现良好,则受约束的 Delaunay 三角剖分可能会起作用,但可能会添加额外的三角形和随机节点:
delaunayTriangulation(trep.Points, trep.edges);
因此我建议你以下
解决方法:
您可以使用 triangulation 类中的方法构建解决方法:
1 2 3
| trep = triangulation (tri, x, y );
QPs = rand(10, 2); % Query points.
TI = pointLocation (trep, QPs ); |
使用自制功能 pointLocation:
1 2 3 4 5 6 7
| function TI = pointLocation (trep, QPs )
% Find query point QPs in triangulation trep
TI = cell(size(QPs, 1), 1);
for i = 1: size(QPs, 1)
barys = trep. cartesianToBarycentric((1: size(trep, 1))', repmat(QPs (i,: ), size(trep, 1), 1));
TI {i} = find(all((0<=barys )& (barys<= 1), 2));
end |
请注意,TI 是一个元胞数组,对于三角剖分,我们无法确定它们在某种意义上是规则的,即只有一个三角形/四面体包含该点。其工作方式是计算查询点相对于所有三角形/四面体的重心坐标,然后使用这些坐标检查这些点是否实际上在其中。 (如果所有重心坐标都在 0<=bx,by,bz<=1 内,就是这种情况。)
我认为没有一种简单的方法可以让 MATLAB 的内置三角测量例程为您执行此操作 - 正如您所指出的,它们明确要求三角测量是 Delaunay...
不过,您可能有兴趣查看我的 FINDTRIA 例程(可从 MATLAB 文件交换中获得)。 FINDTRIA 是一个工具箱,旨在对任意(d 维)三角剖分执行点位置查询,包括非 Delaunay、非凸甚至重叠的三角剖分,因此它应该按原样处理您的三角剖分。
虽然不如 MATLAB 的内置 pointLocation 例程快(当底层三角剖分是 Delaunay 时),但 FINDTRIA 通常比通过每个点/三角形进行蛮力 O(n*m) 搜索要高效得多一对。 FINDTRIA 使用几何搜索树——AABB 树——来加速计算。
从 R2014b 开始,MATLAB 还支持使用 pointLocation 例程对非 Delaunay 三角剖分进行查询,尽管我最初的经验似乎表明,当三角剖分不是 Delaunay 时,这个新的内置函数可能会很慢。 ..