2

MATLABで3D配列を含むデータを視覚化しようとしています。

配列の次元は20*20 * 40で、一部の要素を除いてすべてゼロです。

これらの非ゼロ点を散布図にプロットして、非ゼロ点が互いに接続されるようにする方法を探しています。

これが私がこれまでにしたことです:

b=zeros(6,6,3);
a=[1 1 1;2 2 1;2 1 1;1 2 1;
1 1 2;1 2 2;2 1 2;2 2 2;
6 6 3;6 5 3;5 6 3;5 5 3;
6 6 2;6 5 2;5 6 2;5 5 2];
[r c]=size(a);
for i = 1:r
 b(a(i,c-2),a(i,c-1),a(i,c)) = 1;
end
[m n o]=size(b);
figure (1)
[x,y,z] = meshgrid(1:m,1:n,1:o);
scatter3(x(:),y(:),z(:),90,b(:),'filled')

ですから、私が求めているのは、2つの形の8つのポイントのそれぞれを立方体の格​​子に接続できることです。どんな考えでも大歓迎です。 ここに画像の説明を入力してください

編集: 多くを助けてくれたすべての専門家に感謝します。今、私は記憶に関する別の問題に直面しています。

私の実際の場合のb行列は1000*1000 * 2000であり、サイズが4,4700,000*3の「a」行列があります。「a」行列のすべての要素は整数値です。私は最大48GBのメモリを利用できますが。ただし、上記の「forループ」では、プログラムは「メモリ不足」エラーを返します。

これをよりメモリ効率の良いものにするためのアイデアは大歓迎です。

4

3 に答える 3

3

次のことを考慮してください(以前の回答に基づく):

%# adjacency matrix
adj = false(numel(b));

%# extract first cube, and connect all its points
bb = b;
bb(:,1:3,:) = false;
idx = find(bb);
adj(idx,idx) = true;

%# extract second cube, and connect all its points
bb = b;
bb(:,4:6,:) = false;
idx = find(bb);
adj(idx,idx) = true;

%# points indices
[r c] = find(adj);
p = [r c]';

%# plot
plot3(x(p), y(p), z(p), 'LineWidth',2, 'Color',[.4 .4 1], ...
    'Marker','o', 'MarkerSize',6, ...
    'MarkerFaceColor','g', 'MarkerEdgeColor','g')
axis equal, axis vis3d, grid on, view(3)
xlabel x, ylabel y, zlabel z

ここに画像の説明を入力してください


編集:

ポイントを手動で接続する方が簡単です。

%# edges: connecting points indices
p = [
    1 2; 2 8; 8 7; 7 1;
    37 38; 38 44; 44 43; 43 37;
    1 37; 2 38; 7 43; 8 44;
    65 66; 66 72; 72 71; 71 65;
    101 102; 102 108; 108 107; 107 101;
    65 101; 66 102; 71 107; 72 108
]';

%# plot
figure
plot3(x(p), y(p), z(p), 'LineWidth',2, 'Color',[.4 .4 1], ...
    'Marker','o', 'MarkerSize',6, ...
    'MarkerFaceColor','g', 'MarkerEdgeColor','g')
axis equal, axis vis3d, grid on, view(3)
xlabel x, ylabel y, zlabel z

%# label points
labels = strtrim(cellstr( num2str((1:numel(b))','%d') ));
idx = find(b);
text(x(idx(:)), y(idx(:)), z(idx(:)), labels(idx(:)), ...
    'Color','m', ...
    'VerticalAlignment','bottom', 'HorizontalAlignment','left')

スクリーンショット


編集#2 :(クレジットは@tmpearceに送られます)

エッジリストを作成するプロセスを半自動化できます。p上記のコードで手動で作成したmatrxを次のように置き換えるだけです。

%# compute edges: pairs of vertex indices 
yIdx = {1:3 4:6};           %# hack to separate each cube points
p = cell(numel(yIdx),1);
for i=1:numel(yIdx)         %# for each cube
    %# find indices of vertices in this cube
    bb = b;
    bb(:,yIdx{i},:) = false;
    idx = find(bb);

    %# compute L1-distance between all pairs of vertices,
    %# and find pairs which are unit length apart
    [r,c] = find(triu(squareform(pdist([x(idx) y(idx) z(idx)],'cityblock'))==1));

    %# store the edges
    p{i} = [idx(r) idx(c)]';
end
p = cat(2,p{:});            %# merge all edges found

アイデアは、各キューブについて、すべての頂点間の街区距離を計算することです。「側面」のエッジの距離は。です1が、対角線の距離は。以上2です。

このプロセスでは、各キューブに属する頂点のリストが提供されているか、上記のコードで行ったように簡単に抽出できることを前提としています...

于 2012-06-17T00:51:02.107 に答える
2

Amroの回答のフォローアップに回答し、3次マトリックスに沿ったエッジの接続を自動化する方法を示したいと思いました。この回答はAmroの補足となることを目的としており、将来の視聴者が読みやすいように、このソリューションに組み込むことをお勧めします。

idxこれは、立方体の角の線形インデックスを含むAmroのソリューションから始まります。以下では、1つの立方体だけでそれを行ったので、行列はそれほど大きくはなく、ここでそれらを見ることができます。

>> idx' %# transposed to save space in the printed output
ans =
 1     2     7     8    37    38    43    44 '

%# now get the subindex of each point in 3D
>> [sx sy sz] = ind2sub([6 6 3],idx);
%# calculate the "edge distance" between each corner (not euclidean distance)
>> dist = abs(bsxfun(@minus,sx,sx')) +...
          abs(bsxfun(@minus,sy,sy')) +...
          abs(bsxfun(@minus,sz,sz'))
dist =

 0     1     1     2     1     2     2     3
 1     0     2     1     2     1     3     2
 1     2     0     1     2     3     1     2
 2     1     1     0     3     2     2     1
 1     2     2     3     0     1     1     2
 2     1     3     2     1     0     2     1
 2     3     1     2     1     2     0     1
 3     2     2     1     2     1     1     0 '

%# find row and column index of points one edge apart
>> [r c]=find(triu(dist==1)); %# triu means don't duplicate edges

%# create 'p' matrix like in Amro's answer
>> p = [idx(r) idx(c)]'
p =
 1     1     2     7     1     2    37     7    37     8    38    43
 2     7     8     8    37    38    38    43    43    44    44    44

視覚化するために、Amroの答えとまったく同じようにプロットできます。

于 2012-06-18T21:14:42.190 に答える
0

これはあなたが必要なものですか?

b=logical(b);                                  
scatter3(x(b(:)),y(b(:)),z(b(:)),90,'filled')

ここに画像の説明を入力してください

于 2012-06-16T11:26:59.763 に答える