归档立方体的整个体积与MATLAB小方块 [英] Filing the entire volume of a cube with small cubes in MATLAB

查看:877
本文介绍了归档立方体的整个体积与MATLAB小方块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立了一个中空立方体在MATLAB,我要完全填补其体积小方块。然后我想找到一种方法来访问这些多维数据集,并通过他们做出的路径,即如果当前访问的立方体X是应该有一种方法来知道什么是它的左,右,上,下​​,前,和后面最近的邻居(最近的邻居直接=立方体当前多维数据集旁)。我认为,我们有6个邻居,因为我们有6种不同的立方体的面孔。

I have built a hollow cube in MATLAB, I want to completely fill its volume with small cubes. Then I want to find a way to access these cubes and make paths through them, i.e if cube x is currently accessed, there should be a way to know what is its right, left, top, bottom, front, and back closest neighbors (closest neighbors= the cubes directly beside the current cube). I think we have 6 neighbors, because we have 6 different faces of the cube.

通过知道最近的立方体在每一个方向,通过立方体的路径可以被定义为一系列的步骤(例如,右,左,左,上,右,前)。我认为能够访问每个小立方体,并移动到邻近那些我们需要重新present以矩阵(也许3D),其中,如果一个小立方体具有一个邻居立方体x可其右边的小立方体,然后在矩阵,x将出现在列旁边的小立方体的当前列。此外,如果有在另一个深度层的直接邻居(相同的x,y坐标,但不同的z坐标,例如,正面和背面邻居)应指出。有没有更简单的方法来识别邻居?

By knowing the nearest cube at every direction, a path through the cubes can be defined as a series of steps (eg, right, left, left, top, right, front). I think to be able to access every small cube and move to near ones we need to represent the small cubes in a matrix (maybe 3D), where if a small cube has a neighbor cube x to its right, then in the matrix, x will appear in the column next to the current column of the small cube. Also, if there is a direct neighbor at another depth layer (same x, y coordinates but different z coordinate, eg, the front and back neighbors) it should be indicated. Is there an easier way to identify the neighbors?

我获得了code。通过 rayryeng (<一href="http://stackoverflow.com/questions/31896429/building-a-hollow-cube-and-filing-it-with-small-cubes-in-matlab">Building一个中空立方体,并在MATLAB 的小立方体其归档)随机填补许多小方块内的大个,并建立一个三维矩阵,其中矩阵(深度)重presents的每一片小的一个立方体,并且行和每片的列(8行3列)重新present每小立方体的顶点的XYZ坐标。请看看我提供看code中的提问环节。

I've obtained a code by rayryeng (Building a hollow cube and filing it with small cubes in MATLAB) to fill many small cubes randomly inside the big one and build a 3D matrix, where every slice of the matrix (depth) represents one of the small cubes and the rows and columns of every slice (8 rows and 3 columns) represent the x y z coordinates of the vertices of every small cube. Please take a look at the question link that I provided to see the code.

我想提出两个修改到code,

I want to make two modifications to the code,

1填补的大立方体的小立方体有组织的方式不是随机。

1- fill the big cube with small cubes in an organized way not randomly.

2 - 调整3D矩阵重新present的小方块怎么是邻居给对方。

2- adjust the 3D matrix to represent how the small cubes are neighbors to each other.

我试着调整code在链接的问题,填补了立方体在一个有组织的方式。这是对我的审判(我加的,如果其他人在for循环),

I've tried to adjust the code in the linked question to fill the cube in an organized way. This is my trial (I added the if else in the for loop),

   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', 'EdgeColor', 'none');
material metal;
alpha('color');
alphamap('rampdown');
%view(3);


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]
    if (idx==1)
    vert_new = bsxfun(@plus, vert2, [.01 .01 .01]);

    else 
    vert_new = bsxfun (@plus, vert_new,[.01 .01 .01] );
    end
    %// 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,'EdgeColor', 'none');
end




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

但我得到一个结果,像在下面的图片,

But I'm getting a result like the one in the following picture,

输入图像的描述在这里

谁能告诉我怎么解决这个问题,并建立3D矩阵(或任何其他更简单的方法来重新present每一个立方体的邻居)?

Can anyone please tell me how to solve this problem and build the 3D matrix (or any other easier way to represent the neighbors of every cube )?

