【问题标题】:Most efficient way to draw a bunch of 3d lines in matlab在matlab中绘制一堆3d线的最有效方法
【发布时间】:2011-08-21 11:37:54
【问题描述】:

我需要在 matlab 中绘制一个 3d 线列表。最快的方法是什么? 我目前正在做类似的事情

%edges is a MX2 matrix, holding the list of edges
%points are the vertices' coordinates
hold on; %so all the lines will be saved
for i=1:size(edges,1)
    a=edges(i,1); %get first point's index
    b=edges(i,2); %get second point's index
    p=[points(:,a) points(:,b)]; %construct a 3X2 matrix out of the 2 points
    plot3(p(1,:),p(2,:),p(3,:)); %plot a line
end

但这不仅在实际循环期间很慢,而且在最后,当我尝试使用拖动和旋转工具旋转它时,结果图非常慢且无响应。

我知道使用 opengl 等相同的情节会运行得更快...

【问题讨论】:

    标签: matlab plot line


    【解决方案1】:

    您可以使用LINE 低级函数,使用NaN 将其绘制为单独的段:

    %# sample graph vertices and edges (similar to your data)
    [adj,XYZ] = bucky;
    [r c] = find(adj);
    edges = [r c];      %# M-by-2 matrix holding the vertex indices
    points = XYZ';      %# 3-by-N matrix of points X/Y/Z coordinates
    
    %# build a list of separated lines
    e = edges';
    e(end+1,:) = 1;
    e = e(:);
    p = points(:,e);
    p(:,3:3:end) = NaN;
    
    figure
    h = line(p(1,:), p(2,:), p(3,:));
    view(3)
    

    这非常有效,因为它创建了一个单行对象。现在你可以自定义线条了,但是整个东西只能使用一种颜色:

    set(h, 'Color',[.4 .4 1], 'Marker','.', 'MarkerSize',10, ...
        'MarkerFaceColor','g', 'MarkerEdgeColor','g')
    


    根据 cmets,如果您希望图表中的每条边都具有指定的颜色,请考虑以下代码。它涉及使用SURFACE 函数:

    p = p';                      %'# transpose the above p for convenience
    clr = (1:size(p,1))';        %'# for each edge, color index in current colormap
    figure
    surface(p(:,[1 1]), p(:,[2 2]), p(:,[3 3]), [clr clr], ...
        'EdgeColor','flat', 'FaceColor','none')
    colormap( hsv(numel(clr)) )  %# specify your colormap here
    view(3)
    

    【讨论】:

    • surface 解决方案最接近所要求的,但如果您检查mathworks.com/help/techdoc/ref/surface_props.html,似乎edgecolor 只是通过顶点颜色数据间接设置(这意味着所有边每个面共享编号最低的顶点的颜色),而不是直接为每条边指定颜色 - 这是想要的。根据快速检查,这似乎与patch 解决方案具有相同的行为。也许我错过了什么??
    【解决方案2】:

    我认为你可以做这样的事情(注意 - 大脑编译的代码......)

    figure;
    patch('faces', edges, 'vertices', points, 'edgecolor', 'b');
    axis equal;
    

    其中edges 应该是Nx2 索引矩阵,points 应该是Mx3 坐标矩阵(points 数组的转置)。

    根据我的经验,直接调用patch 比重复调用plot 快得多。

    给出一些想法,使用我的(诚然旧的!)MATLAB 7.1 生成 1000 个随机生成的线段的时间如下:

    1. 呼叫patch:0.03 秒。
    2. 呼叫plot:0.5 秒。

    编辑:让边缘颜色按您的意愿表现的一种方法(为每条边缘指定一种颜色)是引入重复的顶点,如下所示:

    这解决了边缘颜色只能通过顶点颜色数据间接指定的问题。如果我们仅依赖于顶点颜色,那么共享一个公共顶点的所有边可能最终都使用分配给该顶点的颜色 - 查看 'flat 'edgecolour 描述 here

    %% a "star" shape, so that we can really see what's going on 
    %% with the edge colours!!
    pp = [0,0,0; 1,-1,0; 1,1,0; -1,1,0; -1,-1,0];
    ee = [1,2; 1,3; 1,4; 1,5];
    
    %% important - only 1 colour known per edge, not per vertex!!
    cc = (1:size(ee,1))'; 
    
    %% setup a new set of vertices/edges/colours with duplicate vertices
    %% so that each edge gets it's correct colour
    nnum = 0;
    pnew = zeros(2 * size(ee, 1), 3); %% new vertices
    enew = zeros(1 * size(ee, 1), 2); %% new edge indices
    cnew = zeros(2 * size(ee, 1), 1); %% new edge colours - via vertices
    for j = 1 : size(ee, 1)
        n1 = ee(j, 1); %% old edge indices
        n2 = ee(j, 2);
        enew(j, 1) = nnum + 1; %% new edge indicies into pnew
        enew(j, 2) = nnum + 2;
        pnew(nnum + 1, :) = pp(n1, :); %% create duplicate vertices
        pnew(nnum + 2, :) = pp(n2, :);
        cnew(nnum + 1) = cc(j); %% map single edge colour onto both vertices
        cnew(nnum + 2) = cc(j);
        nnum = nnum + 2;
    end
    
    %% Draw the set efficiently via patch
    tic
    figure;
    hold on;
    patch('faces', enew, 'vertices', pnew, 'facevertexcdata', cnew, ...
        'edgecolor', 'flat', 'facecolor', 'none');
    plot(pnew(:,1), pnew(:,2), 'b.');
    axis equal;
    toc
    

    如果 MATLAB 允许您直接指定边缘颜色数据会更好 - 但它似乎不支持...

    希望这会有所帮助。

    【讨论】:

    • 谢谢!有没有机会你也可以告诉我如何发送一组颜色,以便每个边缘都用不同的颜色着色?
    • @noam:根据您的需要,有几种不同的着色选项。您可以使用 'facevertexcdata' 参数从顶点设置插值颜色 - 键入 edit trimesh 以了解这些思路。如果您只想要一些平面颜色 ('b', 'k', 'r', etc),我想您可以将边缘分成几个不同的组并为每个组选择一种颜色 - 我在这里假设您的边缘比颜色多得多。可能还有其他选项 - 检查文档...
    • 我实际上需要用多种颜色为每个边缘着色(假设我正在显示施加在某个结构的所有支撑梁上的应力)。所以我需要按边缘而不是顶点来指定颜色,而且我不能将边缘分成几个不同的组,因为有很多颜色......
    • @noam:您似乎可以获得单独的边缘颜色,但只能间接地从顶点颜色索引中获得 - 在这里查看edgecolor 部分mathworks.com/help/techdoc/ref/patch_props.html。不幸的是,我不确定它能否满足您的需求......
    • @noam:检查我添加的两种解决方案:一种使用单色的 LINE,另一种使用 SURFACE 的多色线条..
    猜你喜欢
    • 2018-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-20
    • 2022-11-10
    • 1970-01-01
    • 2014-10-19
    相关资源
    最近更新 更多