Building a hollow cube and filing it with small cu

2019-06-12 10:49发布

问题:

I want to build a hollow cube with some dimensions x, y, and z, and fill its volume with many small cubes. The following image is similar to what I want to do,

But, instead of small spheres, I want to use small cubes.

After building the cube and filling it with other small cubes, I want to build a matrix that represents these small cubes inside the big one, this is because I want to be able to access every small cube, where I need to change its color.

Is it possible to have this matrix representing the structure of the small cubes? Let's say every small cube is represented by -1, I mean that all -1s in a row of the matrix are small cubes at the same row, and all -1s in a column are actually small cubes in the same column (neighbors inside the big cube must be neighbors inside the matrix). Since the big cube is a 3D shape, I expect such a matrix to be a 3D matrix with row, column, and depth measures. Depth may represent the layers of different small cubes we have, i.e at depth 1 we have a set of rows and columns representing the small cubes at the first depth. After that I want to iterate over this matrix and change the -1 to some other number that represents some color. How to change the color of some small cube using the corresponding number in the matrix? For example, let the number at index (1,1,1) be 0 and let it represent yellow, how can I change the corresponding cube color to yellow? I'm think about patch function, but how to apply it to the corresponding cube?

How can I fill the cube with small cubes? And, how can I build the matrix described above?

Here is a code for placing a small cube inside the big one, but this places it in the center, I tried to fill the big cube with small cubes in an organized way as in the provided picture, but I couldn't figure out how to do that.

clf;
figure(1);
format compact 
h(1) = axes('Position',[0.2 0.2 0.6 0.6]);

%These are the different 8 vertices of the cube, each is defined by its 3 x
%y z coordinates:
vert = [1 1 -1; 
        -1 1 -1; 
        -1 1 1; 
        1 1 1; 
        -1 -1 1;
        1 -1 1; 
        1 -1 -1;
        -1 -1 -1];
%These are the 6 faces of the cube, each is defined by connecting 4 of the
%available vertices:
fac = [1 2 3 4; 
       4 3 5 6; 
       6 7 8 5; 
       1 2 8 7; 
       6 7 1 4; 
       2 3 5 8];

% I defined a new cube whose length is 1 and centers at the origin.
vert2 = vert * .05;  
fac2 = fac;


patch('Faces',fac,'Vertices',vert,'Facecolor', 'w');  % patch function for the first big cube. 
axis([-1, 1, -1, 1, -1, 1]);
axis equal;

hold on;

patch('Faces', fac2, 'Vertices', vert2, 'FaceColor', 'r');
material metal;
alpha('color');
alphamap('rampdown');
view(3);

Can anyone please tell me how to fill the cube and construct the matrix?

Thank You.

回答1:

Some slight modifications to your code can easily be done to populate the cube with smaller cubes. You already have the code to place one cube in the centre. All you really have to do is randomize the centre of the base small cube, adjust the centre of the cube with this centre and place it in the larger cube. You can also randomize the colour of the cube as well. We can loop for as many times as you want cubes and you can generate random centre positions for each cube as well as random colours and place them onto the final cube.

Do this at the end of your code:

hold on;
rng(123); %// Set seed for reproducibility
num_squares = 1000; %// Set total number of squares

%// For each square...
for idx = 1 : num_squares

    %// Take the base cube and add an offset to each coordinate
    %// Each coordinate will range from [-1,1]
    vert_new = bsxfun(@plus, vert2, 2*rand(1,3)-1);

    %// Generate a random colour for each cube
    color = rand(1,3);

    %// Draw the cube
    patch('Faces', fac, 'Vertices', vert_new, 'FaceColor', color);
end

%// Post processing
material metal;
alpha('color');
alphamap('rampdown');
view(3);

We get this image:

Now if you want to build a 3D matrix of these said coordinates, that's quite simple. Simply have a matrix and concatenate these randomly generated coordinates at each iteration:

hold on;
rng(123); %// Set seed for reproducibility
num_squares = 1000; %// Set total number of squares

%// New - to store the coordinates
coords = [];

%// For remembering the colours
colors = [];

%// For each square...
for idx = 1 : num_squares

    %// Take the base cube and add an offset to each coordinate
    %// Each coordinate will range from [-1,1]
    vert_new = bsxfun(@plus, vert2, 2*rand(1,3)-1);

    %// New - For the coordinates matrix
    coords = cat(3, coords, vert_new);

    %// Generate a random colour for each cube
    color = rand(1,3);

    %// New - Save the colour
    colors = cat(1, colors, color);

    %// Draw the cube
    patch('Faces', fac, 'Vertices', vert_new, 'FaceColor', color);
end

%// Post processing
material metal;
alpha('color');
alphamap('rampdown');
view(3);

coords will now be a 3D matrix where each slice is a set of 3D coordinates that represents one cube. Similarly, colors will represent a 2D matrix where each row is the colour associated with the cube you drew.

If you want to reconstruct this by just using coords and colors, you can do this:

close all;
clf;
figure(1);
format compact 
h(1) = axes('Position',[0.2 0.2 0.6 0.6]);

patch('Faces',fac,'Vertices',vert,'Facecolor', 'w');  % patch function for the first big cube. 
axis([-1, 1, -1, 1, -1, 1]);
axis equal;

vert = [1 1 -1; 
        -1 1 -1; 
        -1 1 1; 
        1 1 1; 
        -1 -1 1;
        1 -1 1; 
        1 -1 -1;
        -1 -1 -1];

fac = [1 2 3 4; 
       4 3 5 6; 
       6 7 8 5; 
       1 2 8 7; 
       6 7 1 4; 
       2 3 5 8];

vert2 = vert * .05;  

%// For each square...
for idx = 1 : num_squares

    %// Take the base cube and add an offset to each coordinate
    %// Each coordinate will range from [-1,1]
    vert_new = coords(:,:,idx);

    %// Generate a random colour for each cube
    color = colors(idx,:);

    %// Draw the cube
    patch('Faces', fac, 'Vertices', vert_new, 'FaceColor', color);
end

%// Post processing
material metal;
alpha('color');
alphamap('rampdown');
view(3);

This should reproduce the same figure by using the matrices you wanted to save.