编辑:更详细地说明小立方体邻居的问题。请考虑一个立方体Ç内的任何地方的大立方体。让立方体位置(0.5,3.5,0.5),我们可以将其看作是立方体的中心。那么,这个立方体将有6邻居立方体(直接定位旁边),每轴2的邻居。因此,多维数据集(0.5,3.5,0.5)我们有,

To elaborate more on the small cube neighbor issue. Consider having a cube C anywhere inside the big cube. Let the cube position be (.5,.5,.5) which we may think of as the center of the cube. Then, this cube will have 6 neighbor cubes (positioned directly beside it) with 2 neighbors per axis. So, for the cube (.5,.5,.5) we have,

x轴的邻居C的右侧(0.5 +偏移.5,.5)

x axis neighbor to the right of C (.5 +offset, .5, .5)

x轴的邻居C的左侧(0.5 -offset .5,.5)

x axis neighbor to the left of C (.5 -offset, .5, .5)

y轴的邻居C的顶部(0.5 .5 +偏移,.5)

y axis neighbor to the top of C (.5 , .5+offset, .5)

y轴的邻居C的底部(0.5,3.5偏移,.5)

y axis neighbor to the bottom of C (.5 , .5-offset, .5)

℃后Z轴的邻居一个深度(0.5,3.5,0.5 +偏移量)

z axis neighbor one depth after C (.5 , .5, .5+offset)

C(3.5,3.5,2.5偏移)之前,Z轴的邻居一个深度

z axis neighbor one depth before C (.5 , .5, .5-offset)

其中偏移可以被看作是一个立方体的中心和其任何面之间的距离。这仅仅是一个说明,以澄清的想法,它并不需要实施方式相同。我希望这是明确的,我会的AP preciate在建设这附近矩阵任何帮助。

where offset may be seen as the distance between the center of a cube and any of its faces. This is just an explanation to clarify the idea, it doesn't need to be implemented the same way. I hope this is clear, I would appreciate any help in constructing this neighborhood matrix.

感谢。

推荐答案

同样的原理,我们建立了一个很大的立方体,然后一个小角落里,随后,我们重复的小立方体建筑,一个小胶印机,直到我们都满了。与旧code的主要区别是,这一次的每个坐标设置阶跃变化控制(对函数X,Y,Z 协调小立方体)而不是被随机

Same principle, we build a big cube, then a small one in the corner, then we repeat the small cube building with a small offset until we are full. The main difference with the old code is that this time the step change of each coordinate set is controlled (function of x,y,z coordinates of the small cube) instead of being random.

%%
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];

%// How many small cube do we want
MainCubeSide = 2 ;              %// dimension of the side of the main cube
nCubeOnSide = 5 ;               %// number of small cube in one "row/column" of the main cube
nCubesTotal = nCubeOnSide^3  ;  %// total number of small cube

% define the Main container cube
MainCube.Vertices = vert *(2/MainCubeSide) ; %// because the cube as defined above has already a side=2
MainCube.Faces = fac ;
MainCube.FaceColor = 'w' ;

hMainCube = patch(MainCube);  %// patch function for the first big cube. 
axis([-1, 1, -1, 1, -1, 1]);
axis equal;
hold on;
material metal;
alpha('color');
alphamap('rampdown');
view(138,24)
%view(3);


%% // generate all the coordinates of each cube first
dstep = MainCubeSide / nCubeOnSide ;                                                 %// step size for small cube vertices
vElem = bsxfun(@plus, vert / nCubeOnSide , -( MainCubeSide/2 - dstep/2)*[1 1 1] )  ; %// elementary cube vertices

%%
hold on;
coords = zeros( size(vElem,1),size(vElem,2), nCubesTotal ) ;  %// To store the coordinates
colors = zeros( nCubesTotal , 3 ) ;                           %// To store the colours
hcube  = zeros( nCubesTotal , 1 ) ;                           %// To store the handles of the patch objects

iNeighbour = zeros( nCubesTotal , 6 ) ;   %// To save the index of the neighbours
idc = permute( reshape(1:nCubesTotal,nCubeOnSide,nCubeOnSide,nCubeOnSide) , [3 2 1] ) ;

