2011-08-21 7 views
6

Tôi cần vẽ một danh sách các dòng 3d trong MATLAB. Cách nhanh nhất để làm điều đó là gì? Tôi hiện đang làm một cái gì đó giống nhưCách hiệu quả nhất để vẽ một loạt các dòng 3d trong 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 

Nhưng điều này không chỉ chậm trong vòng lặp thực tế, mà còn ở cuối, cốt truyện kết quả là rất chậm và irresponsive khi tôi cố gắng, ví dụ, xoay nó sử dụng công cụ xoay & xoay.

Tôi biết những âm mưu tương tự sử dụng vv OpenGL sẽ chạy nhanh hơn nhiều ...

Trả lời

1

Tôi nghĩ rằng bạn có thể làm một cái gì đó như thế này (cẩn thận - não biên dịch mã ...)

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

đâu edges phải là ma trận Nx2 của các chỉ mục và points phải là ma trận tọa độ Mx3 (chuyển vị trí của mảng points).

Từ kinh nghiệm của tôi, gọi trực tiếp patch có thể nhanh hơn đáng kể so với các cuộc gọi lặp lại đến plot.

Để đưa ra một số ý tưởng, thời gian để tạo ra 1.000 đoạn thẳng được tạo ra một cách ngẫu nhiên, sử dụng của tôi MATLAB 7.1 như sau (phải thừa nhận là cũ!):

  1. Calling patch: 0.03 giây.
  2. Gọi plot: 0,5 giây.

EDIT: Một cách để có được những hành xử cạnh màu như bạn muốn (chỉ định một màu duy nhất cho mỗi cạnh) là giới thiệu đỉnh trùng lặp như sau:

này hoạt động xung quanh vấn đề này mà cạnh màu sắc chỉ có thể được xác định gián tiếp thông qua dữ liệu màu đỉnh. Nếu chúng ta chỉ dựa vào các màu đỉnh thì tất cả các cạnh chia sẻ một đỉnh chung có thể kết thúc với màu được gán cho đỉnh đó - hãy xem 'phẳng' edgecolour mô tả 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 

Nó sẽ đẹp hơn nếu MATLAB cho phép bạn trực tiếp xác định dữ liệu cạnh màu - nhưng nó dường như không ủng hộ điều đó ...

Hope this helps.

+0

Cảm ơn! Có cơ hội nào bạn cũng có thể chỉ cho tôi cách tôi có thể gửi một mảng các màu để mỗi cạnh có màu sắc khác nhau không? – olamundo

+0

@noam: Có một vài tùy chọn tô màu khác nhau, tùy thuộc vào những gì bạn muốn. Bạn có thể sử dụng tham số ''facevertexcdata'' để thiết lập các màu được nội suy từ các đỉnh - gõ' edit trimesh' để có được một ý tưởng dọc theo các dòng này. Nếu bạn chỉ muốn một vài màu phẳng (''b', 'k', 'r', vv') tôi đoán bạn có thể phá vỡ các cạnh thành một vài nhóm khác nhau và chọn một màu duy nhất cho mỗi nhóm - tôi giả sử ở đây bạn có nhiều cạnh hơn màu sắc. Có thể có các tùy chọn khác - kiểm tra tài liệu ... –

+0

Tôi thực sự cần phải tô màu từng cạnh với màu khác nhau, nhiều màu (Nói rằng tôi đang hiển thị ứng suất gây ra trên tất cả các dầm hỗ trợ của một số cấu trúc). Vì vậy, tôi cần phải xác định màu sắc của cạnh, không phải bởi đỉnh, và tôi không thể phá vỡ các cạnh thành nhiều nhóm khác nhau vì có rất nhiều màu sắc ... – olamundo

6

Bạn có thể sử dụng chức năng LINE ở mức độ thấp, sử dụng NaN để vẽ như phân đoạn riêng biệt:

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

này rất hiệu quả vì nó tạo ra một đối tượng dòng đơn.Bây giờ bạn có thể tùy chỉnh dòng, nhưng nó bị hạn chế để có một màu cho toàn bộ điều:

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

line


Theo ý kiến, nếu bạn muốn có mỗi cạnh trong đồ thị của bạn trong một màu được chỉ định, thay vào đó hãy xem xét mã sau. Nó liên quan đến việc sử dụng các chức năng 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

Giải pháp 'bề mặt 'là gần nhất với những gì được hỏi, nhưng nếu bạn kiểm tra http://www.mathworks.com/help/techdoc/ref/surface_props.html, có vẻ như rằng' edgecolor' chỉ được đặt gián tiếp qua dữ liệu màu đỉnh (Nó ngụ ý tất cả các cạnh trên mỗi mặt chia sẻ màu của đỉnh được đánh số thấp nhất), thay vì chỉ định màu cho từng cạnh trực tiếp - đó là những gì được mong muốn. Dựa trên một kiểm tra nhanh, điều này dường như cung cấp cho hành vi tương tự như giải pháp 'patch'. Có lẽ tôi đã bỏ lỡ một cái gì đó ?? –