MATLAB|【手把手制作三阶魔方模拟器】用MATLAB让你的魔方动起来


【手把手制作三阶魔方模拟器】用MATLAB让你的魔方动起来

  • 1 定义魔方初始状态
  • 2 操作模块
    • 2.1 全操作定义
    • 2.2 旋转公式小函数
    • 2.3操作识别
  • 3 显示模块
    • 3.1 初始化
    • 3.2 显示操作后的魔方
  • 4 测试
  • 其他

by 今天不飞了
有一个酷爱魔方的朋友,托我给他定制一个专门用于“训练魔方观察和预判能力”的程序。听完需求之后觉得很有趣,就答应了,并决定把整个制作过程公开。
今天不飞了,一起写代码吧!
上次已经画好三阶魔方,是时候让它动起来了。话不多说,直接上代码。
1 定义魔方初始状态
function [axisBlock,cornerBlock, edgeBlock] = init(axisPosList,cornerPosList,edgePosList)% 轴块属性初始化 axisBlock = cell(6,1); for n = 1:6 axisBlock{ n}.RotateMatrix = [1,0,0; 0,1,0; 0,0,1]; axisBlock{ n}.position = axisPosList(n,:); axisBlock{ n}.color = ones(1,6)*7; axisBlock{ n}.color(n) = n; end % 角块属性初始化 cornerBlock = cell(8,1); for n = 1:8 cornerBlock{ n}.RotateMatrix = [1,0,0; 0,1,0; 0,0,1]; cornerBlock{ n}.position = cornerPosList(n,:); cornerBlock{ n}.color = ones(1,6)*7; end cornerBlock{ 1}.color([1,2,5]) = [1,2,5]; cornerBlock{ 2}.color([1,2,3]) = [1,2,3]; cornerBlock{ 3}.color([1,3,4]) = [1,3,4]; cornerBlock{ 4}.color([1,4,5]) = [1,4,5]; cornerBlock{ 5}.color([6,2,5]) = [6,2,5]; cornerBlock{ 6}.color([6,2,3]) = [6,2,3]; cornerBlock{ 7}.color([6,3,4]) = [6,3,4]; cornerBlock{ 8}.color([6,4,5]) = [6,4,5]; % 棱块属性初始化 edgeBlock = cell(12,1); for n = 1:12 edgeBlock{ n}.RotateMatrix = [1,0,0; 0,1,0; 0,0,1]; edgeBlock{ n}.position = edgePosList(n,:); edgeBlock{ n}.color = ones(1,6)*7; end edgeBlock{ 1}.color([1,2]) = [1,2]; edgeBlock{ 2}.color([1,3]) = [1,3]; edgeBlock{ 3}.color([1,4]) = [1,4]; edgeBlock{ 4}.color([1,5]) = [1,5]; edgeBlock{ 5}.color([2,3]) = [2,3]; edgeBlock{ 6}.color([3,4]) = [3,4]; edgeBlock{ 7}.color([4,5]) = [4,5]; edgeBlock{ 8}.color([5,2]) = [5,2]; edgeBlock{ 9}.color([6,2]) = [6,2]; edgeBlock{ 10}.color([6,3]) = [6,3]; edgeBlock{ 11}.color([6,4]) = [6,4]; edgeBlock{ 12}.color([6,5]) = [6,5]; end

