www.gusucode.com > 三维模仿源码程序 > 三维模仿源码程序/MathRubik2/PlotCube.m
function [bNewPlot,faces]=PlotCube(hAxes,Cube,bCoor,bColor) %PlotCube - plot the cube Cube in axes hAxes % PlotCube(hAxes,Cube) %!!zaken worden teveel dubbel (meervoudig) gedaan!!! bDoPlot=false; axes(hAxes); % current axes for draw if nargin<2 Cube=get(hAxes,'UserData'); elseif nargin>2 if bCoor<0 bDoPlot=true; end end hL=findobj(hAxes,'Type','line','Tag','PCdummyLine'); bTexture=~isempty(Cube.texture); if isempty(hL) bDoPlot=true; else DhL=get(hL,'UserData'); if ~isequal(Cube.texture,DhL.texture) bDoPlot=true; end end Cmid=Cube.Color(Cube.iMidInd); nMid=sum(Cmid>0); if bTexture&nMid==6 faces=zeros(3,3,6); faces(2,2,:)=1; else faces=[]; end Color=Cube.Color; if bDoPlot if isempty(hL) hL=line(0,0,'Tag','PCdummyLine'); else DhL=get(hL,'UserData'); hCube=DhL.hCube; hCube(hCube==0)=[]; delete(hCube) end if bTexture %(!!surface (bij standaard flat facecolor) geeft niet al de punten waar!!) %(vandaar dat nu ceil gebruikt werd ipv floor bij bepaling grootte) h=zeros(3,9); T0=ClearTexture(Cube); [m,n]=size(T0); colormap(Cube.texture.map) xx=(0:n-1)/(n-1)*2-1; yy=(0:m-1)'/(m-1)*2-1; mxXYZ=max(Cube.Nodes(:)); dd=Cube.Nodes(1,1,2)-Cube.Nodes(1,1,1); for ih=1:3 switch ih case 1 XX=zeros(size(T0))+mxXYZ; YY=xx(ones(1,m),:); ZZ=yy(end:-1:1,ones(1,n)); DX=[0 0]; DY=[dd 0]; DZ=[0 dd]; case 2 XX=xx(ones(1,m),end:-1:1); YY=zeros(size(T0))+mxXYZ; ZZ=yy(end:-1:1,ones(1,n)); DX=[-dd 0]; DY=[0 0]; DZ=[0 dd]; otherwise XX=yy(:,ones(1,n)); YY=xx(ones(1,n),:); ZZ=zeros(size(T0))+mxXYZ; DX=[0 -dd]; DY=[dd 0]; DZ=[0 0]; end iFace=ih*2; for kh=1:9 iCube=Cube.RotLayerCube(iFace,kh); c=rem(kh-1,3)-1; r=floor((kh-1)/3)-1; dx=DX*[c;r]; dy=DY*[c;r]; dz=DZ*[c;r]; currColor = Color(iFace,iCube); if currColor [Image,coor]=GetImage(Cube,currColor,c,r,iFace,iCube,0); if ~isempty(coor) faces(coor(1)+1,coor(2)+1,currColor)=1; end else Image=T0; end h(ih,kh)=surface(XX+dx,YY+dy,ZZ+dz,Image,'CDataMapping','direct','EdgeColor','none'); set(h(ih,kh),'ButtonDownFcn','RotateWithMouse;' ... ,'UserData',[iFace,iCube] ... ); end % for kh end % for ih else % simple cube-patches h=zeros(1,27); for iCube=1:27, CurrNodes = Cube.Nodes(:,:,iCube); currColor = Color(:,iCube)+1; h(iCube)=patch('Vertices',CurrNodes,'Faces',Cube.Order,... 'FaceVertexCData',Cube.ValColor(currColor,:),'FaceColor','flat',... 'ButtonDownFcn','RotateWithMouse;' ... ,'UserData',iCube ... ); end end set(hL,'UserData',struct('hCube',h,'texture',Cube.texture)); else DhL=get(hL,'UserData'); hCube=DhL.hCube; if nargin<4 bColor=true; if nargin<3 bCoor=true; end end if bTexture T0=ClearTexture(Cube); for ih=1:3 iFace=ih*2; for kh=1:9 iCube=Cube.RotLayerCube(iFace,kh); c=rem(kh-1,3)-1; r=floor((kh-1)/3)-1; currColor=Color(iFace,iCube); if currColor [Image,coor]=GetImage(Cube,currColor,c,r,iFace,iCube,0); if ~isempty(coor) faces(coor(1)+1,coor(2)+1,currColor)=1; end set(hCube(ih,kh),'CData',Image) elseif hCube(ih,kh) set(hCube(ih,kh),'CData',T0) end end % for kh end % for ih else % no texture for iCube=1:27 if bCoor set(hCube(iCube),'Vertices',Cube.Nodes(:,:,iCube)); end if bColor set(hCube(iCube),'FaceVertexCData',Cube.ValColor(Color(:,iCube)+1,:)) end end end end if ~isempty(faces)&bTexture % (normally only one test is necessary, but, ..., maybe in the future...) for ih=1:3 iFace=ih*2-1; for kh=[1:4 6:9]; iCube=Cube.RotLayerCube(iFace,kh); c=rem(kh-1,3)-1; r=floor((kh-1)/3)-1; currColor=Color(iFace,iCube); if currColor [Image,coor]=GetImage(Cube,currColor,c,r,iFace,iCube,1); if ~isempty(coor) faces(coor(1)+1,coor(2)+1,currColor)=1; end end end % for kh end % for ih end if nargout bNewPlot=bDoPlot; end function T0=ClearTexture(Cube) T0=ones(ceil(size(Cube.texture.XX{1})/3)); mxT0=max(T0(:)); T0(:,[1 end])=mxT0; T0([1 end],:)=mxT0; function [Image,coor]=GetImage(Cube,currColor,c,r,iFace,iCube,bOnlyCoor) persistent POSCsurfs TOPdirection POSEsurfs if isempty(POSCsurfs) POSCsurfs=reshape([ ... positions of corner surfaces 3 3 3 1 3 1; 3 1 3 3 1 1; 3 1 3 3 3 3; 3 3 3 1 1 3; 1 3 1 1 1 1; 1 1 1 3 3 1; 1 1 1 3 1 3; 1 3 1 1 3 3]' ... ,2,3,8); POSCsurfs(3,:,:)=6.5+POSCsurfs(1,:,:).*POSCsurfs(2,:,:)/2-2*POSCsurfs(1,:,:)-POSCsurfs(2,:,:); TOPdirection=[6 6 6 6 2 1]; % direction of top of texture for each color POSEsurfs=[ ... 0 0 6 4 8 2; ... positions of edge surfaces 0 0 4 6 8 2; 4 6 0 0 8 2; 6 4 0 0 8 2; 8 2 4 6 0 0; 2 8 4 6 0 0]; end [m,n]=size(Cube.texture.XX{1}); m1=ceil(m/3); n1=ceil(n/3); i1=-1; nRot=0; if all(Cube.Color(Cube.iMidInd)) if c*r % corner if sum(Cube.Color(:,iCube)>0)==3 cc=Cube.Color(:,iCube); cc=cc(cc>0); cnr=floor((cc-1)/2); csign=bitand(cc-1,1); Cnr=sum(csign.*2.^cnr)+1; posS1=POSCsurfs(:,floor((currColor+1)/2),Cnr); posS2=2.5-r*c/2+r; nRot=posS1(3)-posS2; i1=posS1(1)-1; j1=posS1(2)-1; end elseif c|r % edge if sum(Cube.Color(:,iCube)>0)==2 cc=Cube.Color(:,iCube); cc=cc(cc>0&cc~=currColor); if ~isempty(cc) % impossible cube posS1=POSEsurfs(currColor,cc); i1=floor((posS1-1)/3); j1=rem(posS1-1,3); %posS2=(5-r*3)*abs(r)+(c+5)*abs(c); posS2=(2+r)*abs(r)+(3-c)*abs(c); nRot=(3-i1)*abs(i1-1)+(4+j1)*abs(j1-1)-posS2; end end else % mid i1=r+1; j1=c+1; MyColor=Cube.Color(:,iCube); if Cube.bFullCube cCheck=TOPdirection(currColor); z=TOPdirection(iFace); % face of small midcube to test % count needed rotations while MyColor(z)~=cCheck nRot=nRot-1; MyColor(Cube.RotCubeFlat(iFace,:))=MyColor; if nRot<-4 % normally not possible!!!! warning(sprintf( ... '!!!!!!Ik kan de juiste orientatie niet vinden!!!! (face %d, color %d, check %d)' ... ,iFace,currColor,cCheck)); break; end end end end end if bOnlyCoor Image=[]; if i1<0 coor=[]; else coor=[i1 j1]; end return end if i1<0 coor=[]; Image=Cube.texture.XX{currColor}(1:3:end,1:3:end); if size(Image,1)<m1 Image(m1,:)=0; end if size(Image,2)<n1 Image(:,n1)=0; end else coor=[i1 j1]; i1=round(i1/3*m)+1; j1=round(j1/3*n)+1; if i1+m1-1>m i1=i1-1; end if j1+n1-1>n j1=j1-1; end Image=Cube.texture.XX{currColor}(i1:i1+m1-1,j1:j1+n1-1); %disp([c r iFace iCube nRot]) switch mod(nRot,4) case 1 Image=Image(m1:-1:1,:)'; case 2 Image=Image(m1:-1:1,n1:-1:1); case 3 Image=Image(:,n1:-1:1)'; end end Image=double(Image+1);