三阶魔方绘制-动态变化
魔方绘制
魔方绘制可以参考链接: 【手把手制作三阶魔方模拟器】用MATLAB绘制一个三阶魔方和 【手把手制作三阶魔方模拟器】用MATLAB让你的魔方动起来。
可以达到的效果为:
可以看到魔方没有动态变化,只是颜色的变化。
在旋转公式函数中,90度为一次循环,改变为单次循环为10度,循环9次,便可以将过程动态展现出来。
alpha = -pi/2*alpha;
beta = -pi/2*beta;
gamma = -pi/2*gamma;
变化后为:
function R = getRotateMatrix(alpha,beta,gamma)
% alpha,beta,gamma 为1或-1,分别表示顺时针转和逆时针转
alpha = -pi/18*alpha; %-pi/2*alpha;
beta = -pi/18*beta; %-pi/2*beta;
gamma = -pi/18*gamma; %-pi/2*gamma;
Rx = [1,0,0;0,cos(alpha),-sin(alpha);0,sin(alpha),cos(alpha)];
Ry = [cos(beta),0,sin(beta);0,1,0;-sin(beta),0,cos(beta)];
Rz = [cos(gamma),-sin(gamma),0;sin(gamma),cos(gamma),0;0,0,1];
R = (Rx*Ry*Rz)';
end
测试函数
由于每次转动角度为10度,因此,主函数即测试函数需要对每次每一个操作循环9次。
操作代码部分:
H = initshowcube(axisBlock, cornerBlock, edgeBlock, ...
blockVertices, blockFace, color, colorAlpha);
%% 操作
% 设置操作
optList = 'RUUR,U,RUR,U,RU,R,';
% 转为编号
[optIdx,optNum] = getOptIdx(optList);
% 循环转动
for k = 1:optNum
for i = 1:9
% 执行
[blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(optIdx(k), blockIdx, axisBlock, cornerBlock, edgeBlock);
% 显示
showcube(H, axisBlock, cornerBlock, edgeBlock, ...
blockVertices, blockFace, color, colorAlpha)
pause(0.1)
end
end
在每次操纵的大循环中加入9次小循环,并显示9次就可以实现了。
中心块转动
但是,这个时候发现一个问题,在旋转过程中,魔方中心块不旋转,只有角块和棱块变化,主要原因是魔方各操作时,没有将中心块位置变化写出,导致变化过程不包含中心块,主要对function [blockIdx, axisBlock, concerBlock, edgeBlock] = operation(opt, blockIdx, axisBlock, concerBlock, edgeBlock) 前12种情况函数进行修改,如下:
function [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(opt, ...
blockIdx, axisBlock, cornerBlock, edgeBlock)
switch opt
case 1 % F
R = getRotateMatrix(1,0,0);
for n = blockIdx.axisIdx(2)
axisBlock{n}.RotateMatrix = axisBlock{n}.RotateMatrix*R;
end
for n = blockIdx.cornerIdx([1,2,6,5])
cornerBlock{n}.RotateMatrix = cornerBlock{n}.RotateMatrix*R;
end
for n = blockIdx.edgeIdx([1,5,9,8])
edgeBlock{n}.RotateMatrix = edgeBlock{n}.RotateMatrix*R;
end
blockIdx.cornerIdx([1,2,6,5]) = blockIdx.cornerIdx([2,6,5,1]) ;
blockIdx.edgeIdx([1,5,9,8]) = blockIdx.edgeIdx([5,9,8,1]);
case -1 % F'
R = getRotateMatrix(-1,0,0);
for n = blockIdx.axisIdx(2)
axisBlock{n}.RotateMatrix = axisBlock{n}.RotateMatrix*R;
end
for n = blockIdx.cornerIdx([1,2,6,5])
cornerBlock{n}.RotateMatrix = cornerBlock{n}.RotateMatrix*R;
end
for n = blockIdx.edgeIdx([1,5,9,8])
edgeBlock{n}.RotateMatrix = edgeBlock{n}.RotateMatrix*R;
end
blockIdx.cornerIdx([1,2,6,5]) = blockIdx.cornerIdx([5,1,2,6]) ;
blockIdx.edgeIdx([1,5,9,8]) = blockIdx.edgeIdx([8,1,5,9]);
case 2 % R
R = getRotateMatrix(0,1,0);
for n = blockIdx.axisIdx(3)
axisBlock{n}.RotateMatrix = axisBlock{n}.RotateMatrix*R;
end
for n = blockIdx.cornerIdx([2,3,7,6])
cornerBlock{n}.RotateMatrix = cornerBlock{n}.RotateMatrix*R;
end
for n = blockIdx.edgeIdx([2,6,10,5])
edgeBlock{n}.RotateMatrix = edgeBlock{n}.RotateMatrix*R;
end
blockIdx.cornerIdx([2,3,7,6]) = blockIdx.cornerIdx([3,7,6,2]) ;
blockIdx.edgeIdx([2,6,10,5]) = blockIdx.edgeIdx([6,10,5,2]);
case -2 % R'
R = getRotateMatrix(0,-1,0);
for n = blockIdx.axisIdx(3)
axisBlock{n}.RotateMatrix = axisBlock{n}.RotateMatrix*R;
end
for n = blockIdx.cornerIdx([2,3,7,6])
cornerBlock{n}.RotateMatrix = cornerBlock{n}.RotateMatrix*R;
end
for n = blockIdx.edgeIdx([2,6,10,5])
edgeBlock{n}.RotateMatrix = edgeBlock{n}.RotateMatrix*R;
end
blockIdx.cornerIdx([2,3,7,6]) = blockIdx.cornerIdx([6,2,3,7]) ;
blockIdx.edgeIdx([2,6,10,5]) = blockIdx.edgeIdx([5,2,6,10]);
case 3 % U
R = getRotateMatrix(0,0,1);
for n = blockIdx.axisIdx(6)
axisBlock{n}.RotateMatrix = axisBlock{n}.RotateMatrix*R;
end
for n = blockIdx.cornerIdx([5,6,7,8])
cornerBlock{n}.RotateMatrix = cornerBlock{n}.RotateMatrix*R;
end
for n = blockIdx.edgeIdx([9,10,11,12])
edgeBlock{n}.RotateMatrix = edgeBlock{n}.RotateMatrix*R;
end
blockIdx.cornerIdx([5,6,7,8]) = blockIdx.cornerIdx([6,7,8,5]) ;
blockIdx.edgeIdx([9,10,11,12]) = blockIdx.edgeIdx([10,11,12,9]);
case -3 % U'
R = getRotateMatrix(0,0,-1);
for n = blockIdx.axisIdx(6)
axisBlock{n}.RotateMatrix = axisBlock{n}.RotateMatrix*R;
end
for n = blockIdx.cornerIdx([5,6,7,8])
cornerBlock{n}.RotateMatrix = cornerBlock{n}.RotateMatrix*R;
end
for n = blockIdx.edgeIdx([9,10,11,12])
edgeBlock{n}.RotateMatrix = edgeBlock{n}.RotateMatrix*R;
end
blockIdx.cornerIdx([5,6,7,8]) = blockIdx.cornerIdx([8,5,6,7]) ;
blockIdx.edgeIdx([9,10,11,12]) = blockIdx.edgeIdx([12,9,10,11]);
case 4 % B
R = getRotateMatrix(-1,0,0);
for n = blockIdx.axisIdx(4)
axisBlock{n}.RotateMatrix = axisBlock{n}.RotateMatrix*R;
end
for n = blockIdx.cornerIdx([3,4,8,7])
cornerBlock{n}.RotateMatrix = cornerBlock{n}.RotateMatrix*R;
end
for n = blockIdx.edgeIdx([3,7,11,6])
edgeBlock{n}.RotateMatrix = edgeBlock{n}.RotateMatrix*R;
end
blockIdx.cornerIdx([3,4,8,7]) = blockIdx.cornerIdx([4,8,7,3]) ;
blockIdx.edgeIdx([3,7,11,6]) = blockIdx.edgeIdx([7,11,6,3]);
case -4 % B'
R = getRotateMatrix(1,0,0);
for n = blockIdx.axisIdx(4)
axisBlock{n}.RotateMatrix = axisBlock{n}.RotateMatrix*R;
end
for n = blockIdx.cornerIdx([3,4,8,7])
cornerBlock{n}.RotateMatrix = cornerBlock{n}.RotateMatrix*R;
end
for n = blockIdx.edgeIdx([3,7,11,6])
edgeBlock{n}.RotateMatrix = edgeBlock{n}.RotateMatrix*R;
end
blockIdx.cornerIdx([3,4,8,7]) = blockIdx.cornerIdx([7,3,4,8]) ;
blockIdx.edgeIdx([3,7,11,6]) = blockIdx.edgeIdx([6,3,7,11]);
case 5 % L
R = getRotateMatrix(0,-1,0);
for n = blockIdx.axisIdx(5)
axisBlock{n}.RotateMatrix = axisBlock{n}.RotateMatrix*R;
end
for n = blockIdx.cornerIdx([1,5,8,4])
cornerBlock{n}.RotateMatrix = cornerBlock{n}.RotateMatrix*R;
end
for n = blockIdx.edgeIdx([4,8,12,7])
edgeBlock{n}.RotateMatrix = edgeBlock{n}.RotateMatrix*R;
end
blockIdx.cornerIdx([1,5,8,4]) = blockIdx.cornerIdx([5,8,4,1]) ;
blockIdx.edgeIdx([4,8,12,7]) = blockIdx.edgeIdx([8,12,7,4]);
case -5 % L'
R = getRotateMatrix(0,1,0);
for n = blockIdx.axisIdx(5)
axisBlock{n}.RotateMatrix = axisBlock{n}.RotateMatrix*R;
end
for n = blockIdx.cornerIdx([1,5,8,4])
cornerBlock{n}.RotateMatrix = cornerBlock{n}.RotateMatrix*R;
end
for n = blockIdx.edgeIdx([4,8,12,7])
edgeBlock{n}.RotateMatrix = edgeBlock{n}.RotateMatrix*R;
end
blockIdx.cornerIdx([1,5,8,4]) = blockIdx.cornerIdx([4,1,5,8]) ;
blockIdx.edgeIdx([4,8,12,7]) = blockIdx.edgeIdx([7,4,8,12]);
case 6 % D
R = getRotateMatrix(0,0,-1);
for n = blockIdx.axisIdx(1)
axisBlock{n}.RotateMatrix = axisBlock{n}.RotateMatrix*R;
end
for n = blockIdx.cornerIdx([1,2,3,4])
cornerBlock{n}.RotateMatrix = cornerBlock{n}.RotateMatrix*R;
end
for n = blockIdx.edgeIdx([1,2,3,4])
edgeBlock{n}.RotateMatrix = edgeBlock{n}.RotateMatrix*R;
end
blockIdx.cornerIdx([1,2,3,4]) = blockIdx.cornerIdx([4,1,2,3]) ;
blockIdx.edgeIdx([1,2,3,4]) = blockIdx.edgeIdx([4,1,2,3]);
case -6 % D'
R = getRotateMatrix(0,0,1);
for n = blockIdx.axisIdx(1)
axisBlock{n}.RotateMatrix = axisBlock{n}.RotateMatrix*R;
end
for n = blockIdx.cornerIdx([1,2,3,4])
cornerBlock{n}.RotateMatrix = cornerBlock{n}.RotateMatrix*R;
end
for n = blockIdx.edgeIdx([1,2,3,4])
edgeBlock{n}.RotateMatrix = edgeBlock{n}.RotateMatrix*R;
end
blockIdx.cornerIdx([1,2,3,4]) = blockIdx.cornerIdx([2,3,4,1]) ;
blockIdx.edgeIdx([1,2,3,4]) = blockIdx.edgeIdx([2,3,4,1]);
修改后执行便可以得到可以动态运动的魔方了。