本文承接在matlab入门基础操作介绍的两篇推文之后,在matlab入门(下)中介绍了部分绘图相关的操作,本文首先做一点简单回顾,重点介绍三维图形的绘制部分。
1、基础知识
1.1 二维图形绘制
plot函数是Matlab绘制二维图形的常用函数,该函数将数组中的数据点绘连起来构成一条连续的曲线。
plot(x,y,'PropertyName',PropertyValue)
当x和y为同维数组时,分别以x和y为横纵坐标绘制曲线;
x为一维数组,y为矩阵时,y的某一维度与x维度相等,绘制多条曲线;
x和y都为矩阵时,分别以对应的x和y为横纵坐标,曲线条数与矩阵列数相等。
plot(x1,y1,x2,y2,'PropertyName',PropertyValue)
在窗口中同时绘制以x1和y1,x2和y2等分别为横纵坐标的曲线。
%plot函数绘图示例
%生成一维数组及参数数组
a = 0:0.1:1; t = 0:0.01:1;
%生成二维数组
y = sin(3*t').*exp(-t')*a;
%figure1:二维数组绘制曲线
subplot(1,2,1);plot(y);axis([0,100,0,1]);
xlabel('index');ylabel('y');title('figure1');
%figure2:一维数组和二维数组绘制曲线
subplot(1,2,2);plot(t,y);axis([0,1,0,1]);
xlabel('t');ylabel('y');title('figure2');
1.2 三维图形绘制
plot3函数是Matlab绘制三维曲线的常用函数。
Plot3(x,y,z,LineSpec,'PropertyName',PropertyValue)
如果x,y和z是同维数组(向量、矩阵),分别以对应列作为x、y和z坐标,曲线的个数等于矩阵列维。
%plot3函数绘图示例
t = 0:pi/50:10*pi;subplot(1,2,1);
plot3(sin(t),cos(t),t,'r*-');xlabel('sin(t)');
ylabel('cos(t)');zlabel('t');title('figure1:helix');
%绘制多条曲线
x = linspace(0,3*pi,200);z1 = sin(x); z2 = sin(2*x); z3 = sin(3*x);
y1 = zeros(size(x)); y2 = ones(size(x));y3 = 2*ones(size(x));
subplot(1,2,2);plot3(x,y1,z1,'r*',x,y2,z2,'bp',x,y3,z3,'mx');
xlabel('x');ylabel('y');zlabel('z');title('figure2:sin(x),sin(2x),sin(3x)');
1.3 曲面图与等值线
三维网格图相当于在x-y平面上的z坐标定义一个网格面,相邻的点通过直线连接,网格节点就是z的数据点,在Matlab中通过mesh函数实现。
mesh(z):以z矩阵的列和行的下标为x和y轴的自变量绘制网格图;
mesh(x,y,z):x和y为自变量矩阵,z为建立在x和y之上的函数矩阵;
与mesh函数相比,surf函数使曲面上的所有网格都填充了颜色,命令格式与mesh函数类似。但提供了平面阴影和插值阴影。
等值线图能够将具有相同数值的点连起来绘制相等数值的曲线或曲面,常用的MATLAB绘制等值线图函数的命令格式为:
contour(z):绘制z所表达的等值线图
coutour(z,n):参数n为所需要绘制的等值线图的数目
contour(z,v):向量v定义了等值线的数目和数值
%surf函数绘图示例
%颜色表示等值线绘图示例
x = 0:pi/20:2*pi;y = 0:pi/20:2*pi;
[X,Y] = meshgrid(x,y);Z = sin(X)+cos(Y);
subplot(1,2,1);surf(X,Y,Z);
shading interp;
subplot(1,2,2);contourf(X,Y,Z,20)
2、特殊的三维图形
2.1 三维切片图
对一个三维立体数据点集进行切片观察数据分布,可以采用matlab中的slice函数。
Slice(x,y,z,V,sx,sy,sz):绘制在三个坐标轴方向在于sx,sy和sz向量所对应的切片图,其中x,y,z,V是m*n*p的三维立体数据点集。
%绘制三维切片图
[x,y,z,v] = flow;
sx = linspace(min(min(min(x)))+1.5,max(max(max(x))),5);
sy = [1,-1]; sz = [1,-1];
slice(x,y,z,v,sx,sy,sz);
shading interp;
colormap jet;
2.2 三维向量图
为了表示某一函数曲面上各点的梯度向量,比如速度图等,我们需要在曲面图上各点绘制向量,这可以调用matlab函数quiver3()来实现。
quiver3(x,y,z,u,v,w):在位置(x,y,z)处绘制元素(u,v,w)的向量图。
%三维向量图示例
x = 0:pi/10:2*pi;y = 0:pi/10:2*pi;
[X,Y] = meshgrid(x,y);Z = sin(X)+cos(Y);
[u,v,w] = surfnorm(X,Y,Z);
colormap hsv;
surf(X,Y,Z);
hold on
quiver3(X,Y,Z,u,v,w,0.5)
axis([0,2*pi,0,2*pi])
2.3 三维等值线
在matlab中绘制三维等值线可以调用contour3函数,调用格式类似于二维等值线的绘制。
contour3(Z):绘制矩阵Z的三维等值线;
contour3(Z,n):绘制具有n条矩阵Z的三维等值线;
contour3(Z,v):在参数v上绘制矩阵Z的三维等值线,等值线数量等于数组v的长度。
x = 0:pi/20:2*pi;
y = 0:pi/20:2*pi;
[X,Y] = meshgrid(x,y);
Z = sin(X)+cos(Y);
contour3(X,Y,Z,30)
xlabel('X');ylabel('Y');zlabel('Z');
title('三维等值线图');
2.4 三维柱状图
在matlab中绘制三维柱状图可以调用bar3函数来实现,其调用格式为:
bar3(Y):绘制矩阵Y的三维柱状图,矩阵每一行元素代表图形中一排柱形图;
bar3(x,Y,width):在参数向量x的指定位置绘制矩阵Y的三维柱状图,width参数可省,控制柱形图的宽度。
Y = 10*rand(5,5);
x = 0:2.5:10;
bar3(x,Y,0.6);
2.5 三维饼图
在matlab中绘制三维饼图需要调用pie3函数,类似于二维饼图绘制,其函数调用格式为:
pie3(X):当X为向量时,三维饼状图表示每个元素占所有元素之和的比例,当X为矩阵时,表示每个元素占矩阵全部元素和的比例;
pie3(X,explode,labels):其中explode参数与X维度相同,表示是否将对应的扇形区域单独表示,例如explode取值为[0,0,0,1]表示将第四个元素对应的扇形区域单独表示,labels表示重新标注每个扇形区域名称。
3、小试牛刀
在今年情人节的推文中,展示了一张用matlab做的明信片,我们就以此为例,熟悉一下matlab的绘图命令。
在这张明信片中,文字部分可以用text函数添加,重点需要做的是右侧的树。
在这棵树中,树干部分采用了原始图像中的树干,树叶采用一个心形线函数进行填充,树冠轮廓用一个心形线进行约束,确保所有树叶都在树冠轮廓内,所有树叶可以组成一个心形图。
Step1:导入树干图像,同时提取树干轮廓数据备用;
%读取树干图像
im = imread('tree.jpg');
%提取树干轮廓
A = rgb2gray(I);
se1=strel('disk',2);
A2=imerode(A,se1);
bw = im2bw(A2);
contour = bwperim(bw);
Step2:根据树干,确定树冠轮廓线位置和树冠大小;
h = ezplot('x^2-1.3*abs(x)*y+y^2-1');
data=get(h, 'contourMatrix');
data = data(:,2:end);
theta = 1.04*pi;
data = data'*[cos(theta),-sin(theta);
sin(theta),cos(theta)];
X=50*data(:,1) + 300;
Y=50*data(:,2) + 75;
通过心形线生成的树冠轮廓中心在原点处,我们需要对心形线上各点进行旋转和平移,其中旋转操作可以通过矩阵运算来实现;
上式表示,将点(X,Y)逆时针旋转角度theta。缩放可以对坐标乘上一个合适的系数,同理对坐标加或减某一个单位长度,即可完成对坐标的平移。
Step3:绘制树叶,在原点处绘制心形线,并通过fill函数进行随机的颜色填充;
function [] = show_heart(x,y,color)
%绘制心形线
h = ezplot('x^2-1.4*abs(x)*y+y^2-1');
set(h,'color','w');
hold on
%抓取轮廓数据
heart = get(h, 'contourMatrix');
heart = heart(:,2:end);
%将树叶轮廓点进行旋转和平移
theta = 2*rand()*pi;
heart = heart'*[cos(theta),-sin(theta);
sin(theta),cos(theta)];
heart=3*heart;
heart(:,1) = heart(:,1) + x;
heart(:,2) = heart(:,2) + y;
%对树叶进行颜色填充
h = fill(heart(:,1),heart(:,2),[color(1)/255,color(2)/255,color(3)/255]);
set(h,{'LineStyle'},{'none'})
end
Step4:在树冠区域内随机选择一些位置,作为树叶中心点,同时确保选中的位置树干轮廓线内;
%在树冠轮廓内和树干轮廓外随机添加树叶
for x = min(X):6:max(X)
for y = min(Y):6:max(Y)
if rand() > 0.25
if inpolygon(x,y,X,Y) && (~inpolygon(x,y,XX,YY))
index = sum((rand() - heart_rand)>=0);
hold on
show_heart(x,y,heart_color(index,:));
end
end
end
end
以上,就可以完成这颗心形树的绘制,完整代码可以在公众号后台回复【明信片】获取。
相关推文
MATLAB入门(上)
MATLAB入门(下)