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

21 篇文章 3 订阅

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 opt
    
    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([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); % S
        
    case -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); % E
        
    case 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); % S
        
    case 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 -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); % E
        
    case -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); % L
        
    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); % 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); % D
        
    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); % 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); % B
        
end

end

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: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} = patch('Faces',[1 2 3 4],'Vertices',V,'FaceColor',C,...
            'FaceAlpha',A);
    end
end

end

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
end

end

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

效果图

在这里插入图片描述
大家肯定发现了,这样实现的话缺少“动感”,给人感觉就是颜色在变,没有转动的感觉。
没错,下一期就一起来实现“动态旋转”。

其他

  1. 程序有bug,或有更好的提议,欢迎留言告诉我
  2. 代码录播视频见B站【三阶魔方】手把手从零实现,魔方观察训练程序(二)让魔方动起来
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值