matlab的三维图绘制

本章节主要以代码为主

-----引言

代码一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
%% mesh函数:绘制出在某一区间内完整的网格图

%% mesh(X,Y,Z)的用法,其中X是n维向量,Y是m维向量,Z是m*n维的矩阵
X = [1,2,4]
Y = [3,5]
Z = [4,8,10;5,9,13]
mesh(X,Y,Z) % (X(j), Y(i), Z(i,j))是线框网格线的交点的坐标
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签
% 三维旋转和数据游标的使用,以及X-Y视图的切换(在三维旋转状态下点击鼠标右键)
% 数据游标默认只能添加一个,按住Alt键不动,可以添加多个数据游标
% 插入颜色栏,可显示色阶

%% mesh(Z)的用法,其中Z是m*n维的矩阵
Z = [4,8,10;5,9,13]
mesh(Z)
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签
% 等价于
X = 1:3
Y = 1:2
Z = [4,8,10;5,9,13]
mesh(X,Y,Z)
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签

%% 思考:如果X中元素不是按照从小到大排序的,图像会是什么样子?
X = [1,10,4]
Y = [3,5]
Z = [4,8,10;5,9,13]
mesh(X,Y,Z)
hidden off % 可以看到背部的图像,不会遮挡(默认是看不到的)
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签
% 如果觉得背部的图像显示的颜色太深了,可以更改透明度
mesh(X,Y,Z)
alpha(0.8) % 设置透明度为0.8,这时候隐隐约约能看到(透明度介于0-1之间,越大表示越透明)
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签

%% mesh(X,Y,Z)的用法,其中X、Y和Z都是m*n维的矩阵
X = [1,2,4;1,2,4]
% X = [1,2,4;1,2,5]
Y = [3,3,3;5,5,5]
Z = [4,8,10;5,9,13]
mesh(X,Y,Z) % (X(i,j), Y(i,j), Z(i,j))是线框网格线的交点的坐标
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签

