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

时间:2015-02-11 13:08:09

标签: matlab graph 3d adjacency-matrix

我有一个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有共享面,则为for

在matlab中有没有有效的方法呢?在每次迭代中搜索一个面的出现的简单{{1}}循环很慢。

2 个答案:

答案 0 :(得分:3)

使用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

答案 1 :(得分:1)

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

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函数。