以下是我的思路

先了解几个重要的函数

patch()函数

原理:点按顺序连成封闭多边形。

使用:

point_sequence=[1,2,3,4]; %点连接的顺序
square_xyz=[3,1,3;1,1,3;1,-1,3;3,-1,3]; %三维坐标4x3矩阵
patch('Faces',point_sequence,'Vertices',square_xyz,'FaceColor','blue');
axis([-3,3,-3,3,-3,3]);%坐标系范围
view(3);

rotx()、roty()、rotz()函数

作用:生成三阶旋转矩阵,例如点A以x为轴逆时针旋转90°得到点B,旋转矩阵为Q,则B=QA,A,B为列向量。rotx(theta);%theta为逆时针旋转角度

使用:

A = [1,1,1]';
Q=rotx(90);
B=Q*A>>B =1-11

如何实现旋转

用patch()函数生成patch对象句柄,用句柄查看patch对象的属性,使用get()函数获取坐标属性值,使用set()函数重新设置坐标矩阵从而实现旋转。

例如将蓝色正方形绕x轴旋转45°,程序如下:

point_sequence=[1,2,3,4]; %点连接的顺序
square_xyz=[3,1,3;1,1,3;1,-1,3;3,-1,3]; %三维坐标4x3矩阵,行向量坐标axis([-3,3,-3,3,-3,3]);%坐标系范围
xlabel('X');
ylabel('Y');
zlabel('Z');
view(3);%三维视角
patch_handles=patch('Faces',point_sequence,'Vertices',square_xyz,'FaceColor','blue');
Vertices=get(patch_handles,'Vertices') %得到三维坐标4x3矩阵,行向量坐标
R = rotx(45); %绕x轴旋转45°生成旋转矩阵
Vertices = (R*Vertices')'; %得到旋转后的矩阵
pause(1); %暂停1秒
set(patch_handles,'Vertices',Vertices); %设置坐标矩阵

效果:

确定三维坐标

如何确定魔方6个面共54个色卡,每个色块4个顶点的坐标呢?如果一个一个点确定坐标,然后得到一个一个色块的4x3矩阵(行向量),工程量太大也容易出错,而且不易修改尺寸,这里我提供一个方法。

以魔方的正中心为原点(0,0,0),通过单轴坐标平移得到6个面的中心点坐标,取一个面的中心点坐标通过双轴坐标平移得到每个色块的中心点坐标,再取一个色块的中心点坐标通过双轴坐标平移得到色块4个顶点的坐标。双轴坐标平移都是有规律的。

取一个色块边长为2个单位,因为是双轴坐标平移有一个坐标轴是不变的,所以下面这两个全局变量是4x2矩阵(行向量)。

global anticlockwise_4point_xyxzyz %逆时针4个点,逆时针即夹角增大的方向
anticlockwise_4point_xyxzyz=[1,1;-1,1;-1,-1;1,-1];
global anticlockwise_9point_xyxzyz %逆时针9个点,最后一个坐标原点
anticlockwise_9point_xyxzyz=[2,0;2,2;0,2;-2,2;-2,0;-2,-2;0,-2;2,-2;0,0];

编写3个函数

函数一:一个中心点生成9个中心点

%双轴坐标平移,得到每个面的9个中心点,最后一个是中心块的坐标
function central_9point_xyz=get_central_9point_xyz_fun(xyz_axis)
global anticlockwise_9point_xyxzyz;
temp=anticlockwise_9point_xyxzyz;
central_9point_xyz=ones(9,3).*3;%原点(0,0,0)向某个轴正方向移动3个单位
switch xyz_axiscase '+x' %垂直+x轴的面上的点坐标平移central_9point_xyz(:,2:3)=temp;case '-x'central_9point_xyz=-central_9point_xyz; %负方向移动3个单位central_9point_xyz(:,2:3)=temp;        case '+y'central_9point_xyz(:,1)=temp(:,1);central_9point_xyz(:,3)=temp(:,2);case '-y'central_9point_xyz=-central_9point_xyz;central_9point_xyz(:,1)=temp(:,1);central_9point_xyz(:,3)=temp(:,2);case '+z'central_9point_xyz(:,1:2)=temp;case '-z'central_9point_xyz=-central_9point_xyz;central_9point_xyz(:,1:2)=temp;
end
end

函数二:一个中心点生成色块4个顶点

%双轴坐标平移,一个色块的中心点得到色块4个顶点
function square_4point_xyz=get_square_4point_xyz_fun(xyz_axis,central_point_xyz)
global anticlockwise_4point_xyxzyz
temp=anticlockwise_4point_xyxzyz;
increment=central_point_xyz; %中心点为偏移量
square_4point_xyz=zeros(4,3); %色块的坐标矩阵
switch xyz_axiscase '+x'square_4point_xyz(:,2:3)=temp;case '-x'square_4point_xyz=-square_4point_xyz;square_4point_xyz(:,2:3)=temp;        case '+y'square_4point_xyz(:,1)=temp(:,1);square_4point_xyz(:,3)=temp(:,2);case '-y'square_4point_xyz=-square_4point_xyz;square_4point_xyz(:,1)=temp(:,1);square_4point_xyz(:,3)=temp(:,2);case '+z'square_4point_xyz(:,1:2)=temp;case '-z'square_4point_xyz=-square_4point_xyz;square_4point_xyz(:,1:2)=temp;
end
for i=1:4 square_4point_xyz(i,:)=square_4point_xyz(i,:)+increment; %每个点加上偏移量
end
end

 函数三:拼成36x3阶矩阵(行向量),包含一个面9个色块的顶点坐标,调用了函数二

%得到一个面九个色块顶点的坐标,36x3阶矩阵(行向量)
function face_9square_xyz=get_face_9square_xyz_fun(xyz_axis,face_central_9point_xyz)
face_9square_xyz=zeros(36,3);
for i=1:9face_9square_xyz((i-1)*4+1:i*4,:)=get_square_4point_xyz_fun(xyz_axis,face_central_9point_xyz(i,:));
end
end

旋转魔方一个面的思路

1、句柄

前面举例说了修改patch句柄的'Vertices'属性即顶点坐标可实现色块的移动,可以用一维数组patch_handles存储54个色块的54个句柄,用patch()函数生成句柄,第一个色块的句柄就是patch_handles(1)=patch()。patch_handles为全局变量。

global patch_handles %patch对象句柄
patch_handles=[];patch_handles(1)=patch('Faces',point_sequence,'Vertices',Uface_9square_xyz(1:4,:),'FaceColor',Uface_color);

2、找要旋转色块句柄的索引

流程为:

确定色块所在平面垂直的坐标轴,如x正半轴表示为'+x'。下面以'+x'为例

用get()函数获取色块句柄的'XData'属性得到四个顶点的x坐标组成的列向量xyz

用find()函数判断列向量xyz中是否存在等于3的元素,因为垂直正半x轴面上的点的x轴坐标必=3

记下索引存储到index数组中

函数如下返回值为索引数组index:

function index=get_index_fun(xyz_axes) %找要旋转色块句柄的索引
global patch_handles
index=[];
XYZData_str='';
compare=0;
switch xyz_axescase '+x'XYZData_str='XData';compare=3;case '-x'XYZData_str='XData';compare=-3;case '+y'XYZData_str='YData';compare=3;case '-y'XYZData_str='YData';compare=-3;case '+z'XYZData_str='ZData';compare=3;case '-z'XYZData_str='ZData';compare=-3;
end
for i=1:54   xyz=get(patch_handles(i),XYZData_str);f=find(xyz==compare);if ~isempty(f)index=[index,i];endif length(index)==21break;end
end
end

3、设置句柄属性实现旋转

要注意坐标矩阵V与旋转矩阵R相乘后可能出现分数,就不能用某个轴坐标等于3或-3判断色块所在面,需使用四舍五入取整函数对坐标矩阵取整,应该在最后一轮设置坐标属性时取整,因为旋转90°分为9次每次旋转10°实现动态旋转,应该在第9次时对坐标矩阵四舍五入取整,取整早了魔方会缩小。

函数如下:

function rotation_90(xyz_axes,direction) %旋转在xyz_axes轴上的面90°并画色块
global patch_handles
index=get_index_fun(xyz_axes);
L=length(index); %需要旋转21个色块
per_degree=10; %每次旋转10°
time=9; %一共旋转9次
switch xyz_axescase '+x'R=rotx(per_degree*direction); %绕x轴旋转生成的旋转矩阵Rcase '-x'R=rotx(per_degree*direction);case '+y'R=roty(per_degree*direction);case '-y'R=roty(per_degree*direction);case '+z'R=rotz(per_degree*direction);case '-z'R=rotz(per_degree*direction);
end
for t=1:time-1for i=1:LV=get(patch_handles(index(i)),'Vertices');%获得4x3坐标矩阵V=(R*V')'; %得到旋转后的矩阵set(patch_handles(index(i)),'Vertices',V); %画色块endpause(0.1);
end
%最后一次旋转坐标四舍五入取整
for i=1:LV=get(patch_handles(index(i)),'Vertices');%获得4x3坐标矩阵V=(R*V')'; %得到旋转后的矩阵V=round(V); %非常重要,四舍五入取整set(patch_handles(index(i)),'Vertices',V); %画色块
end
end

主函数和运行效果

以下是部分主函数,很多重复的没有贴出来,例如给patch_handles赋值54个句柄。

clc;
clear;
global patch_handles %patch对象句柄
patch_handles=[];
global point_sequence
point_sequence=[1,2,3,4];
global anticlockwise_4point_xyxzyz %逆时针4个点
anticlockwise_4point_xyxzyz=[1,1;-1,1;-1,-1;1,-1];
global anticlockwise_9point_xyxzyz %逆时针9个点,逆时针即夹角增大的方向
anticlockwise_9point_xyxzyz=[2,0;2,2;0,2;-2,2;-2,0;-2,-2;0,-2;2,-2;0,0];%逆时针8个中心点,加一个(0,0)点
%六个面颜色
Uface_color='y';
Dface_color='w';
Fface_color='b';
Bface_color='g';
Lface_color=[1,0.5,0];%橙色
Rface_color='r';Uface_central_9point_xyz=get_central_9point_xyz_fun('+z'); %F面9个中心点的坐标
Uface_9square_xyz=get_face_9square_xyz_fun('+z',Uface_central_9point_xyz);axis([-5,5,-5,5,-5,5]);%坐标系范围
title('魔方');
axis off
view(3);%三维视角patch_handles(1)=patch('Faces',point_sequence,'Vertices',Uface_9square_xyz(1:4,:),'FaceColor',Uface_color);pause(1);
rotation_90('+x',1);
rotation_90('+z',-1);
rotation_90('+y',1);
rotation_90('+y',-1);
rotation_90('+z',1);
rotation_90('+x',-1);

结尾

你可以根据我的思路自己写一个,以上就是全部函数没有漏的。或者另辟蹊径。

下一篇文章:给魔方加一个GUI操作界面

http://t.csdn.cn/yk9wDhttp://t.csdn.cn/yk9wD

原创不易还请支持

https://download.csdn.net/download/qq_42053235/85240749https://download.csdn.net/download/qq_42053235/85240749

MATLAB画三维动态魔方/旋转魔方/旋转立方体相关推荐

  1. Matlab画三维图的一些技巧

    引言 本人是一位数学科研工作者,平时的文章采用的是latex编写,里面图形的生成主要来自于Matlab(个人对Matlab非常喜欢,感觉上手比较容易,更亲民).对于图形的处理比较频繁,而且总会有一些特 ...

  2. matlab如何修改三维箭头类型,matlab画三维箭头

    matlab绘制动态三维心形代码(蛋疼的情人节奉献)_设计/艺术_人文社科_专业资料.Matlab 绘制三维动态心形 It's OK to send a pic to your girlfriend ...

  3. matlab绘图z=sin(x_「matlab画三维图」Matlab 应用之绘制三维图形(基础篇) - seo实验室...

    matlab画三维图 在Matlab中,三维图形的绘制包括三维曲线,三维网线图和三维曲面图.闲话不多说,直接进入正题.首先介绍几个函数: 1.plot3(x,y,z,-) 其中,x,y,z为维数相同的 ...

  4. MATLAB 画三维长方体 介绍+代码

    MATLAB 画三维长方体 介绍+代码 在做机械臂三维避障仿真时可能用到对空间障碍物进行描述,一般用长方体,圆柱体等描述,以下是两种画长方体的程序,第一种是指定长方体的八个顶点坐标,第二种是指定长方体 ...

  5. MATLAB画三维球体函数

    MATLAB画三维球体函数区别 共四种方法 [u,v,w] = sphere(56);subplot(2,2,1) plot3(u,v,w); title('plot()')subplot(2,2,2 ...

  6. matlab鼠标三维坐标点,请问如何用matlab画三维点,已知x,y,z的坐标,在三维坐标系上显示...

    点击查看请问如何用matlab画三维点,已知x,y,z的坐标,在三维坐标系上显示具体信息 答:例如 : X=1,Y=2,Z=3; 代码就是: plot3(1,2,3,'*') grid on%加网格 ...

  7. matlab三维图像比较,matlab 画三维图像

    数学学习中,有很多地方需要画图来直观对比显示,本节记录一下用matlab画三维图形的几种方法. 例: , 1.surf.surfc.surfl surf: clear clc close all %% ...

  8. Matlab画三维立体网状图形(类似魔方)

    第一次用Matlab画这种三维立体的图形,搞了半天发现这个样例图片真的是个坑!发现选择Matlab画这种图真的是大材小用了. 样例图片: Matlab中有很多绘制三维立体图形的函数,搜了很多资料之后发 ...

  9. matlab 画三维花瓶,cad三维旋转命令画花瓶三维模型教程

    1.打开autoCAD,视图--前视 2.新建图层 LA--空格--新建图形图层与标注图层 3.画一个长100mm,高300mm的矩形 REV(矩形)--空格--用鼠标左键点一个,松开左键再拖一下鼠标 ...

最新文章

  1. Oracle新建用户赋只读某几张表的权限
  2. 华章数学译丛目录(2020年7月补缺更新版,共73本)
  3. 2019蓝桥杯省赛---java---A---6(完全二叉树的权值)
  4. java角度_java中角度或弧度的计算 | 学步园
  5. Go程序:演示map用法
  6. 对reids 服务器性能测试
  7. arpg网页游戏之地图(二)
  8. 现实世界的Windows Azure:采访Gizmox 研发中心的副总裁Itzik Spitzen先生
  9. SpringCloud集成分布式事务LCN (一)
  10. 大数据之Hadoop3.x模板虚拟机配置图解
  11. 《Nodejs开发加密货币》之十六:利益,魔鬼与天使的共同目标
  12. catia里画铰链_基于CATIA的汽车车门铰链设计
  13. 校验EXE文件防止软件被破解
  14. 【TFLearn和TensorFlow应用】——泰坦尼克号预测
  15. 什么是数据工程师,数据工程师主要是做什么的?
  16. PERL-5.26.1安装教程(LINUX系统)
  17. 什么是WINSXS文件夹
  18. Flink的背压问题产生原因和解决方法
  19. wordpress4.4禁用自动保存草稿和去除文章修订的方法
  20. echarts----雷达图

热门文章

  1. 编写Java程序,使用面向接口编程模拟不同动物的吼叫声
  2. Action Recognition(行为识别)
  3. 华为云ECS下安装MySQL
  4. APIView 怎么写?
  5. UML2.0包含的14种图
  6. IntelliJ IDEA JDK配置
  7. matplotlib 多子图图例显示
  8. 【机器学习】贝叶斯学习
  9. 特征工程-什么是特征工程(Kaggle微课)
  10. 生鲜电商平台多方位可行性方案,如何撬开“蓝海”