- /
-
Rubix Cube
on 12 Oct 2024
- 64
- 941
- 2
- 4
- 1871
Cite your audio source here (if applicable):
Music Credit: LAKEY INSPIRED
Track Name: "Blue Boi"
Write your drawframe function below
function drawframe(f)
clf
% Movement sequence, MS
% (1,:) Which axis x, y, z, or (pause p) to rotate around
% (2,:) Which row to rotate 1, 2, or 3. any character if pause
% (3,:) Which direction to rotate, n if negative direction, p for positive
% Change to alter moves made. The function tries to fit all moves within 4s
% If timing issues arise all moves are executed and then a pause untill all
%
MS=['yyxxzzyypyyzzxxyy';'13311313031311331';'nppnpnpn0pnpnpnnp'];
%Timing and frame variables
FramesPerMove = floor(96/size(MS,2));
AngSpd = 90/FramesPerMove;
if f > FramesPerMove*size(MS,2)
f=FramesPerMove*size(MS,2);
% Some Equivivalent of pause
end
% Get coordinates and colors needed to patch() the geometry
[X,Y,Z,C]=initCoords;
%Draw the initial cube
P = patch(X,Y,Z,C,EdgeColor='k');
% Set figure window properties
lim = [-2.4,2.4];
xlim(lim);
ylim(lim);
zlim(lim);
ax=gca;
set(ax,'xtick',[])
set(ax,'ytick',[])
set(ax,'ztick',[])
set(get(ax, 'XAxis'), 'Visible', 'off');
set(get(ax, 'YAxis'), 'Visible', 'off');
set(get(ax, 'ZAxis'), 'Visible', 'off');
pbaspect([1,1,1])
view(-45, 30);
% To adjust this code to plot the current frame instead of looping all
% moves we (unnecessarily) loop from the start to the frame we desire
c=1;
for frame = 1:f
% Set the rotation matrix and get the coordinates for the axis we
% rotate around
if MS(3,c)=='n'
dir=-1;
elseif MS(3,c)=='p'
dir=1;
end
switch MS(1,c)
case 'x'
R=[1,0,0;
0,cosd(dir*AngSpd),-sind(dir*AngSpd);
0,sind(dir*AngSpd),cosd(dir*AngSpd)];
F=P.XData;
case 'y'
R=[cosd(dir*AngSpd),0,sind(dir*AngSpd);
0,1,0;
-sind(dir*AngSpd),0,cosd(dir*AngSpd)];
F=P.YData;
case 'z'
R=[cosd(dir*AngSpd),-sind(dir*AngSpd),0;
sind(dir*AngSpd),cosd(dir*AngSpd),0;
0,0,1];
F=P.ZData;
case 'p' %pause
if ~mod(AngSpd*frame,90)
c=c+1;
end
continue
end
% Find the indexes for the faces to rotate
if MS(2,c)=='1'
faces=find(sum(F>=.5-10^-5,1)==4);
elseif MS(2,c)=='2'
faces=find(sum(F<=.5+10^-5&&F>=-.5-10^-5,1)>4);
else
faces=find(sum(F<=-.5+10^-5,1)==4);
end
% Get the coordinate data in the correct dimensions for a matrix
% multiplication for each face
D(:,:,1) = P.XData;
D(:,:,2) = P.YData;
D(:,:,3) = P.ZData;
D = permute(D,[3,2,1]);
% Perform the rotation for each of the four vertices in a face
for j = 1:4
K(1:3,1:length(faces),j) = R*D(:,faces,j);
end
% Return the dimensions and update the coordinate data in the plot
K=permute(K,[3,2,1]);
P.XData(:,faces) = K(:,:,1);
P.YData(:,faces) = K(:,:,2);
P.ZData(:,faces) = K(:,:,3);
% Reset variables to avoid any mishaps with erroneous dimensions
K=[];
D=[];
if ~mod(AngSpd*frame,90)
c=c+1;
end
end
drawnow
end
function [X,Y,Z,C] = initCoords
% Set the colors of different cube faces
colors=[1 0 0;1 .6471 0;0 0 1;0 1 0;1 1 0;1 1 1;0 0 0];
% shorthand some matrixes to save some characters
a=[0,0,0,0];
b=[2,3,3,2];
c=[0,0,1,1];
% Predefine Variables to append information in
X=[];
Y=[];
Z=[];
C=[];
% Loop over the x, y, and z plane
% Loop over the "6" planes of the cube
% Technically there are 3 "rows" or "planes" in a rubix cube, but to
% avoid the cube feeling hollow we build the cube from 3x3x3 smaller
% cubes. Meaning we get six planes along any given axis that should be
% able to rotate indepenently from each other
% Loop over the three horizontal sides of a face
% Loop over the three vertical faces on a side
for Coord=1:3
for plane=0:5
for i=0:2
for j=0:2
del=0;
if plane==0 % First plane, colorful outside plane!
col=2*Coord-1;
elseif plane== 5 % Last plane, also colorful outside plane!
col=2*Coord;
else % Plane inside the cube, we color these black
% To be able to "select" plane faces easily, we
% separate them slightly from eachother with a delta
if mod(plane,2)
del=-10^-4;
else
del=+10^-4;
end
col=7;
end
pl = round(plane/2);
%Determine coordinates based on axis and plane
switch Coord
case 1 %x
x=a+pl+del;
y=[3,3,2,2]-i;
z=b-j;
case 2 %y
x=c+i;
y=a+pl+del;
z=b-j;
case 3 %z
x=c+i;
y=[1,0,0,1]+j;
z=a+pl+del;
end
% Append coordinates of face verticies and specified color
X=[X,x'];
Y=[Y,y'];
Z=[Z,z'];
C = [C;colors(col,:)];
end
end
end
end
% Center the cube coordinates around 0 and get C into proper dimensions
X=X-1.5;
Y=Y-1.5;
Z=Z-1.5;
C=reshape(C,size(X,2),1,3);
end