The most efficient way to draw a bunch of 3d lines in matlab

I need to build a list of 3D lines in matlab. What is the fastest way to do this? I'm currently doing something like

%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 index b=edges(i,2); %get second point 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 

But this is not only slow during the actual cycle, but also at the end, the resulting graph is very slow and irresponsible when I try, for example, to rotate it with the drag and rotate tool.

I know the same plot using opengl etc. will work much faster ...

+6
source share
2 answers

I think you can do something like this (carefully - compiled brain code ...)

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

Where edges should be the Nx2 index Nx2 , and points should be the Mx3 coordinate Mx3 (transpose of your points array).

In my experience, calling patch directly can be significantly faster than calling repeatedly on plot .

To give some idea, the generation time of 1000 randomly formed line segments using my (true, old!) MATLAB 7.1 is as follows:

  • Call patch : 0.03 seconds.
  • Call plot : 0.5 seconds.

EDIT . One way to ensure that the color of the edges behaves the way you want (by pointing one color to the edge) is to introduce duplicate vertices as follows:

This concerns the problem that the edge color can be specified indirectly only through vertex color data. If we only relied on vertex colors, all the edges sharing a common vertex could get the color assigned to that vertex — check the “flat” edgecolour description.

 %% a "star" shape, so that we can really see what 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 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 

It would be better if MATLAB allowed you to specify the edge color data directly - but it doesn't seem to support ...

Hope this helps.

+1
source

You can use the low-level LINE function, using NaN to build as separate segments:

 %# sample graph vertices and edges (similar to your data) [adj,XYZ] = bucky; [rc] = find(adj); edges = [rc]; %# 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) 

This is very effective because it creates a separate object. Now you can customize the line, but it is limited to one color for everything:

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

line


According to the comments, if you want each edge on your chart to have a specific color, consider the following code instead. It includes the SURFACE function:

 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

+6
source

Source: https://habr.com/ru/post/895526/


All Articles