MatLab中文版word版第九章.docx
《MatLab中文版word版第九章.docx》由会员分享,可在线阅读,更多相关《MatLab中文版word版第九章.docx(29页珍藏版)》请在冰点文库上搜索。
![MatLab中文版word版第九章.docx](https://file1.bingdoc.com/fileroot1/2023-5/11/f380210f-73b7-4d21-8971-2bd194ced982/f380210f-73b7-4d21-8971-2bd194ced9821.gif)
MatLab中文版word版第九章
第九章句柄图形
句柄图形是对底层图形函数集合的总称,它实际上进行生成图形的工作。
这些函数一般隐藏于M文件内部,但是它们非常地重要,因为程序员可以利用它对图象或图片的外观进行控制。
例如,我们可以利用句柄图形只对x轴产生网格线,或选择曲线的颜色为桔黄色,桔黄色plot命令中的标准LineSpec参数。
还有,句柄图形可以帮助程序员为他们的程序创建用户图形界面,用户图形界面,我们将在下一章介绍。
在本章中,我们向大家介绍MATLAB图形系统的结构,以及如何控制图形对象的属性。
9.1MATLAB图形系统
MATLAB图形系统是建立图形对象的等级系统之上,每一个图形对象都有一个独立的名字,这个名字叫做句柄。
每一个图形对象都有它的属性,我们可以通过修改它的属性来修改物体的行为。
例如,一条曲线是图形对象的一种。
曲线对象有以下的属性:
x数据,y数据,颜色,线的类型,线宽,符号类型等等。
修改其中的一个属性就会改变图象窗口中的一个图象。
由图形命令产生的每一件东西部是图形对象。
例如,图形中的每一个曲线,坐标轴和字符串是独立的对象(拥有独立的名字句柄,还有形式)。
所有的图象对象按子对象和父对象的形式管理,如图9.1所示。
当一个子对象被创建时,它可能继承了父对象的许多属性。
图9.1对象的层次结构
在MATLAB中最高层次的图形对象被根对象,我们可以通过它对整个计算机屏幕进行控制。
当MATLAB启动时,根对象会被自动创建,它一直存在到MATLAB关闭。
与根对象相关的属性是应用于所用MATLAB窗口的默认属性。
在根对象下,有多个图象窗口,或只有图象。
每一个图象在用于显示图象数据的计算机屏幕上都有一个独立的窗口,每一个图象都有它独立的属性。
与图象相关的属性有,颜色,图片底色,纸张大小,纸张排列方向,指针类型等。
每一个图形可包括四个对象:
Uimenu对象,Uicontrol对象,坐标系对象和Uicontextmenus对象。
Uimenu对象,Uicontrol对象,和Uicontextmenus对象是专门地用来创建用户图形界面的对象,它们将在下一章讨论。
坐标系对象是指在用于显示图象的图片中的区域。
在一个图象窗口中,它可能含有一个或多个坐标系。
每一个坐标系对象可能包括曲线对象,文本对象,贴片对象,还有其他的你所需的图形对象。
9.2对象句柄
每一个图象对象都有一个独一无二的名字,这个名字叫做句柄。
句柄是在MATLAB中的一个独一无二的整数或实数,用于指定对象的身份。
用于创建一个图象对象的任意命令都会自动地返回一个句柄。
例如,命令
>>Hnd1=figure;
创建一个新的图象,并返回这个图象的句柄到变量Hnd1。
根对象句柄一般为0,图象(图)对象的句柄一般是一个小的正整数,例如1,2,3……而其他的图形(graphic)对象为任意的浮点数。
我们可以利用MATLAB函数得到图象,坐标系和其他对象的句柄。
例如,函数gcf返回当前
图象窗口的句柄,而函数gca则返回在当前图象窗口中的当前坐标系对象的句柄,函数gco返回当前选择对象的句柄。
这些函数将会在后面将会被具体讨论。
为了方便,存储句柄的变量名要在小写字母后面个H。
这样就可以与普通变量(所有的小写变量,大写变量,全局变量)区分开来。
9.3对象属性的检测和更
对象属性是一些特殊值,它可以控制对象行为的某些方面。
每一个属性都有一个属性名和属性值。
属性名是用大小写混合格式写成的字符串,属性名中的每一个单词的第一个字母为大写,但是MATLAB中的变量名的大小不与区分。
9.3.1在创建对象时改变对象的属性
当一个对象被创建时,所有的属性都会自动初始化为默认值。
包含有"propertyname(属性名)"的创建函数创建对象时,默认值会被跳过,而跳过的值在创建函数中有。
例如,我们在第二章看到,线宽属性可以通过下面的plot命令改变。
plot(x,y,'LineWidth',2);
录一个曲线被创建时,函数用值2来替代它的默认值。
9.3.2对象创建后改变对象的属性
我们可以用随时用get函数检测任意一个对象的属性,并用set函数对它进行修改。
get函数最常见的形式如下
value=get(handle,'PropertyName');
value=get(handle);
value是勤句柄指定对象的属性值。
如果在调用函数时,只有一个句柄,那么函数将会返
回一个结构,域名为这个对象的属性名,域值为属性值。
set函数的最常用形式为
set(handle,'PropertyName1',value1,...);
在一个单个的函数中可能有多个"propertyname"和"value"。
例如,假设我们用下面的语句,画出函数y(x)=x2在(0,2)中的图象
x=0:
0.1:
2;
y=x.^2;
Hnd1=plot(x,y);
图象如图9.2a所示。
这个曲线的句柄被存储在变量Hnd1内,我们可以利用它检测和修改这条曲线的属性。
函数get(Hnd1)在一个结构中返回这条曲线所有的属性,每一个属性名都为结构的一个元素。
>>result=get(Hnd1)
result=
Color:
[001]
EraseMode:
'normal'
LineStyle:
'-'
LineWidth:
0.5000
Marker:
'none'
MarkerSize:
6
MarkerEdgeColor:
'auto'
MarkerFaceColor:
'none'
XData:
[1x21double]
YData:
[1x21double]
ZData:
[1x0double]
BeingDeleted:
'off'
ButtonDownFcn:
[]
Children:
[0x1double]
Clipping:
'on'
CreateFcn:
[]
DeleteFcn:
[]
BusyAction:
'queue'
HandleVisibility:
'on'
HitTest:
'on'
Interruptible:
'on'
Selected:
'off'
SelectionHighlight:
'on'
Tag:
''
Type:
'line'
UIContextMenu:
[]
UserData:
[]
Visible:
'on'
Parent:
151.0012
DisplayName:
''
XDataMode:
'manual'
XDataSource:
''
YDataSource:
''
ZDataSource:
''
注意当前曲线的线宽为0.5pixel,线型为虚线。
我们能够用这些命令改变线型和线宽。
set(Hnd1,'LineWidth',4,'LineStyle','--')
产生的结果图象如9.2b所示。
(a)
(b)
图9.1(a)用默认值画出的函数y=x2的图象,(b)修改了线宽和线型的函数图象
函数get和set对程序员来说非常的有用,因为它们可以直接插入到MATLAB程序中,根据用户的输入修改图象。
在下一章,我们把它用于GUI编程。
但对于最终的用户,他们要很容易地改变MATLAB对象的属性。
属性编辑器是为了这个目的而设计的工具。
启动属性编辑器的命令为
propedit(HandleList);
propedit;
这个函数第一个形式用于编辑所列出的句柄的属性,而这个函数的第二种形式用于编辑当前图象的属性。
例如下面的语句创建函数y(x)=在(0,2)x2中的图象并打开属性编辑器,让用户间接地改变曲线的属性。
figure
(2);
x=0:
0.1:
2;
y=x.^2;
Hnd1=plot(x,y);
propedit(Hnd1);
我们用这些语句调用属性编辑器,如图9.3。
属性编辑器包含了许多的窗格,用户可以根据对象的类型改变对象的属性。
在例子中讨论的曲线对象,它窗格包括"Date","Style",和"Info"。
"Date"窗格允许用户选择和修改所要显示的数据它可以修改X数据,Y数据和Z数据的属性。
"Style"窗格用来线型和符号属性,"Info"用来设置曲线对象的其它信息。
图9.3编辑曲线对象的属性编辑器。
属性编辑器可以用图象工具条上的
按钮调用,然后双击你所要编辑的对象。
例9.1
底层图形命令的应用
函数sinc(x)的定义如下
sincx=
x的取值从-3π到3π,画出这个函数的图象,用句柄图形函数画出图象,满足下面的要求
1.使图象背景为粉红色
2.只在y轴上有网格线
3.曲线为3point宽,桔黄色的实线
答案
为了创建图象,我们需要计算x从-3π到3π之间的函数sincx,然后用plot命令画出它的图象。
plot命令这条直线的句柄。
画完直线后,我们需要修改figure对象的颜色和axes对象的网格状态,以及line对象的颜色与线宽。
这些修改需要我们访问图对象,axes对象,line对象的句柄。
图对象的句柄由函数gcf返回,axes对象的句柄由函数gca返回,line对象由plot函数返回。
需要修改的底层图形属性可以在MATLAB在线帮助工作台文件中找到,在主题"HandleGraphicsObjects"目录下。
它们包括当前图象的"color"属性,当前的坐标系的"YGrid"属性,以及曲线的"LineWidth"属性和"color"属性。
1.陈述问题
画出函数sincx的图象,x的取值从-3π到3π,图象背景为粉红色,只在y轴上有网格线,曲线为3point宽,桔黄色的实线
2.定义的输入与输出
这个程序无输入,输出为指定的图象。
3.设计算法
这个问题可分为三大步
Calculatesinc(x)
Plotsinc(x)
Modifytherequiredgraphicsobjectproperties
这个程序的第一大步是计算x从-3π到3π之间的函数sincx。
这个工作可以用向量化语句完成,但向量化语句在x=0时会产生一个NaN,因为0/0没有意义。
在画这个函数之前我们必须用1.0替换NaN。
这个步骤的伪代码为
%Calculatesinc(x)
x=-3*pi:
pi/10:
3*pi
y=sin(x)./x
%Findthezerovalueandfixitup.Thezerois
%locatedinthemiddleofthexarray.
index=fix(length(y)/2)+1
y(index)=1
下一步,我们必须画出这个函数的图象,并把所要修改的曲线的句柄存入一个变量。
这个步骤的伪代码为
Hndl=plot(x,y);
现在,我们必须用句柄图形修改图象背景,y轴上的网格线,线宽和线色。
图对象的句柄由函数gcf返回,axes对象的句柄由函数gca返回,line对象由plot函数返回。
粉红色背景可由RGB向量[10.80.8]创建,桔黄色曲线可以由RGB向量[10.50]创建。
伪代码如下
set(gcf,'Color',[10.80.8])
set(gca,'YGrid','on')
set(Hndl,'Color',[10.50],'LineWidth',3)
4.把算法转化为MATLAB语言
%Scriptfile:
plotsinc.m
%
%Purpose:
%Thisprogramillustratestheuseofhandlegraphics
%commandsbycreatingaplotofsinc(x)from-3*pito
%3*pi,andmodifyingthecharacteristicsofthefigure,
%axes,andlineusingthe"set"function.
%
%Recordofrevisions:
%DateProgrammerDescriptionofchange
%===================================
%11/22/97S.J.ChapmanOriginalcode
%
%Definevariables:
%Hndl--Handleofline
%x--Independentvariable
%y--sinc(x)
%Calculatesinc(x)
x=-3*pi:
pi/10:
3*pi;
y=sin(x)./x;
%Findthezerovalueandfixitup.Thezerois
%locatedinthemiddleofthexarray.
index=fix(length(y)/2)+1;
y(index)=1;
%Plotthefunction.
Hndl=plot(x,y);
%Nowmodifythefiguretocreateapinkbackground,
%modifytheaxistoturnony-axisgridlines,and
%modifythelinetobea2-pointwideorangeline.
set(gcf,'Color',[10.80.8]);
set(gca,'YGrid','on');
set(Hndl,'Color',[10.50],'LineWidth',3);
5.检测程序
这个程序的检测是非常简单的,我们只要运行这个程序,并检查产生的图象就可以了。
产生的图象如图9.4所示,它就是我们需要的样式。
图9.4sincx的图象
9.4用set函数列出可能属性值
函数用于提供所有可能的属性值列表。
如果在调用函数set时,只包括属性名而不包括相应的属性值,那么函数set就会返回所有的合法属性值。
例如,命令set(Hnd1,"LineStyle")将返回所有可能的线型,大括号中是默认的线型。
>>set(Hndl,'LineStyle')
[{-}|--|:
|-.|none]
这个函数的合法包括和"none",第一个是默认的类型。
>>set(Hndl,'LineWidth')
Aline's"LineWidth"propertydoesnothaveafixedsetofpropertyvalues.
函数set(Hnd1)返回一个对象的所有属性的所有可能的属性值。
>>set(Hndl)
ans=
Color:
{}
EraseMode:
{4x1cell}
LineStyle:
{5x1cell}
LineWidth:
{}
Marker:
{14x1cell}
MarkerSize:
{}
MarkerEdgeColor:
{2x1cell}
MarkerFaceColor:
{2x1cell}
XData:
{}
YData:
{}
ZData:
{}
ButtonDownFcn:
{}
Children:
{}
Clipping:
{2x1cell}
CreateFcn:
{}
DeleteFcn:
{}
BusyAction:
{2x1cell}
HandleVisibility:
{3x1cell}
HitTest:
{2x1cell}
Interruptible:
{2x1cell}
Selected:
{2x1cell}
SelectionHighlight:
{2x1cell}
Tag:
{}
UIContextMenu:
{}
UserData:
{}
Visible:
{2x1cell}
Parent:
{}
DisplayName:
{}
XDataMode:
{2x1cell}
XDataSource:
{}
YDataSource:
{}
ZDataSource:
{}
9.5自定义数据
除了一个GUI对象定义的标准属性以外,程序可以定义所要控制的数据的特殊属性。
程序员可以用附加属性把任意类型的数据添加到GUI对象中。
任意数量的数据可以被存储,并应用于各种目的。
自定义数据可以用近似标准属性的形式存储。
每一个数据条目都有一个名字和值。
数据
变量可以用函数setappdate存储在一个对象,并用函数getappdata接收。
setappdate函数的基本形式如下
setappdata(Hndl,'DataName',DataValue);
其中Hndl是数据存入的对象的句柄,"DateName"是这个数据的名字,而DateValue是赋于是这个名字的值。
注意数据值可以是数字,也可以是字符串。
例如,假设我们要定义两个特殊的数据值,其中一个用于存储发在指定图象中的错误数,另一个是用于描述最后发现的错误的字符串。
这两个数据值的名字是"ErrorCount"和"LastError"。
我们假设H1为这个图象的句柄,创建这些数据条目和初始化的命令为
setappdata(Hl,'ErrorCount',0);
setappdata(H1,'LastError','Noerror');
我们可以用getappdata函数随时调用这些数据。
getappdata的两种形式如下
value=getappdata(Hndl,'DataName');
struct=getappdata(Hndl);
其中,Hnd1是包含有这个数据的对象句柄,"DateName"是要调用的数据的名字,如果一个"DateName"被指定,那么与"DateName"相关的值就会被返回。
如果没有被指定,那么所有与这个对象形字相关的自定义值就会以结构的形式被返回。
数据条目名就是结构元素名。
对上面的例子来说,getappdata将会产生下面的结果
>>value=getappdata(Hl,'ErrorCount')
value=
0
>>value=getappdata(Hl);
struct=
ErrorCount:
0
LastError:
'Noerror'
与自定义数据相关的函数被总结在表9.1中。
表9.1与自定义数据相关的函数
函数
描述
setappdata(Hndl,'DataName',DataValue)
把DataValue存储在对象中的'DataName',这个对象以Hndl为句柄。
value=getappdata(Hndl,'DataName')
struct=getappdata(Hndl)
从以Hndl句柄的对象重新调用程序,第一种形式只读取'DataName'中的数据,第二种形式重新所有的自定义数据。
isappdata(Hndl,'DataName')
如果'DataName'在以Hndl为句柄的对象中有定义,那就会返回1,否则返回0。
isappdata(Hndl,'DataName')
删除'DataName','DataName'是在以Hndl为句柄的对象中的自定义数据。
9.6对象查找
每一个新的图象在从创建开始时就有它们自已的句柄,句柄可以由创建函数返回。
好的编程习惯
如果你打算修改你创建的对象的属性,那么请保存对象的句柄,为以后调用函数get和set做准备。
但是我们有时不能访问句柄。
假设我们由于一些原因,丢失了对象的句柄。
我们如何检测和图形对象呢?
MATLAB提供了四个专门的函数,用来帮助寻找对象的句柄。
●gcf返回当前图象的句柄
●gca返回当前图象中当前坐标系的句柄
●gco返回当前对象的句柄
●findobj寻找指定属性值的图形对象
函数gcf返回当前图象的句柄。
如果这个图象不存在,gcf将会创建一个,并返回它的句柄。
函数gca返回当前图象中当前坐标系的句柄,如果图象不存在,或当前图象中无坐标系,那么函数gca将创建一个坐标系,并返回它的句柄。
函数gco的形式如下
H_obj=gco;
H_obj=gco(H_fig);
其中,H_obj是一个对象的句柄,H_fig是一个图象的句柄。
这个函数的第一种形式返回当前图象中的当前对象的句柄。
它的第二种形式返回一指定图象中的当前对象的句柄。
当前对象是指用鼠标单击的最一个对象。
这个对象可以是除了根对象的任意图形对象。
直到鼠标在图象内发生了单击事件,在图象内才有一个当前对象。
在单击事件发生之后,函数gco将返回一个空数组[],不像函数gcf和gca,gco如果不存在就自动创建。
一旦我们得知了一个对象的句柄,我们可以通过检测"Type"属性去时来确定对象的类型。
"Type"属性是一个字符串,例如"图","line","text"等等。
H_obj=gco;
type=get(H_obj,'Type')
查找任意一个MATLAB对象最简单的方法是用findobj函数。
它的基本形式如下
Hndls=findobj('PropertyName1',value1,...)
这个命令起始于根对象,并搜索所有的对象,找出含有指定属性,指定值的对象。
注意可以指定多个属性/值,findobj只返回与之匹配的对象句柄。
例如,假设我们已经创建了图1和图3。
那么函数findobj("Type","图")将会返回结果
>>H_fig=findobj('Type','figure')
H_fig=
3
1
函数findobj的这种形式非常的有用,但却比较慢,因为它必须对整个对象树进行搜索。
如果你必须多次用到一对象,只调用一次函数findobj,为了重复利用句柄,句柄应存储下来。
限定搜索对象的数目能够加快函数运行的速度。
它的形式为
Hndls=findobj(SrchHndls,'PropertyName1',value1,...)
在这里,只有数组srchHndls和它的子数组中的句柄,才在搜索的范围内。
例如你想找到图1中的虚线。
它的命令为
Hndls=findobj(1,'Type','line','LineStyle','--');
好的编程习惯
如果有可能的话,限定函数findobj的搜索范围将能加快函数的运行速度。
9.7用鼠标选择对象
函数gco将返回当前对象,当前对象是指用鼠标最后一次单击的对象。
每一个对象都有一个与之相关的可选择区,在可选择区内任意一个单击都可以看作对这个对象的单击。
对于细小的对象(例如线,点)来说,这种特性是非常重要的。
可选择区的宽度和形状由对象的类型确定。
例如,一个曲线的可选择区在离直线5pixel的范围内,而一个表面,一个小块和文本对象的可选择区是包含这些对象的最小长方形。
对于一个坐标系对象来说,它的可选择区是坐标轴区域加上标题和标签的区域。
但是在坐标轴内的曲线对象或其他对象有更高的优先权,你必须在单击坐标内的一点