我需要在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等的相同情节会跑得更快......
答案 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')
根据评论,如果您希望图表中的每条边都是指定的颜色,请考虑使用以下代码。它涉及使用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)
答案 1 :(得分:1)
我认为你可以做这样的事情(谨慎 - 大脑编译代码......)
figure;
patch('faces', edges, 'vertices', points, 'edgecolor', 'b');
axis equal;
edges
应该是Nx2
索引矩阵,points
应该是Mx3
坐标矩阵(points
数组的转置)。
根据我的经验,直接拨打patch
可能比重复拨打plot
要快得多。
为了给出一些想法,使用我的(老实说!)MATLAB 7.1生成1000个随机生成的线段的时间如下:
patch
:0.03秒。plot
:0.5秒。编辑:获得边缘颜色表现的一种方法(每条边指定一种颜色)是引入重复顶点,如下所示:
这解决了边缘颜色只能通过顶点颜色数据间接指定的问题。如果我们只依赖于顶点颜色,则共享一个公共顶点的所有边可能最终都会分配给该顶点的颜色 - 请查看'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允许您直接指定边缘颜色数据会更好 - 但它似乎不支持...
希望这有帮助。