如何从 MATLAB 中的现有三角剖分创建 delaunayTriangulation 对象

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 时,这个新的内置函数可能会很慢。 ..