5

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,

Community
  • 1
  • 1
Kongling
  • 65
  • 6
  • It is quite unclear. What you want is to emulate those images in Matlab? Which one do you prefer, the former or the later? – Ander Biguri Mar 24 '15 at 10:33
  • The former, I want to visualize the three-dimensional array, each element in the array represent a body with the size according to its value – Kongling Mar 24 '15 at 10:41
  • What are the red squares in the image? shoudl those be there? – Ander Biguri Mar 24 '15 at 10:52
  • Thank you for your attention, you can ingore the red squares. – Kongling Mar 24 '15 at 13:54
  • Thank you for your answer, your idea is pretty good! besides, I don't quite follow the meaning " your circles of diameter of the number, not radius." . I am sorry for my unclear discription, the value 1 represents the side length of the cube, other value(such as 2) represents diameter of the sphere. – Kongling Mar 25 '15 at 12:45
  • Apologies, I did wrongly read your question. Indeed, other values, such as 2 represent diameters in my answer. I read radious in your question and it has less sense , but it was my mistake, you actually explained very good. If you like my answer please accept it, else tell me what can I improve! – Ander Biguri Mar 25 '15 at 12:53
  • 1
    Ok, I am trying to figure out the codes you write. – Kongling Mar 25 '15 at 12:57
  • Let me expand the answer with more explanations about the specific code. – Ander Biguri Mar 25 '15 at 14:00
  • You are very kind. By the way, I basically figure out the codes you wrote. and I think “camlight left” don't satisfy my need, my desired effect drawing is showed as shown in the front (in the end of the question). thank you for your good job! – Kongling Mar 25 '15 at 14:41
  • camligth left just puts ligth in the image, does not set up the view. You may be referring to `view`. Change the values accordingly to your needs. However that part of the code just makes the figure looks nicer, it shoud run without that. – Ander Biguri Mar 25 '15 at 14:46
  • I delete the code "camlight left" , and "set(h,'edgecolor','none');" in the Function drawCube, so I can see every cube. now I encounter another question, if the side length of cube is 1, everything is Ok, but if I set the side length of cube is 2, i.e. drawCube([ix,iy,iz],2,Royal_Blue); cubes will be overlapping, could you solve my problem? – Kongling Mar 26 '15 at 06:32
  • But.... That makes sense. Why do you want to do that? If you do it, then the spheres wont be bigger than the cubes anymore! Anyways, if you really want to do that the trick is plotting the cubes in `2*[ix,iy,iz]` – Ander Biguri Mar 26 '15 at 08:48
  • In my model, the cubes is bigger than the spheres intially. Now I have another solution, keep the side length of cube as 1, and I discrease the diameter of the spheres. The question is solved now, thank you for help ! – Kongling Mar 26 '15 at 09:54
  • Related: [How do I resolve this issue with 3D image visualization?](https://stackoverflow.com/q/43948680/52738) – gnovice Oct 10 '17 at 14:03

1 Answers1

10

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
Ander Biguri
  • 35,140
  • 11
  • 74
  • 120
  • That is crazy! I had no idea MATLAB could render stuff like that... it almost looks like OpenGL! – rayryeng Mar 26 '15 at 20:42
  • @rayryeng To be honest it looks that good because I render it in 2014b. In the previous version is cool, but not *that* cool. – Ander Biguri Mar 26 '15 at 20:54