Matlab:来自补丁对象的邻接矩阵

Matlab: adjacency matrix from patch object

我有一个 Matlab patch 对象,其中 Faces 属性 是顶点索引三元组的列表,因此每一行代表一个三角形面。例如:

   293    13     1
   433    13   293
   293   294   433
   434   433   294

在这种情况下,第一行定义了一个在顶点 1,13 和 293 之间拉伸的面。我的实际矩阵大约有 200,000 个顶点和 400,000 个面。

我想形成一个顶点邻接矩阵,例如稀疏二进制方阵 A s.t。 A(i,j)true 当且仅当顶点 ij 有一个共享面。

在matlab中有什么有效的方法吗?一个简单的 for 循环在每次迭代中搜索出现的一张脸很慢。

使用sparse构造函数,让nv成为你拥有的顶点数,然后

A = sparse( Faces(:,1), Faces(:,2), 1, nv, nv ) + ...
    sparse( Faces(:,2), Faces(:,3), 1, nv, nv ) + ...
    sparse( Faces(:,3), Faces(:,1), 1, nv, nv );
A = spfun( @(x) 1, A + A.' ); %// make it symmetric

这可以用于任意维度的单纯数据:

halfedges = nchoosek(1:size(Faces,2), 2);
edges = [halfedges; fliplr(halfedges)];
A = logical(sparse(Faces(:,edges(:,1)), Faces(:,edges(:,2)), 1));

如果您更关心内存开销而不是速度,您可以循环遍历边缘:

nv = max(Faces(:)); % Get the maximum vertex id.

halfedges = nchoosek(1:size(Faces,2), 2);
edges = [halfedges; fliplr(halfedges)];
A = sparse(nv,nv);
for i = 1:size(edges,1)
    A = A | logical(sparse(Faces(:,edges(i,1)), Faces(:,edges(i,2)), 1, nv, nv));
end

另一种方法是构建一个 triangulation 对象,然后使用内置的 isConnected 函数。