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

How to create a delaunayTriangulation object from an existing triangulation in MATLAB

我有一个现有的三角剖分(顶点 xy 以及连接矩阵 tri),我想在这个现有的三角剖分上应用 delaunayTriangulation 类的 PointLocation 方法(很像过时的tsearch 旧版本 MATLAB 中的函数)。

然而,PointLocation 方法显然需要一个 delaunayTriangulation 实例作为输入。 delaunayTriangulation 类似乎总是执行它自己的三角测量过程,这导致与现有的 tri 矩阵不同的连接矩阵,给定顶点 xy.

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