第十八章三维图形 为了显示三维图形, MATLAB提供了各种各样的函数。有一些函数可在三维空 间中画线,而另一些可以画曲面与线格框架。另外,颜色可以用来代表第四维。当 颜色以这种方式使用时,由于它不再象照片中那样显示信息的自然属性-色彩,而 且也不是基本数据的内在属性,所以它称作伪彩色。为了简化对三维图形的讨论 对颜色的介绍推迟到下一章。在这一章,主要讨论绘制三维图形的基本概念。 18.1函数p|ot3 plot3命令将绘制二维图形的函数plot的特性扩展到三维空间。函数格式除了包 括第三维的信息(比如Z方向)之外,与二维函数plot相同。plot3一般语法调用 格式是plot3(x1y1,z1,S1,x2,y2,z2S2…),这里xnyn和是向量或矩阵,Sn是可选的字 符串,用来指定颜色、标记符号和或线形。 总的来说,pot3可用来画一个单变量的三维函数。如下为一个三维螺旋线例子: t=0pi50:10*pi; >)plot(sin(t), cos(t), t) ttl( Helix‘) xlabel(‘sint(t') ylabel(‘cos(t)), zlabel(‘t >)text(0,0,0, Origin') grid ))v-axIs 输出见图181
第十八章 三维图形 为了显示三维图形,MATLAB 提供了各种各样的函数。有一些函数可在三维空 间中画线,而另一些可以画曲面与线格框架。另外,颜色可以用来代表第四维。当 颜色以这种方式使用时,由于它不再象照片中那样显示信息的自然属性----色彩,而 且也不是基本数据的内在属性,所以它称作伪彩色。为了简化对三维图形的讨论, 对颜色的介绍推迟到下一章。在这一章,主要讨论绘制三维图形的基本概念。 18.1 函数 plot3 plot3 命令将绘制二维图形的函数 plot 的特性扩展到三维空间。函数格式除了包 括第三维的信息(比如 Z 方向)之外,与二维函数 plot 相同。plot3 一般语法调用 格式是 plot3(x1,y1,z1,S1,x2,y2,z2,S2,…),这里 xn,yn 和 zn 是向量或矩阵,Sn 是可选的字 符串,用来指定颜色、标记符号和/或线形。 总的来说,plot3 可用来画一个单变量的三维函数。如下为一个三维螺旋线例子: » t=0:pi/50:10*pi; » plot3(sin(t),cos(t),t) » title( ‘ Helix ‘ ),xlabel( ‘ sint(t) ‘ ),ylabel( ‘ cos(t) ‘ ),zlabel( ‘ t ‘ ) » text(0,0,0, ‘ Origin ‘ ) » grid » v = axis v = -1 1 -1 1 0 40 输出见图 18.1
40 20 10 05 05 -0.5 -0.5 cos(t) 图18.1螺旋线图 从上例可明显看出,二维图形的所有基本特性在三维中仍都存在。axis命令扩 展到三维 只是返回Z轴界限(0和40),在数轴向量中增加两个元素。函数 zlabel用来指定 z轴的数据名称,函数grid在图底绘制三维网格。函数 test(x,y,z," string")在由三 维坐标x,y,所指定的位置放一个字符串。另外,子图和多图形窗口可以直接应用到 三维图形中 在最后一章可以看到,通过指定plot命令的多个参量或使用hold命令,可以把 多条直线或曲线重叠画出。plot3以及其它的三维图形函数都可以提供相同的能力 例如,增加维数的plot命令可以使多个二维图形沿一个轴排列起来,而不是直接 将二维图形叠到另一个的上面 >)x=linspace(0, 3pi); % X-axis data >)ZI=sin(x); plot in x-z plane ) >)y1=zeros(size(x)); spread out along y-axis ))y3=zeros(size(x)); by giving each diffent y-axis valu y2=3/2
图 18.1 螺旋线图 从上例可明显看出,二维图形的所有基本特性在三维中仍都存在。axis 命令扩 展到三维 只是返回 Z 轴界限(0 和 40),在数轴向量中增加两个元素。函数 zlabel 用来指定 z 轴的数据名称,函数 grid 在图底绘制三维网格。函数 test(x,y,z, ‘ string ‘ )在由三 维坐标 x,y,z 所指定的位置放一个字符串。另外,子图和多图形窗口可以直接应用到 三维图形中。 在最后一章可以看到,通过指定 plot 命令的多个参量或使用 hold 命令,可以把 多条直线或曲线重叠画出。plot3 以及其它的三维图形函数都可以提供相同的能力。 例如,增加维数的 plot3 命令可以使多个二维图形沿一个轴排列起来,而不是直接 将二维图形叠到另一个的上面。 » x=linspace(0,3*pi); % x-axis data » z1=sin(x); % plot in x-z plane » z2=sin(2*x); » z3=sin(3*x); » y1=zeros(size(x)); % spread out along y-axis » y3=zeros(size(x)); % by giving each diffent y-axis values » y2=y3/2;
>)plot(x,yl, zl, x, y2, Z2, x, y3, z3); >) grid, xlabel( X-axis), ylabel('y-axis, abel( z-axis) itle( sin(x), sin(2 x), sin(3x)') 输出见图182 sin(x), sin(2x),sin(3x) 0.5 -05 0.5 -0.5 图182正弦曲线图 上述图形也可以沿另外方向堆列。 >)plot(x, zl,yl, x, Z2, y2, x, Z3, y3) >)grid, xlabel(X-axis, ylabel( y-axis), zlabel( ' Z-axis) title(‘sin(x)sin(2x),sin(3x)‘) 输出见图18.3
» plot3(x,y1,z1,x,y2,z2,x,y3,z3); » grid,xlabel( ‘ x-axis ‘ ),ylabel( ‘ y-axis ‘ ,abel( ‘ z-axis ‘ ) » title( ‘ sin(x),sin(2x),sin(3x) ‘ ) 输出见图 18.2. 图 18.2 正弦曲线图 上述图形也可以沿另外方向堆列。 » plot3(x,z1,y1,x,z2,y2,x,z3,y3) » grid,xlabel( ‘ x-axis ‘ ,ylabel( ‘ y-axis ‘ ),zlabel( ‘ z-axis ‘ ) » title( ‘ sin(x),sin(2x),sin(3x) ‘ ) 输出见图 18.3
in(x) sin(2x), sin(x) 0.5 0 0.5 -0.5 图183正弦曲线图 18.2改变视角 注意两个图形,一个是以30度视角向下看z=0平面,一个是以37.5度视角向上 看x=0平面。这是对所有三维图形的缺省视角。与z=0平面所成的方向角叫仰角, 与x=0平面的夹角叫做方位角。这样,缺省的三维视角方向仰角为30度,方位角 为-37.5度。而缺省的二维视角仰角为90度,方位角为0度。仰角和方位角的概念 在图184中形象地画出
图 18.3 正弦曲线图 18.2 改变视角 注意两个图形,一个是以 30 度视角向下看 z=0 平面,一个是以 37.5 度视角向上 看 x=0 平面。这是对所有三维图形的缺省视角。与 z=0 平面所成的方向角叫仰角, 与 x=0 平面的夹角叫做方位角。这样,缺省的三维视角方向仰角为 30 度,方位角 为-37.5 度。而缺省的二维视角仰角为 90 度,方位角为 0 度。仰角和方位角的概念 在图 18.4 中形象地画出
图184仰角和方位角示意图 Default Az =-37,5.E1 30 Az Rotated to 52.5 05 10 05 Y-axis 00 x-axis X-axis 100 Y-axis E1 Increased to 60 Az=0E1=90 05 5 图18.5视角举例图
图 18.4 仰角和方位角示意图 图 18.5 视角举例图
在 MATLAB中,函数view改变所有类型的二维和三维图形的图形视角 view(az,e和view(aze将视角改变到所指定的方位角az和仰角el。考虑下面脚本 M文件形式的例子。 viewpoint example using subplots xlinspace(0, 3 pi) z=Isin(x) sin(2*x) sin(2 x)I create y and Z axes as matrices Y=zeros(size(x)) ones(size(x))2 ones(size(x)) subplot(2, 2, 1) lot3(x,, z)% plot works with column-oriented matrices too grd, alabel(x-axis) ylabel(Y-axis‘) alabel(‘Z-axis‘) title( Default Az=-37.5, El=30) iew(-37.5,30) subplot(2, 2, 2) plot(x,Y, 4) grid, xlabel(X-axis) ylabel(‘Y-axis‘), zlabel(‘Z-axis‘) title( az rotated to 52.5) vew(-37.5+90,30) subplot(2, 2, 3) plot(x,Y, Z grid, Xlabel(x-axis‘) ylabel(Y-axis"), zlabel(‘ Z-axis‘) title( el increased to 60) view(-37.5,60) plot(x,Y, Z) grid, xlabel( X-axis), ylabel('Y-axis ') title( Az=0,El=90) w(090)
在 MATLAB 中,函数 view 改变所有类型的二维和三维图形的图形视角。 view(az,el)和 view([az,el)]将视角改变到所指定的方位角 az 和仰角 el。考虑下面脚本 M 文件形式的例子。 % viewpoint example using subplots x=linspace(0,3*pi).’; Z=[sin(x) sin(2*x) sin(2*x)]; % create Y and Z axes as matrices Y=[zeros(size(x)) ones(size(x))/2 ones(size(x))]; subplot(2,2,1) plot3(x,Y,Z) % plot3 works with column-oriented matrices too grid,xlabel( ‘ X-axis ‘ ),ylabel( ‘ Y-axis ‘ ),zlabel( ‘ Z-axis ‘ ) title( ‘ Default Az = -37.5,E1 = 30 ‘ ) view(-37.5,30) subplot(2,2,2) plot3(x,Y,Z) grid,xlabel( ‘ X-axis ‘ ),ylabel( ‘ Y-axis ‘ ),zlabel( ‘ Z-axis ‘ ) title( ‘ Az Rotated to 52.5 ‘ ) view(-37.5+90,30) subplot(2,2,3) plot3(x,Y,Z) grid,xlabel( ‘ X-axis ‘ ),ylabel( ‘ Y-axis ‘ ),zlabel( ‘ Z-axis ‘ ) title( ‘ E1 Increased to 60 ‘ ) view(-37.5,60) subplot(2,2,4) plot3(x,Y,Z) grid,xlabel( ‘ X-axis ‘ ),ylabel( ‘ Y-axis ‘ ) title( ‘ Az = 0,E1 = 90 ‘ ) view(0,90)
输出见图185。 除了上面的形式,view还提供了综合在表18.1的其它特性: 表181 函数view view(az, el) 将视图设定为方位角a和仰角el view(laz, elD view(x, y, z 在笛卡儿坐标系中将视图设为沿向量Ix,y,z指向原点,例如 view(00 ID=view(0, 90) view(2) 设置缺省的二维视角,az=0,ek90 设置缺省的三维视角,az=-37.5,e=30 laz, ell=view 返回当前的方位角az和仰角el view( 用一个4×4的转矩阵T来设置视图角 T=view 返回当前的4×4转矩阵 最后,为了演示 MATLAB句柄图形能力,精通 MATLAB工具箱包含了函数 mmview3d。在产生二维或三维图形后调用此函数,) mmview3d,在当前图形中放 置水平角和方位角滑标(滚动条)以设置视角。使用函数 mmview3d的更详细的信 息见在线帮助。 18.3两个变量的标量函数 相对于plot3产生的线条图形,经常希望画出两个变量的标量函数,比如 z=f(x,y) 这里每一对x与y的值产生一个z的值。它作为x与y的函数,是三维空间中的 个曲面。为了在 MATLAB里画出这个曲面,z的值存放在一个矩阵中。象在**二维 插值这一节所描述的那样,给出x与y的值作为独立的变量,z是因变量矩阵,x y与z的联系就是 z(i,: Ff(x,y() and z(=f(xo,y) 即z的第i行与的y第i个元素相关,而z的第j列与x的第个j元素相关。或者说
输出见图 18.5。 除了上面的形式,view 还提供了综合在表 18.1 的其它特性: 表 18.1 函数 view view(az,el) 将视图设定为方位角 az 和仰角 el view([az,el]) view([x,y,z]) 在笛卡儿坐标系中将视图设为沿向量[x,y,z]指向原点,例如 view([0 0 1])=view(0,90) view(2) 设置缺省的二维视角,az=0,el=90 view(3) 设置缺省的三维视角,az=-37.5,el=30 [az,el]=view 返回当前的方位角 az 和仰角 el view(T) 用一个 4×4 的转矩阵 T 来设置视图角 T=view 返回当前的 4×4 转矩阵 最后,为了演示 MATLAB 句柄图形能力,精通 MATLAB 工具箱包含了函数 mmview3d。在产生二维或三维图形后调用此函数,» mmview3d,在当前图形中放 置水平角和方位角滑标(滚动条)以设置视角。使用函数 mmview3d 的更详细的信 息见在线帮助。 18.3 两个变量的标量函数 相对于 plot3 产生的线条图形,经常希望画出两个变量的标量函数,比如: z=f(x,y) 这里每一对 x 与 y 的值产生一个 z 的值。它作为 x 与 y 的函数,是三维空间中的一 个曲面。为了在 MATLAB 里画出这个曲面,z 的值存放在一个矩阵中。象在**二维 插值这一节所描述的那样,给出 x 与 y 的值作为独立的变量,z 是因变量矩阵,x、 y 与 z 的联系就是: z(i,:)=f(x,y(i)) and z(:,j)=f(x(j),y) 即 z 的第 i 行与的 y 第 i 个元素相关,而 z 的第 j 列与 x 的第个 j 元素相关。或者说
y沿着z的列变化,而x沿着z的行变化。 当z=f(xy)能简化表示时,可以方便地用数组运算在单个语句中算出z的所有的 值。这样做,要求我们以合适的方向创建所有ⅹ与y值的矩阵。(这种方向有时被 Mathwork公司称作为方格)。 MATLAB提供了函数 meshgrid来执行这个步骤 ))x=-3: 3: choose x-axisd values >)y=1: 5; %y-axis values 区X,Y]= meshgrid(xy) 000 0 22222 2345 2345 2345 3333312345 4 如上所见,函数 meshgrid对y中行的每一行复制x,同样也对x中列的每一列 复制y。这种方向与前面语句相一致,即y向下改变其列,而x横跨改变其行。给 定X和Y,如果z=f(xy)=(x+y},那么z便定义一个三维曲面的数据矩阵 Z=(X+Y)^2 0 496 16 123 9162: 3649 4964 当函数不能象上面那样简单表示出来时,便只能用For循环或 While循环 来计算Z的元素。在很多情况下,有可能按行或按列计算Z。例如,如果能按行计 算Z,下面的脚本文件段会很有帮助:
y 沿着 z 的列变化,而 x 沿着 z 的行变化。 当 z=f(x,y)能简化表示时,可以方便地用数组运算在单个语句中算出 z 的所有的 值。这样做,要求我们以合适的方向创建所有 x 与 y 值的矩阵。(这种方向有时被 Mathwork 公司称作为方格)。MATLAB 提供了函数 meshgrid 来执行这个步骤。 » x=-3:3; % choose x-axisd values » y=1:5; % y-axis values » [X,Y]=meshgrid(x,y) X = -3 -2 -1 0 1 2 3 -3 -2 -1 0 1 2 3 -3 -2 -1 0 1 2 3 -3 -2 -1 0 1 2 3 -3 -2 -1 0 1 2 3 Y = 1 1 1 1 1 1 1 2 2 2 2 2 2 2 3 3 3 3 3 3 3 4 4 4 4 4 4 4 5 5 5 5 5 5 5 如上所见,函数 meshgrid 对 y 中行的每一行复制 x,同样也对 x 中列的每一列 复制 y。这种方向与前面语句相一致,即 y 向下改变其列,而 x 横跨改变其行。给 定 X 和 Y,如果 z=f(x,y)=(x+y)2,那么 z 便定义一个三维曲面的数据矩阵: » Z=(X+Y).^2 Z = 4 1 0 1 4 9 16 1 0 1 4 9 16 25 0 1 4 9 16 25 36 1 4 9 16 25 36 49 4 9 16 25 36 49 64 当函数不能象上面那样简单表示出来时,便只能用 For 循环或 While 循环 来计算 Z 的元素。在很多情况下,有可能按行或按列计算 Z。例如,如果能按行计 算 Z,下面的脚本文件段会很有帮助:
x=??? statement defining vector of x-axis values y=??? statement defining vector of y-axis values nxlength(x); length of x is no of rows in Z ny=length(y); length of y is no of columns in Z Z=zeros(nx, ny); initialize Z matrix for speed nds, Z(r, Ffa function of y and x(r) defining r-th row of Z) 相反,如果能按列计算Z,下面的脚本文件段会很有帮助: -?? statement defining vector of x-axis values y=??? statement defining vector of y-axis values Length(x); length of x is no of rows in Z ny=length(y); length of y is no of columns in Z Z=zeros(nx, ny); initialize Z matrix for speed for c=l:ny d preliminary commands, Z(, cF(a function of y(c)and x defining c-th column ofZ) end 只有当Z中的元素必须一个一个地计算时,就常常要求象下面的脚本文件一样, 用嵌套循环进行计算。 x=??? statement defining vector of x-axis values y=??? %statement defining vector of y-axis values length (x); length of x is no of rows in Z ny=length(y); length of y is no of columns in Z Z=zeros(nx, ny); initialize Z matrix for speed
x=??? % statement defining vector of x-axis values y=??? % statement defining vector of y-axis values nx=length(x); % length of x is no. of rows in Z ny=length(y); % length of y is no. of columns in Z Z=zeros(nx,ny); % initialize Z matrix for speed for r=1:nx {preliminary commands} Z(r,:)={a function of y and x(r) defining r-th row of Z} end 相反,如果能按列计算 Z,下面的脚本文件段会很有帮助: x=??? % statement defining vector of x-axis values y=??? % statement defining vector of y-axis values nx=length(x); % length of x is no. of rows in Z ny=length(y); % length of y is no. of columns in Z Z=zeros(nx,ny); % initialize Z matrix for speed for c=1:ny {preliminary commands} Z(:,c)={a function of y(c) and x defining c-th column of Z} end 只有当 Z 中的元素必须一个一个地计算时,就常常要求象下面的脚本文件一样, 用嵌套循环进行计算。 x=??? % statement defining vector of x-axis values y=??? % statement defining vector of y-axis values nx=length(x); % length of x is no. of rows in Z ny=length(y); % length of y is no. of columns in Z Z=zeros(nx,ny); % initialize Z matrix for speed
form dpreliminary commands) Z(r, cfa function of y(c) and x(r)defining Z(r, c)) 18.4杂乱或散射数据的插值 在有些情况下,两个变量的标量函数的值,如z=f(xy),不能简单地算出。这是 因为要么ⅹ和y的值是非均匀间隔的(最坏时是随机分布),要么是用了不同的坐 标系,比如非长方形的网格。出现这些情况时, MATLAB中的函数 griddata就用 来产生经插值后的均匀间隔数据以作图。首先考虑前面的例子。假设要求较高的分 辨率,但我们不想重新计算函数来得到新值。 >)X-3: 3: original x-axis values >)y=1: 5; original y-axis values 》区X,Y]= meshgrid(xy),% >)Z=(X+Y). 2 original z values >)size(z) original array size 7 >)XF-3: 5: 4; interpolated x-axis values >> length(xi) get new x-axis length ans ))yi0: 2: 5: interpolated y-axis values >) length(yi) get new y-axis length ans 26 》区XY= meshgrid(xiyi);% make new data plaid ))Zigriddata(X,Y, Z, Xi, Yi); interpolated Z data using original data >)size(zi interpolated size is correct
for r=1:nx for c=1:ny {preliminary commands} Z(r,c)={a function of y(c) and x(r) defining Z(r,c)} end end 18.4 杂乱或散射数据的插值 在有些情况下,两个变量的标量函数的值,如 z=f(x,y),不能简单地算出。这是 因为要么 x 和 y 的值是非均匀间隔的(最坏时是随机分布),要么是用了不同的坐 标系,比如非长方形的网格。出现这些情况时,MATLAB 中的函数 griddata 就用 来产生经插值后的均匀间隔数据以作图。首先考虑前面的例子。假设要求较高的分 辨率,但我们不想重新计算函数来得到新值。 » x=-3:3; % original x-axis values » y=1:5; % original y-axis values » [X,Y]=meshgrid(x,y); % create plaid data matrices » Z=(X+Y).^2; % original z values » size(Z) % original array size ans = 5 7 » xi=-3:.5:4; % interpolated x-axis values » length(xi) % get new x-axis length ans = 15 » yi=0:.2:5; % interpolated y-axis values » length(yi) % get new y-axis length ans = 26 » [Xi,Yi]=meshgrid(xi,yi); % make new data plaid » Zi=griddata(X,Y,Z,Xi,Yi); % interpolated Z data using original data » size(Zi) % interpolated size is correct ans =