在matlab中绘制一堆3d线的最有效方法

时间:2011-08-21 11:37:55

标签: matlab plot line

我需要在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等的相同情节会跑得更快......

2 个答案:

答案 0 :(得分:6)

您可以使用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')

line


根据评论,如果您希望图表中的每条边都是指定的颜色,请考虑使用以下代码。它涉及使用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

答案 1 :(得分:1)

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

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秒。
  3. 编辑:获得边缘颜色表现的一种方法(每条边指定一种颜色)是引入重复顶点,如下所示:

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

    %% 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允许您直接指定边缘颜色数据会更好 - 但它似乎不支持...

    希望这有帮助。