我有一个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
如果顶点i
,j
有共享面,则为for
。
在matlab中有没有有效的方法呢?在每次迭代中搜索一个面的出现的简单{{1}}循环很慢。
答案 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
函数。