Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visualize a three-dimensional array like cubic lattice using MATLAB

I want to visualize a three-dimensional array just like cubic lattice using MATLAB.

I have read How to plot 3D grid (cube) in Matlab, and Simple cubic lattice using three-dimensional array

If element in the array is only 0 and 1, I know how to use a three-dimensional array to draw a simple cubic lattice, the small cube has the same size.

However, Now I have a three-dimensional array like this,

cube(:,:,1) =
 1     0     1
 0     1     1
 2    1     0
cube(:,:,2) =

 0     0     1
 1     5     1
 0     1     0

cube(:,:,3) =

 1     1     1
 0     1     1
 2    0     1

The array cube have value except 0 and 1. I want to visualize the array like cubic lattice, in which cube(:,:,1) denotes the first floor of the cubic lattice,

 cube(:,:,2) denotes the second floor, and 
 cube(:,:,3) the third floor.

The value 0 denotes nothing, while value 1 denotes a small blue cube.

Value greater than 1 denotes sphere, the diameter of sphere varies according to the value. The desired result is something like this: Visualization of a three-dimensional array, 1 denotes a small green cube,0 denotes nothing,Value greater than 1 denotes white sphere, the diameter of sphere varies according to the value.

Visualization of a three-dimensional array, 1 denotes a small green cube,0 denotes nothing,Value greater than 1 denotes white sphere, the diameter of sphere varies according to the value.

To explain my question more clear, show one visualization of two-dimensional array

enter image description here

1 denotes a small black sphere,0 denotes nothing,Value greater than 1 denotes white sphere, the diameter of sphere varies according to the value.

The desired  effect drawing The desired effect drawing

enter image description here it is Ok, when side length of cube is 1

enter image description here when set side length as 2, drawCube([ix,iy,iz],2,Royal_Blue). The problem occurs, cubes is overlapping,

like image 847
Kongling Avatar asked Mar 24 '15 10:03

Kongling


1 Answers

Let me show you my attempt. It is based into drawing each cube and circle independently. This will be slow in if A is big.

Result:

enter image description here

The code should be self explanatory.

% Create some data. This piece of code just creates some matrix A with
% some 1s and 0s and inserts a 2 and a 3 to specific positions. Subsitute
% this with your own data matrix.
th=0.2;
A=double(rand(10,10,10)<th);
A(1,1,1)=2;
A(5,5,5)=3;

% A nice color. I just dont like the standard blue so I picked another one.
Royal_Blue=[65 105 225]/255; 

%%%%%%%%%%%%%%%%%%%%%%
%% Draw cubes

% Obtain all the linear indexes (search mathworks for help between  
% subscripts vs linear indices) of the locations where a cube is wanted 
% (A==1)

ind=find(A==1);

% Create a figure
fig=figure();
hold on

% Draw the cubes one by one

for ii=1:length(ind)

    % For each linear index get its subscript (that also 
    % will be x,y,z position)
    [ix,iy,iz]=ind2sub(size(A),ind(ii));

    % Use the drawcube function to draw a single cube in the
    % desired position with the desired size (1) and colour.
    drawCube([ix,iy,iz],1,Royal_Blue);
end

% Nice plotting code. This just makes the drawing nicer. 

camlight left
lighting gouraud
axis equal
axis off
view(-50,25)

%%%%%%%%%%%%%%%
%% Now draw the spheres

% This code is the same as the previous one but I just draw
% spheres instead of cubes.
ind=find(A>1);
% create an sphere
[X,Y,Z] = sphere;
for ii=1:length(ind)
    [ix,iy,iz]=ind2sub(size(A),ind(ii));
    % scale sphere
    Xs=X*A(ix,iy,iz)/2;
    Ys=Y*A(ix,iy,iz)/2;
    Zs=Z*A(ix,iy,iz)/2;
    surf(Xs+ix,Ys+iy,Zs+iz,'edgecolor','none','facecolor',[1 1 1]);

end

% Change the background colour to black
whitebg(fig,'k')
% MAke sure it stays black
set(gcf, 'InvertHardCopy', 'off');

Function drawCube is as follows:

function drawCube( origin, size,color)
% From
% http://www.mathworks.com/matlabcentral/newsreader/view_thread/235581

if nargin<3
    color='b';

end
x=([0 1 1 0 0 0;1 1 0 0 1 1;1 1 0 0 1 1;0 1 1 0 0 0]-0.5)*size+origin(1);
y=([0 0 1 1 0 0;0 1 1 0 0 0;0 1 1 0 1 1;0 0 1 1 1 1]-0.5)*size+origin(2);
z=([0 0 0 0 0 1;0 0 0 0 0 1;1 1 1 1 0 1;1 1 1 1 0 1]-0.5)*size+origin(3);
for i=1:6
    h=patch(x(:,i),y(:,i),z(:,i),color);

    set(h,'edgecolor','none')

end

end
like image 173
Ander Biguri Avatar answered Oct 26 '22 01:10

Ander Biguri