%% 例题1:绘制 z = x^2 - y^2的图像 ,其中x和y都位于[0,5]之间
% linspace是Matlab中的一个函数,用于产生给定范围内指定数量的点数,相邻数据跨度相同,并返回一个行向量。
% 调用方法:linspace(x1,x2,N)
% 功能:用于产生x1,x2之间的N点行向量,相邻数据跨度相同。其中x1、x2、N分别为起始值、终止值、元素个数。
n = 11;
tem = linspace(0,5,n); % 将[0,5]这个区间等分为n个点(等差数列的形式)
x = repmat(tem,n,1);
y = repmat(tem',1,n);
z = x.^2 - y.^2; % 要使用点运算符号哦~
mesh(x,y,z)
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签
axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示



%% 例题2: 绘制 z = sin(sqrt(x^2+y^2))/sqrt(x^2+y^2) 的图形,其中x和y都位于[-5,5]之间
[x,y] = meshgrid(-5:0.5:5); % 快速生成网格所需的数据
tem = sqrt(x.^2+y.^2)+1e-12; % tem=sqrt(x.^2+y.^2); % 在后面加上一个非常非常小的数字: 1e-12 = 10^(-12) ,当然你也可以单独找到值为0的地方对其修改
z = sin(tem)./tem; % 如果不对tem处理,那么z的最中间的一个值 0/0 = NaN
mesh(x,y,z)
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签
axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示

%% meshc函数:除了mesh函数图形外,还在xy平面上绘制曲面的等高线
meshc(x,y,z)
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签
axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示

%% meshz函数:除了mesh函数图形外,还在xy平面上绘制曲面的底座
meshz(x,y,z)
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签
axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示

例题一

  1. n = 11;: 将变量 n 的值设为11。

  2. tem = linspace(0,5,n);: 生成一个包含n个在0和5之间等间距点的行向量 tem。函数 linspace 用于创建线性间隔的向量。

  3. x = repmat(tem,n,1);: 通过在行方向(重复n次)和列方向(重复1次)复制向量 tem,创建矩阵 x。这形成一个矩阵,其中每一行都是向量 tem 的副本。

  4. y = repmat(tem',1,n);: 类似于第3行,通过在行方向(重复1次)和列方向(重复n次)复制向量 tem 的转置,创建矩阵 y。这形成一个矩阵,其中每一列都是转置向量 tem 的副本。

  5. z = x.^2 - y.^2;: 对矩阵 xy 进行逐元素运算。z 的每个元素计算为相应的 x 元素的平方减去相应的 y 元素的平方。

  6. mesh(x,y,z): 使用矩阵 xyz 中的值创建一个3D网格图。这将表示函数 z = x^2 - y^2 的曲面图。

  7. xlabel('x轴'); ylabel('y轴'); zlabel('z轴');: 为图的x轴、y轴和z轴添加标签。

  8. axis vis3d: 将图的三个维度的纵横比设置为相等,使图在视觉上更加准确。这对于3D图来说尤为重要,以避免失真。

总之,该代码在指定范围内使用由 xy 定义的网格,生成函数 z = x^2 - y^2 的3D曲面图。然后,图被标注为x轴、y轴和z轴的标签。

代码二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
%% surf函数:绘制出在某一区间内完整的曲面图
% surf函数和mesh函数的的调用格式基本相同
% 两者的区别: mesh绘出彩色的线,surf绘出彩色的面

%% 例题1的对比
[x,y] = meshgrid(linspace(0,5,11));
% [x,y] = meshgrid([0:0.5:5]); 或者直接写成[x,y] = meshgrid(0:0.5:5);
z = x.^2 - y.^2;
subplot(1,2,1) % subplot(m,n,index)
mesh(x,y,z)
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签
axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示
title('mesh(x,y,z)')

subplot(1,2,2)
surf(x,y,z)
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签
axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示
% axis([0,5,0,5,-inf,+inf]) % 设置坐标轴刻度范围
title('surf(x,y,z)')

%% 例题2的对比
[x,y] = meshgrid(-5:0.5:5); % 快速生成网格所需的数据
tem = sqrt(x.^2+y.^2)+1e-12;
z = sin(tem)./tem; % 如果不对tem处理,那么z的最中间的一个值 0/0 = NaN
subplot(1,2,1)
mesh(x,y,z)
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签
axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示
title('mesh(x,y,z)')

subplot(1,2,2)
surf(x,y,z) % (X(j), Y(i), Z(i,j))是线框网格线的交点
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签
axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示
title('surf(x,y,z)')

%% surfc函数:除了surf函数图形外,还在xy平面上绘制曲面的等高线
surfc(x,y,z)
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签
axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示

%% surfl函数:加上了灯光效果,看起来自然点
surfl(x,y,z)
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签
axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示

%% 设置色彩模式
% shading 是用来处理色彩效果的,分以下三种:
% shading faceted是默认的模式
% shading flat 在faceted的基础上去掉图上的网格线
% shading interp 在flat的基础上进行色彩的插值处理,使色彩平滑过渡
subplot(1,3,1)
surf(x,y,z) % (X(j), Y(i), Z(i,j))是线框网格线的交点
shading faceted % 默认的色彩模式
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签
axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示
title('shading faceted')

subplot(1,3,2)
surf(x,y,z) % (X(j), Y(i), Z(i,j))是线框网格线的交点
shading flat % 看起来光滑一点
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签
axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示
title('shading flat')

subplot(1,3,3)
surf(x,y,z) % (X(j), Y(i), Z(i,j))是线框网格线的交点
shading interp % 看起来最光滑
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签
axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示
title('shading interp')

subplot(m, n, index) 是 MATLAB 中用于创建多个子图的函数,其中:

  • m 表示子图布局的行数(即总行数)。
  • n 表示子图布局的列数(即总列数)。
  • index 表示当前子图的索引,从左上角开始按行从左到右的顺序编号。

在你提供的例子中,subplot(1,2,1) 表示将当前图形划分为1行2列的子图布局,并且当前绘图将位于第1个(左侧)子图位置。这意味着在当前图形中,你可以绘制两个子图,而当前命令将设置绘图环境为左侧的第一个子图,以便在此子图中进行绘图。

例如,你可以使用以下代码在两个子图中绘制不同的图形:

1
2
3
4
5
subplot(1,2,1)
% 在第一个子图中绘制图形

subplot(1,2,2)
% 在第二个子图中绘制另一个图形

这样可以方便地将多个相关的图形进行比较,而不必为每个图形创建一个新的图形窗口。

代码三

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
%% contour函数: 绘制等高线图

[x,y] = meshgrid(-3:0.1:3);
% 一个语句太长时,可以加上三个点然后在下一行继续写
z = 3*(1-x).^2.*exp(-(x.^2) - (y+1).^2)...
-10* (x/5 - x.^3 - y.^5).*exp(-x.^2-y.^2) ...
- 1/3*exp(-(x+1).^2 - y.^2); % matlab中内置的peaks函数,常常作为演示使用
% edit peaks

%% contour(x,y,z) 在x-y平面绘制等高线图,Matlab会自动选择等高线的层级
contour(x,y,z)
xlabel('x轴'); ylabel('y轴'); % 加上坐标轴的标签

%% contour(x,y,z,n) 在x-y平面绘制等高线图,n是一个标量,那么Matlab会将等高线的层数设置为n,且会自动选择层所在的高度。
contour(x,y,z,5)
contour(x,y,z,5,'LineWidth',2) % 设置线的宽度为2
contour(x,y,z,5,'--') % 设置等高线为虚线
contour(x,y,z,5,'ShowText','on') % 显示每一层的高度
contour(x,y,z,5,'--','ShowText','on','LineWidth',2) % 可以组合起来使用
colorbar % 显示颜色栏,也可以手动插入
xlabel('x轴'); ylabel('y轴'); % 加上坐标轴的标签

%% contour(x,y,z,levels) 若想得到固定的n个高度的等高线,将levels可以设置为n元行向量,其中向量中的值为高度值。
maxz = max(max(z))
minz = min(min(z))
levels = linspace(minz,maxz,10) % 从最小值到最大值,等分成10个点
contour(x,y,z,levels,'ShowText','on','LineWidth',1) % 最小值或者最大值可能显示不出来,因为Matlab会帮我们自动调整
xlabel('x轴'); ylabel('y轴'); % 加上坐标轴的标签

% 思考如果只想画出高度为3的单等高线怎么办?
contour(x,y,z,[3 3],'ShowText','on')
xlabel('x轴'); ylabel('y轴'); % 加上坐标轴的标签

%% contourf函数:和contour函数类似,只不过画出来的等高线图有颜色填充
contourf(x,y,z,levels,'ShowText','on')
xlabel('x轴'); ylabel('y轴'); % 加上坐标轴的标签

%% contour3函数:3维等高线图,等高线不再投影到x-y平面
contour3(x,y,z,levels,'ShowText','on')
xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签


代码四

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
%% 符号函数的三维图形绘制
clear;clc

%% plot3函数 (类似于plot函数,实际上可以认为画的是三维空间下的折线图)
% t = 0: 0.1: 4*pi; % 符号是t,t从0变动到4pi,间隔设置为0.1
t = linspace(0,4*pi,100); % 符号是t,t从0变动到4pi,等分为100个点
x = sin(t)+1; % 利用t计算x的值
y = cos(t); % 利用t计算y的值
z = t; % 利用t计算z的值
plot3(x,y,z) % 绘制三维空间下的折线图
plot3(x,y,z,'r--')
% close % 关闭图形

%% fplot3函数 (2016a版本推出的函数,老版本Matlab用的是ezplot3函数,未来版本可能会被淘汰)
syms t % 符号是t
x = sin(t)+1;
y = cos(t);
z = t;
fplot3(x,y,z) % 默认t的变化范围为[-5 5]
fplot3(x,y,z,[0 4*pi]) % 修改t的变化范围为0至4pi
% close % 关闭图形

%% fmesh 三维网格图 (2016a版本推出的函数,老版本Matlab用的是ezmesh函数,未来版本可能会被淘汰)
syms x y
z=x^2+y^2;
fmesh(z) % 默认x的变化范围和y的变化范围都是[-5 5]
fmesh(z,[-2 2 -4 4]) % 修改x的变化范围和y的变化范围分别为[-2 2]和[-4 4]
% axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示
% axis equal % 设置屏幕高宽比,使得每个坐标轴的具有均匀的刻度间隔
fmesh(z,[-2 2 -4 4],'MeshDensity',11) % 设置每个方向计算的点数

% 画一朵花花送给亲爱的Ta
syms u v
r = 2 + sin(7.*u + 5.*v);
x = r.*cos(u).*sin(v);
y = r.*sin(u).*sin(v);
z = r.*cos(v);
% 可以直接用乘号
% r = 2 + sin(7*u + 5*v);
% x = r*cos(u)*sin(v);
% y = r*sin(u)*sin(v);
% z = r*cos(v);
fmesh(x,y,z,[0 2*pi 0 pi])
alpha(0.8)

%% fsurf 三维曲面图 (2016a版本推出的函数,老版本Matlab用的是ezsurf函数,未来版本可能会被淘汰)
syms x y
z=x^2+y^2;
fsurf(z) % 默认x的变化范围和y的变化范围都是[-5 5]
fsurf(z,[-2 2 -4 4]) % 修改x的变化范围和y的变化范围分别为[-2 2]和[-4 4]
% axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示
% axis equal % 设置屏幕高宽比,使得每个坐标轴的具有均匀的刻度间隔
fsurf(z,[-2 2 -4 4],'MeshDensity',11) % 设置每个方向计算的点数

% 画一朵花花送给亲爱的Ta
syms u v
r = 2 + sin(7.*u + 5.*v);
x = r.*cos(u).*sin(v);
y = r.*sin(u).*sin(v);
z = r.*cos(v);
fsurf(x,y,z,[0 2*pi 0 pi])

%% fcontour 绘制等高线 (2016a版本推出的函数,老版本Matlab用的是ezcontour函数,未来版本可能会被淘汰)
syms x y
z=x^2+y^2;
fcontour(z) % 默认x的变化范围和y的变化范围都是[-5 5]
fcontour(z,[-2 2 -4 4]) % 修改x的变化范围和y的变化范围分别为[-2 2]和[-4 4]
fcontour(z,'fill','on') % 在等高线线条间进行填充