2 操作模块 2.1 全操作定义 就是所谓的“U U’ R R’ f r M x” 等等,直接上成品,对推导过程感兴趣的,可以上B站看录播视频(见文末)
function [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(opt, ... blockIdx, axisBlock, cornerBlock, edgeBlock)switch optcase 1 % F R = getRotateMatrix(1,0,0); 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.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.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.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.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.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.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.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.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.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.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.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]); case 13 % S R = getRotateMatrix(1,0,0); for n = blockIdx.axisIdx([1,3,6,5]) axisBlock{ n}.RotateMatrix = axisBlock{ n}.RotateMatrix*R; end for n = blockIdx.edgeIdx([2,10,12,4]) edgeBlock{ n}.RotateMatrix = edgeBlock{ n}.RotateMatrix*R; end blockIdx.axisIdx([1,3,6,5]) = blockIdx.axisIdx([3,6,5,1]) ; blockIdx.edgeIdx([2,10,12,4]) = blockIdx.edgeIdx([10,12,4,2]); case -13 % S' R = getRotateMatrix(-1,0,0); for n = blockIdx.axisIdx([1,3,6,5]) axisBlock{ n}.RotateMatrix = axisBlock{ n}.RotateMatrix*R; end for n = blockIdx.edgeIdx([2,10,12,4]) edgeBlock{ n}.RotateMatrix = edgeBlock{ n}.RotateMatrix*R; end blockIdx.axisIdx([1,3,6,5]) = blockIdx.axisIdx([5,1,3,6]) ; blockIdx.edgeIdx([2,10,12,4]) = blockIdx.edgeIdx([4,2,10,12]); case 14 % M R = getRotateMatrix(0,-1,0); for n = blockIdx.axisIdx([1,4,6,2]) axisBlock{ n}.RotateMatrix = axisBlock{ n}.RotateMatrix*R; end for n = blockIdx.edgeIdx([1,3,11,9]) edgeBlock{ n}.RotateMatrix = edgeBlock{ n}.RotateMatrix*R; end blockIdx.axisIdx([1,4,6,2]) = blockIdx.axisIdx([2,1,4,6]) ; blockIdx.edgeIdx([1,3,11,9]) = blockIdx.edgeIdx([9,1,3,11]); case -14 % M' R = getRotateMatrix(0,1,0); for n = blockIdx.axisIdx([1,4,6,2]) axisBlock{ n}.RotateMatrix = axisBlock{ n}.RotateMatrix*R; end for n = blockIdx.edgeIdx([1,3,11,9]) edgeBlock{ n}.RotateMatrix = edgeBlock{ n}.RotateMatrix*R; end blockIdx.axisIdx([1,4,6,2]) = blockIdx.axisIdx([4,6,2,1]) ; blockIdx.edgeIdx([1,3,11,9]) = blockIdx.edgeIdx([3,11,9,1]); case 15 % E R = getRotateMatrix(0,0,-1); for n = blockIdx.axisIdx([2,3,4,5]) axisBlock{ n}.RotateMatrix = axisBlock{ n}.RotateMatrix*R; end for n = blockIdx.edgeIdx([5,6,7,8]) edgeBlock{ n}.RotateMatrix = edgeBlock{ n}.RotateMatrix*R; end blockIdx.axisIdx([2,3,4,5]) = blockIdx.axisIdx([5,2,3,4]) ; blockIdx.edgeIdx([5,6,7,8]) = blockIdx.edgeIdx([8,5,6,7]); case -15 % E' R = getRotateMatrix(0,0,1); for n = blockIdx.axisIdx([2,3,4,5]) axisBlock{ n}.RotateMatrix = axisBlock{ n}.RotateMatrix*R; end for n = blockIdx.edgeIdx([5,6,7,8]) edgeBlock{ n}.RotateMatrix = edgeBlock{ n}.RotateMatrix*R; end blockIdx.axisIdx([2,3,4,5]) = blockIdx.axisIdx([3,4,5,2]) ; blockIdx.edgeIdx([5,6,7,8]) = blockIdx.edgeIdx([6,7,8,5]); case 7 % f [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(1, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % F [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(13, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % Scase -7 % f' [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-1, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % F' [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-13, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % S'case 8 % r [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(2, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % R [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-14, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % M'case -8 % r' [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-2, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % R' [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(14, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % M case 9 % u [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(3, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % U [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-15, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % E'case -9 % u' [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-3, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % U' [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(15, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % Ecase 10 % b [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-4, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % B [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-13, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % S'case -10 % b' [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-4, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % B' [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(13, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % Scase 11 % l [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(5, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % L [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(14, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % Mcase -11 % l' [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-5, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % L' [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-14, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % M' case 12 % d [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(6, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % D [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(15, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % Ecase -12 % d' [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-6, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % D' [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-15, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % E'case 16 % x (y) [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(8, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % r [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-5, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % L'case -16 % x'(y') [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-8, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % r' [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(5, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % Lcase 17 % y (z) [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(9, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % u [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-6, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % D'case -17 % y'(z') [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-9, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % u' [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(6, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % Dcase 18 % z (x) [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(7, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % f [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-4, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % B'case -18 % z'(x') [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(-7, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % f' [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(4, ... blockIdx, axisBlock, cornerBlock, edgeBlock); % Bendend

2.2 旋转公式小函数
function R = getRotateMatrix(alpha,beta,gamma) % alpha,beta,gamma 为1或-1,分别表示顺时针转和逆时针转alpha = -pi/2*alpha; beta = -pi/2*beta; 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

2.3操作识别 咱们直接用魔方手法代号,让它自动转为上面的编号把
注:由于字符串里面不能再写 这个符号,所以我们用代替。比如RUR’U’ ,代码里用RUR,U,
function [optIdx,optNum] = getOptIdx(optList)optListNum = length(optList); optNum = 0; optIdx = zeros(optListNum,1); for k = 1:optListNum tmp = strfind('FRUBLDfrubldSMExyz',optList(k)); if ~isempty(tmp) optNum = optNum+1; optIdx(optNum) = tmp; else if optNum >0 optIdx(optNum) = -optIdx(optNum); end end end optIdx(optNum+1:end) = []; end

3 显示模块 3.1 初始化 画一个未打乱的魔方
function H = initshowcube(axisBlock, cornerBlock, edgeBlock, ... blockVertices, blockFace, color, colorAlpha)% 轴块 for n = 1:6 for f = 1:6 V = (axisBlock{ n}.position+blockVertices(blockFace{ f},:))*axisBlock{ n}.RotateMatrix; C = color{ axisBlock{ n}.color(f)}; A = colorAlpha(axisBlock{ n}.color(f)); H.axis{ n}{ f} = patch('Faces',[1 2 3 4],'Vertices',V,'FaceColor',C,... 'FaceAlpha',A); end end% 棱 for n = 1:12 for f = 1:6 V = (edgeBlock{ n}.position+blockVertices(blockFace{ f},:))*edgeBlock{ n}.RotateMatrix; C = color{ edgeBlock{ n}.color(f)}; A = colorAlpha(edgeBlock{ n}.color(f)); H.edge{ n}{ f} = patch('Faces',[1 2 3 4],'Vertices',V,'FaceColor',C,... 'FaceAlpha',A); end end% 角块 for n = 1:8 for f = 1:6V = (cornerBlock{ n}.position+blockVertices(blockFace{ f},:))*cornerBlock{ n}.RotateMatrix; C = color{ cornerBlock{ n}.color(f)}; A = colorAlpha(cornerBlock{ n}.color(f)); H.corner{ n}{ f} = patch('Faces',[1 2 3 4],'Vertices',V,'FaceColor',C,... 'FaceAlpha',A); end endend

3.2 显示操作后的魔方
function showcube(H, axisBlock, cornerBlock, edgeBlock, ... blockVertices, blockFace, color, colorAlpha)% 轴块 for n = 1:6 for f = 1:6 V = (axisBlock{ n}.position+blockVertices(blockFace{ f},:))*axisBlock{ n}.RotateMatrix; C = color{ axisBlock{ n}.color(f)}; A = colorAlpha(axisBlock{ n}.color(f)); H.axis{ n}{ f}.Vertices = V; H.axis{ n}{ f}.FaceColor = C; H.axis{ n}{ f}.FaceAlpha = A; end end% 棱 for n = 1:12 for f = 1:6 V = (edgeBlock{ n}.position+blockVertices(blockFace{ f},:))*edgeBlock{ n}.RotateMatrix; C = color{ edgeBlock{ n}.color(f)}; A = colorAlpha(edgeBlock{ n}.color(f)); H.edge{ n}{ f}.Vertices = V; H.edge{ n}{ f}.FaceColor = C; H.edge{ n}{ f}.FaceAlpha = A; end end% 角块 for n = 1:8 for f = 1:6 V = (cornerBlock{ n}.position+blockVertices(blockFace{ f},:))*cornerBlock{ n}.RotateMatrix; C = color{ cornerBlock{ n}.color(f)}; A = colorAlpha(cornerBlock{ n}.color(f)); H.corner{ n}{ f}.Vertices = V; H.corner{ n}{ f}.FaceColor = C; H.corner{ n}{ f}.FaceAlpha = A; end endend

4 测试 简单测试
clear; close all; clc%% 基本定义(魔方几何信息) 尺寸颜色透明度之类的可以根据需要自己修改 blockVertices = [ 1,-1,-1; 1, 1,-1; -1, 1,-1; -1,-1,-1; ... 1,-1, 1; 1, 1, 1; -1, 1, 1; -1,-1, 1]*0.95; blockFace{ 1} = [1,2,3,4]; blockFace{ 2} = [1,2,6,5]; blockFace{ 3} = [2,3,7,6]; blockFace{ 4} = [3,4,8,7]; blockFace{ 5} = [4,1,5,8]; blockFace{ 6} = [5,6,7,8]; % 6轴 axisPosList = [0, 0,-1; 1, 0, 0; 0, 1, 0; -1, 0, 0; 0,-1, 0; 0, 0, 1]*2; % 8角 cornerPosList = [1,-1,-1; 1, 1,-1; -1, 1,-1; -1,-1,-1; ... 1,-1, 1; 1, 1, 1; -1, 1, 1; -1,-1, 1]*2; % 12棱 edgePosList = [1, 0,-1; 0, 1,-1; -1, 0,-1; 0,-1,-1; ... 1, 1, 0; -1, 1, 0; -1,-1, 0; 1,-1, 0; 1, 0, 1; 0, 1, 1; -1, 0, 1; 0,-1, 1]*2; % 颜色定义 白 蓝 红 绿 橙 黄 color = { [1,1,1],[0,0.2,0.8],[0.8,0,0],[0,0.8,0.2],[1,0.4,0],[1,1,0],[0.1,0.1,0.1]}; colorAlpha = [1,1,1,1,1,1,0.9]; % 初始槽位 blockIdx.axisIdx = [1,2,3,4,5,6]; blockIdx.cornerIdx = [1,2,3,4,5,6,7,8]; blockIdx.edgeIdx = [1,2,3,4,5,6,7,8,9,10,11,12]; %% 初始化 [axisBlock,cornerBlock,edgeBlock] = init(axisPosList,cornerPosList,edgePosList); % 显示 figure('Position',[100,100,600,700]) axis off axis equal axis([-1,1,-1,1,-1,1]*4) xlabel('x') ylabel('y') zlabel('z') view([5,2,2])H = initshowcube(axisBlock, cornerBlock, edgeBlock, ... blockVertices, blockFace, color, colorAlpha); %% 操作 % 设置操作 optList = 'RUUR,U,RUR,U,RU,R,'; % 转为编号 [optIdx,optNum] = getOptIdx(optList); % 循环转动 for k = 1:optNum % 执行 [blockIdx, axisBlock, cornerBlock, edgeBlock] = operation(optIdx(k), blockIdx, axisBlock, cornerBlock, edgeBlock); % 显示 showcube(H, axisBlock, cornerBlock, edgeBlock, ... blockVertices, blockFace, color, colorAlpha) pause(0.1) end

效果图
MATLAB|【手把手制作三阶魔方模拟器】用MATLAB让你的魔方动起来
文章图片

大家肯定发现了,这样实现的话缺少“动感”,给人感觉就是颜色在变,没有转动的感觉。
没错,下一期就一起来实现“动态旋转”。
其他
  1. 程序有bug,或有更好的提议,欢迎留言告诉我
  2. 代码录播视频见B站【三阶魔方】手把手从零实现,魔方观察训练程序(二)让魔方动起来
【MATLAB|【手把手制作三阶魔方模拟器】用MATLAB让你的魔方动起来】P.S. 宇茵小姐姐的代写平台开业啦。如果你是技术大佬想做兼职,可以扫描下方二维码加入平台;如果你是小可爱想找代写,可以直接找我哦
MATLAB|【手把手制作三阶魔方模拟器】用MATLAB让你的魔方动起来
文章图片

    推荐阅读