我建设,填补了许多小方块中空立方体的程序。 然后,使通过随机立方体连接的路径。 路径是通过查看每个立方体的直接邻居发现一步一步的选择它们中的任何一个作为下一个步骤。 为了说明,下面的图片显示的是由立方体的路径(红色立方体),
要构建路径,我开始形成一些立方体,用红颜色的它,发现它的邻居立方体(6个邻居,因为我们有6个面),选择其中的任何随机,有色选定一个带有红色,然后重复同样的发现它的邻居处理。 这是一个好方法,但如果邻居立方体已经是红色的(已经属于路径)也不会承认,它可以重新选择。 为了解决这个问题,我做了如下,
1-我由称为访问阵列,并且我中储存的所有访问的立方体的索引。
2-我所存储的当前的立方体的邻居另一个数组称为比较它与访问之一,我删除的任何共同的元件,然后把残留在一个元件的随机数。
3-有时候,所有的邻居都可以访问, 因此将成为空。 在这种情况下,我找了所有当前多维数据集的中,选择其中的任何随机,检查它的邻居,将它们存储邻居阵列( 一 )相比,随着访问的立方体阵列。 这将不断重复(while循环),如果邻居数组不为空。 但在我的情况下,程序陷在while循环。 此外,有时它不会被卡住,但立方体的路径数小于指定的一个。
我已经获得的构建主要的立方体,用小方块填满它的代码,并获得由伯耆邻居前一个问题( 备案与MATLAB小立方体立方体的整个体积 ),我刚添加的构建路径机制使用邻居。 下面是代码,
%%
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
disp (2/ MainCubeSide);
MainCube.Faces = fac ;
MainCube.FaceColor = 'w' ;
hMainCube = patch(MainCube); %// patch function for the first big cube. MainCube can be seen as an object that contains all the infor that the patch function needs.
axis([-1, 1, -1, 1, -1, 1]);
axis equal;
hold on; %wait we didn't finish yet.
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, this will determine the edge length for the small cube that best fits the required small cubes per edge.
vElem = bsxfun(@plus, vert / nCubeOnSide , -( MainCubeSide/2 - dstep/2)*[1 1 1] ) ; %// elementary cube vertices. Because the small cube was defined in the center of the big cube, to push it to one side we only need to move it by half the size of the main cube (minus half the size of a small cube)
%%
hold on;
coords = zeros( size(vElem,1),size(vElem,2), nCubesTotal ) ; %// To store the coordinates (8 rows * 3 columns) in every of the nCubesTotal slices.
colors = zeros( nCubesTotal , 3 ) ; %// To store the RBG colours for every small cube.
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)* all for loops have the smame length, because the total number of cubes = mCubeOnSide^3
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)]); %the fist one will not have offset, iline-1=0.
%// Save the colour
colors(iCube,:) = rand(1,3) ;
%// Draw the cube and store its info in the cube handler hcube.
hcube(iCube) = patch('Faces', fac, 'Vertices', coords(:,:,iCube), 'FaceColor', colors(iCube,:) ) ; %Remember each slice of coords contains the vertices of one of the small cubes, that's why it corresponds to vertices here.
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
getNeighbourIndex = @(idx) iNeighbour(idx,~isnan(iNeighbour(idx,:))) ;
set(hcube,'Visible','off') %// turn off all small cubes
cubeOfInterest = 32 ; %// 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)
visited= []; %to hold the indices of the visited cubes.
for i=1:124
visited (i) = cubeOfInterest; %the first visited cube is the cube of interest.
a= (getNeighbourIndex(cubeOfInterest)); %get all the neighbors\ indices and store them in an array so we can select randomly from them.
disp (a);
looping=true;
while looping==true %To avoid visiting any previously visited cube.
disp ('program is looping') %just to know if the program is stuck in an infinite loop.
inds = find(ismember(a, visited)); %store the indices of the common elements if found.
a(inds)= []; %delete the indices of the common elements.
if (isempty (a)==1)
temp = randsample((getNeighbourIndex(cubeOfInterest)), 1);
a= getNeighbourIndex(temp);
disp (a)
else
looping=false ;
end
end
x = randsample(a, 1);
set(hcube(x),'Visible','on','FaceColor','r','FaceAlpha',1)
cubeOfInterest= x;
end
在代码构建路径的上方从其中我初始化访问立方体阵列(受访= [])的行开始。
谁能告诉我,为什么程序卡在while循环?
编辑:我已经添加了一些代码来伯耆的代码 ,以使路径即使走访邻居继续。 它会选择任何没有访问过的立方体,并移动到它,如果它不会使断开的路径。 该代码是现在的工作合租以及所需。 下面是修改的部分,
%% // Random path
rng(1) %// set that if you want reproducible results, otherwise comment it
set(hcube,'Visible','off')
startCubeIndex = randi([1 numel(hcube)],1) ; %// random starting cube
%// startCubeIndex = 1 ; %// or fixed one
maxPathLength = 125 ; %// maximum length of path
maxPathLength= maxPathLength+1;
path_terminated = false ; %// condition to get out of loop
path_visited = [] ; %// store the generated path (visited cubes)this to be checked in case 2 as well.
ptIndex = 1 ;
path_visited(1) = startCubeIndex ;
set(hcube( path_visited(ptIndex) ) ,'Visible','on','FaceColor','r','FaceAlpha',1)
availableAll =[1:125];
while ~path_terminated
available_next = getNeighbourIndex( path_visited(ptIndex) ) ; %// get all the neighbours
[~,~,ib] = intersect(path_visited,available_next) ; %// check if we already went through some
if ~isempty(ib)
available_next(ib) = [] ; %// remove visited cube from "available" list
end
nAvail = numel(available_next) ; %// number of actually available neighbour
if nAvail == 0 %// Exit loop if no neighbour available
msgTerm = 'Path blocked. No other neighbour available.' ; %// Reason for terminating path
%//path_terminated = true ;
%//here I want to make the modification.
looping=true; %//To keep looping until we find the correct next move.
counter=0; %//to iterate through the cubes which are not visisted.
while looping==true
counter= counter+1;
jump= availableAll (counter); %//select the first available cube and check if it is suitable or not
if (~isempty (intersect(getNeighbourIndex(jump), path_visited))) %// if the selcted cube has a visited neighbor, it means it is suitable. The path will stay connected.
%good we found it.
ptIndex = ptIndex+1 ;
path_visited(ptIndex) = jump ; %//add the selected cube to the path.
availableAll (availableAll==jump)= []; %//remove the selected cube from the list of available cubes.
looping= false; %//stop looping.
end
%continue
end
else
ptIndex = ptIndex+1 ;
path_visited(ptIndex) = available_next( randi([1 nAvail],1) ) ;
availableAll (availableAll==path_visited(ptIndex))= []; %//remove the selected cube from the list of available cubes.
end
if ptIndex >= maxPathLength %// exit loop if we reached the max number of elements
msgTerm = 'Path terminated. Reached max number of elements.' ; %// Reason for terminating path
path_terminated = true ;
continue
end
%// choose one neighbour randomly among the available ones
set(hcube( path_visited(ptIndex) ) ,'Visible','on','FaceColor','r','FaceAlpha',1) %// highlight new cube
set(hcube( path_visited(1:ptIndex-1) ) ,'Visible','on','FaceColor','g','FaceAlpha',.2) %// shade old cubes
pause(0.05) %// just for intermediate display, you can comment these 2 lines
drawnow %// just for intermediate display, you can comment these 2 lines
end
disp(msgTerm)
上面的代码运行良好。 伯耆提供了很大的帮助,非常感谢伯耆 。
谢谢。