%// For each cube ...
iCube = 0 ;
for iline=1:nCubeOnSide         %// Lines
    for icol=1:nCubeOnSide      %// Columns
        for ih=1:nCubeOnSide    %// Slice (height)
            iCube = iCube + 1 ;

            %// Take the base corner coordinates and add an offset to each coordinate
            coords(:,:,iCube) = bsxfun(@plus, vElem , dstep*[(iline-1) (icol-1) (ih-1)]);

            %// Save the colour
            colors(iCube,:) = rand(1,3) ; 

            %// Draw the cube
            hcube(iCube) = patch('Faces', fac, 'Vertices', coords(:,:,iCube), 'FaceColor', colors(iCube,:) ) ;

            drawnow     %// just for intermediate display, you can comment these 2 lines
            pause(0.05) %// just for intermediate display, you can comment these 2 lines

            %// save adjacent cubes indices
            ixAdj = [iline-1 iline+1 icol-1 icol+1 ih-1 ih+1] ;  %// indices of adjacent cubes
            idxFalse = (ixAdj<1) | (ixAdj>nCubeOnSide) ;  %// detect cube which would be "out" of the main cube
            ixAdj(idxFalse) = 1 ;                                %// just to not get an "indexing" error at this stage
            iNeighbour(iCube,:) = [idc(ixAdj(1),icol,ih)    idc(ixAdj(2),icol,ih) ...
                                   idc(iline,ixAdj(3),ih)   idc(iline,ixAdj(4),ih) ...
                                   idc(iline,icol,ixAdj(5)) idc(iline,icol,ixAdj(6)) ] ;
            iNeighbour(iCube,idxFalse) = NaN ;
        end
    end
end

这code保存每个立方体的手柄在变量 hcube 所以你可以做财产分配散装的所有多维数据集,如果你想要的。例如删除(hcube)将删除一气呵成所有的小方块,或设置(hcube,Facealpha',0.5)将所有多维数据集的一半是透明的。

This code saves the handle of each cube in the variable hcube so you can do assignment of property in bulk on all the cubes if you want. For example delete(hcube) will delete all the small cubes in one go, or set(hcube,'Facealpha',0.5) will make all cubes half transparent.

您还可以在其中的一个子集设置/更改属性 hcube(idx_subset)= ... 。这是知道相邻立方体他们的指数可能是有用的,但你的邻居的问题是还没有完全确定。

You can also set/change properties on only a subset of them hcube(idx_subset) = .... This is where knowing the adjacent cubes by their index could be useful, but your adjacency question is not completely defined yet.

编辑: 我已经加入了邻居跟踪主循环。它可能不是最有效的方法来做到这一点,但它确实让所有的邻居来回回每个基本立方体的索引。 该 iNeighbour 变量(尺寸: nCubesx6 )持有每个邻居(6个可能的邻居)的手柄指标。当邻居根本不存在,我选择把一个 NaN的代替。 要检索邻居的指数没有直接的 NaN的 S,我定义了一个帮手匿名函数:

I have added the neighbour tracking in the main loop. It is probably not the most efficient way to do it but it does keep an index of all the neighbour fro each elementary cube. The iNeighbour variable (size: nCubesx6) hold the handle index of each neighbour (6 possible neighbours). When a neighbour didn't exist, I opted to place a NaN instead. To retrieve the index of the neighbour directly without the NaNs, I defined a helper anonymous function:

getNeighbourIndex = @(idx) iNeighbour(idx,~isnan(iNeighbour(idx,:))) ;

现在帮助你跟踪一个给定的立方体的所有邻居。例如:

Which now help you track all the neighbour of a given cube. For example:

set(hcube,'Visible','off')  %// turn off all small cubes
CubeOfInterest = 111 ;      %// select one cube
%// display the main cube of interest, and it's neighbours in transparency
set(hcube(CubeOfInterest),'Visible','on','FaceColor','r','FaceAlpha',1) 
set(hcube(getNeighbourIndex(CubeOfInterest)),'Visible','on','FaceColor','g','FaceAlpha',.05)

正如你所看到的,所有的邻居都在那里,我们是否靠近墙壁或没有。

As you can see, all the neighbours are there, whether we are close to a wall or not.

这篇关于归档立方体的整个体积与MATLAB小方块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