【问题标题】:Matlab: adjacency matrix from patch objectMatlab:来自补丁对象的邻接矩阵
【发布时间】:2015-02-11 13:08:08
【问题描述】:

我有一个 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 iff 顶点 i,j 具有共享面。

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

【问题讨论】:

    标签: matlab graph 3d adjacency-matrix


    【解决方案1】:

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

    【讨论】:

    • spfun真的比A = (A+A.')>0;快吗?
    • @LuisMendo 我没有测试它,但我怀疑它是。 spfun 仅适用于非零元素,而 (A+A.')>0 实际上计算 nv-by-nv 矩阵的 所有 项。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2012-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-31
      • 1970-01-01
      相关资源
      最近更新 更多