2011-08-21 16 views
6

Necesito trazar una lista de líneas 3d en matlab. ¿Cuál es la forma más rápida de hacer eso? actualmente estoy haciendo algo así comoLa manera más eficiente de dibujar un grupo de líneas 3d en matlab

%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 

Pero esto no sólo es lento durante el bucle actual, sino también al final, la trama resultante es muy lento y que no reacciona cuando intento, por ejemplo, rotarlo usando la herramienta de rotación arrastrar &.

sé la misma parcela usando OpenGL, etc iría mucho más rápido ...

Respuesta

1

Creo que se puede hacer algo como esto (precaución - código compilado cerebro ...)

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

Dónde edges debe ser una matriz de índices Nx2 y points debe ser una matriz de coordenadas Mx3 (la transposición de su matriz points).

Desde mi experiencia, llamar directamente al patch puede ser significativamente más rápido que las llamadas repetidas al plot.

Para dar una idea, los tiempos para generar 1.000 segmentos de línea generados al azar, usando mi MATLAB 7.1 son los siguientes (la verdad de edad!):

  1. Calling patch: 0,03 segundos.
  2. Llamando plot: 0.5 segundos.

EDITAR: Una forma de obtener el comportarse color del borde que desee (la especificación de un solo color por filo) es introducir vértices duplicados de la siguiente manera:

Esto funciona-en torno a la cuestión de que el borde el color solo puede especificarse indirectamente a través de datos de color de vértices. Si tuviéramos que confiar únicamente en los colores de los vértices, entonces todos los bordes que comparten un vértice común podrían terminar con el color asignado a ese vértice: consulte 'plano' edgecolour descripción 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 

Sería mejor si MATLAB permite especificar directamente los datos de color de borde - pero no parecen apoyar que ...

Espero que esto ayude.

+0

Gracias! ¿Existe la posibilidad de que también me muestres cómo puedo enviar una matriz de colores para que cada borde tenga un color diferente? – olamundo

+0

@noam: hay algunas opciones de color diferentes, dependiendo de lo que desee. Puede usar el parámetro ''facevertexcdata'' para establecer colores interpolados a partir de los vértices, escriba' edit trimesh' para obtener una idea en esta línea. Si solo quieres unos pocos colores planos (''b ',' k ','r', etc.') supongo que podrías dividir los bordes en unos pocos grupos diferentes y elegir un solo color para cada grupo, supongo Aquí tienes muchos más bordes que colores. Puede haber otras opciones - verifique la documentación ... –

+0

De hecho necesito colorear cada borde con un color diferente, de muchos colores (digamos que estoy mostrando la tensión ejercida sobre todos los haces de soporte de alguna estructura). Por lo tanto, debo especificar el color por el borde, no por el vértice, y no puedo dividir los bordes en varios grupos diferentes, ya que hay muchos colores ... – olamundo

6

Usted puede utilizar la función LINE de bajo nivel, usando NaN para trazar como segmentos separados:

%# 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) 

Esto es muy eficiente, ya que crea un objeto de línea única.Ahora puedes personalizar la línea, sino que se limita a tener un color para toda la cosa:

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

line


De acuerdo con los comentarios, si usted quiere tener cada borde en el gráfico en un color específico, considere el siguiente código en su lugar. Se trata de utilizar la función 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

+0

La solución de 'superficie' es la más cercana a lo que se pide, pero si revisa http://www.mathworks.com/help/techdoc/ref/surface_props.html, de nuevo parece que el 'edgecolor' solo se establece indirectamente a través de los datos de color del vértice (implica que todos los bordes por cara comparten el color del vértice con el número más bajo), en lugar de especificar un color para cada borde directamente, que es lo que se desea. Con base en una comprobación rápida, esto parece dar el mismo comportamiento que la solución 'parche '. Tal vez me perdí algo ?? –

Cuestiones relacionadas