QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1000|回复: 2
打印 上一主题 下一主题

一个例子

[复制链接]
字体大小: 正常 放大

2620

主题

162

听众

1万

积分

升级  0%

  • TA的每日心情
    开心
    2015-3-12 15:35
  • 签到天数: 207 天

    [LV.7]常住居民III

    社区QQ达人 发帖功臣 新人进步奖 优秀斑竹奖 金点子奖 原创写作奖 最具活力勋章 助人为乐奖 风雨历程奖

    群组第六届国赛赛前冲刺培

    群组国赛讨论

    群组2014美赛讨论

    群组2014研究生数学建模竞

    群组数学中国试看培训视频

    跳转到指定楼层
    1#
    发表于 2014-12-30 10:37 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    前面介绍了MATLAB中事件模型的基本原理和设计方法。下面通过一个完整的实例来实现事件模型的具体设计过程。

    例8-2  建立一个图形用户界面,要求:
    (1)在界面上用subplot命令绘制两个坐标轴,在每个坐标轴上各绘制一个曲面;
    (2)利用函数的变化和函数区间的变化来触发件,通过事件来及时更新函数图形的绘制;
    (3)通过上下文菜单来设置各个坐标轴是否收听事件。
    分析:在本例中涉及到两个事件来对应函数变化情况和自变量区间变化情况。函数的变化情况可以在events块中定义一个普通的事件UpdateGraphics来描述,而函数区间的变化情况可以采用PostSet事件来设置。这样,就需要定义两个听众来响应这两个事件。利用听众的Enabled特性来设置是否收听这些事件。
    解:为解决本例问题,需要设计两个类,一个是函数运算类MfunEval,在这个类中定义一个函数句柄hFun和区间变量Lm,并在其中events块中定义一个UpdateGraph事件,另一个是坐标轴类Maxes,在其中定义两个听众对象,并与相应的回调函数相关联实现绘图更新。
    本实例文件目录结构如图8-2所示。
    文件MFunEval.m中的代码为:
    classdef  MFunEval< handle  %函数计算类
        properties
          hFun              %函数句柄
        end
        properties (SetObservable = true)
           Lm = [];   %区间
        end
        properties (Dependent = true)
           Data     %保存网格化数据
        end  
        events
           UpdateGraph   %更新图形
        end
        methods
          function obj = MFunEval(fcn_handle,limits)         %构造函数
           obj.hFun = fcn_handle;
           obj.Lm = limits;
          end
          function fofxy = set.hFun(obj,func)
            obj.hFun = func;
            notify(obj,'UpdateGraph');                                   %广播事件
          end
          function data = get.Data(obj)                                    %获取网格化数据
           [x,y] = MFunEval.grid(obj.Lm);
           matrix = obj.hFun(x,y);
           data.X = x;
           data.Y = y;
           data.Matrix = matrix;
          end
        end
        methods (Static)
            function [x,y] = grid(lim)                                   %网格化
              inc = (lim(2)-lim(1))/20;
              [x,y] = meshgrid(lim(1):inc:lim(2));
            end
        end   
    end
    复制代码
    文件MAxes.m中的代码为:
    classdef MAxes < handle           %坐标轴类
       properties
          FunObject  = []                    %函数计算类对象
          hLUpdateGraph = []              %图形更新听众句柄
          hLLm = []                       %区间Lm的PostSet事件听众句柄
          hEnableCm = []                  %上下文菜单“Listen”句柄
          hDisableCm = []                 %上下文菜单“Don't Listen”句柄
          hAxes = [];                      %坐标轴句柄
          hSurface = []                     %曲面对象句柄
       end  
       methods
          function obj= MAxes(funobj)  
            obj.FunObject = funobj;
            obj.CreateLisn;  %创建听众   
          end
          function CreateLisn(obj)  %创建两个听众
              obj.hLUpdateGraph = addlistener(obj.FunObject,'UpdateGraph',...
                               @(src,evnt)listenUpdateGraph(obj,src,evnt));
              obj.hLLm = addlistener(obj.FunObject,'Lm','PostSet',...
                             @(src,evnt)listenLm(obj,src,evnt));
          end
          %听众1的回调函数
          function listenUpdateGraph(obj,src,evnt)  %更新图形
              if ishandle(obj.hSurface)
                  obj.updateSurfaceData
              end
          end
          function updateSurfaceData(obj)
               data = obj.FunObject.Data;
               set(obj.hSurface,...
                   'XData',data.X,...
                   'YData',data.Y,...
                   'ZData',data.Matrix);
          end
          %听众2的回调函数
          function listenLm(obj,src,evnt)
                 if ishandle(obj.hAxes)
                     lims(obj);
                     if ishandle(obj.hSurface)
                         obj.updateSurfaceData
                     end
                 end
          end
          function lims(obj)
               lmts = obj.FunObject.Lm;
               set(obj.hAxes,'XLim',lmts);
               set(obj.hAxes,'Ylim',lmts);
          end
          function delete(obj)  %析构函数
              if ishandle(obj.hAxes)
                  delete(obj.hAxes);
              else
                  return
              end
          end
    end
        methods (Static = true)
            function CreateViews(funobj)  %绘制曲面
                 hFigure = figure('Name','利用事件模型更新图', 'Toolbar','none');
                for k=1:2
                  axesobj(k)= MAxes(funobj);  %定义坐标轴对象
                  axh=subplot(1,2,k);
                  axesobj(k).hAxes=axh;
                  hcm(k)=uicontextmenu;  %上下文菜单
                  set(axesobj(k).hAxes,'Parent',hFigure,...
                     'FontSize',8,...
                     'UIContextMenu',hcm(k));
                   axesobj(k).hEnableCm = uimenu(hcm(k),...
                      'Label','Listen',...
                       'Checked','on',...
                      'Callback',...
                      @(src,evnt)enableLisn(axesobj,src,evnt));
                   axesobj(k).hDisableCm = uimenu(hcm(k),...
                      'Label','Don''t Listen',...
                       'Checked','off',...
                      'Callback',...
                      @(src,evnt)disableLisn(axesobj(k),src,evnt));
                    view(axesobj(k).hAxes,60,30)
                    axesobj(k).lims;
                    surfLight(axesobj(k),axesobj(k).hAxes);  %绘制曲面
                 end
            end
        end
    end
    复制代码
    以下是三个全局函数:
    function surfLight(obj,axh)
               obj.hSurface = surface(obj.FunObject.Data.X,...
               obj.FunObject.Data.Y,...
               obj.FunObject.Data.Matrix,...
               'FaceColor',[.8 .8 0],'EdgeColor',[.3 .3 .2],...
               'FaceLighting','phong',...
               'FaceAlpha',.3,...
               'HitTest','off',...
               'Parent',axh);
               lims(obj)
               camlight left; material shiny; grid off
               colormap copper
    end
    function enableLisn(obj,src,evnt)
                obj.hLUpdateGraph.Enabled = true;
                obj.hLLm.Enabled = true;
                set(obj.hEnableCm,'Checked','on')
                set(obj.hDisableCm,'Checked','off')
            end
    function disableLisn(obj,src,evnt)
                obj.hLUpdateGraph.Enabled = false;
                obj.hLLm.Enabled = false;
                set(obj.hEnableCm,'Checked','off')
                set(obj.hDisableCm,'Checked','on')
    end
    复制代码
    在命令窗口中输入如下命令后,会出现如图8-3所示的执行效果。
    >>funobj = MFunEval(@(x,y) 3*cos(x).*cos(y).*exp(-sqrt(x.^2+y.^2)/6),[-5 5]);
    >>MAxes.CreateViews(funobj);
    提示:第一条命令创建了一个MfunEval对象,构造函数中第一个参数是一个二元函数,用无名函数方式给出;第二个参数是区间,即函数计算区域是 。第二条命令是调用了坐标轴类MAxes中的静态方法CreateViews。

    图8-3  利用事件模型更新图形
      将鼠标移到在上面图形界面的左面坐标轴上点击右键,在弹出的上下文快捷菜单中选择“Don’t Listen”,在命令窗口再输入如下命令:
    >>funobj.hFun=@(x,y) (x.^2+y.^2)
    此对象funobj中的事件UpdateGraph被触发,由于左侧坐标轴对象听众的特性值Enabled为false,所有它不去执行回调函数listenUpdateGraph;而右侧听众的特性值Enabled为true,所有会去执行回调函数listenUpdateGraph。此时坐标轴上图形更新变化情况如图8-4所示。

    图8-4  利用事件模型更新图形
    同样输入:
    >>funobj.Lm=[-10,10];
    复制代码
    会触发PostSet事件的发生,可改变函数绘图区间,并有相同的更新效果。


    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    光之仑 实名认证       

    14

    主题

    9

    听众

    3472

    积分

    升级  49.07%

  • TA的每日心情
    奋斗
    2016-12-4 17:02
  • 签到天数: 983 天

    [LV.10]以坛为家III

    超级版主

    社区QQ达人

    群组数学趣味、游戏、IQ等

    群组数学建摸协会

    群组学术交流A

    群组学术交流B

    回复

    使用道具 举报

    0

    主题

    7

    听众

    705

    积分

    升级  26.25%

  • TA的每日心情

    2017-5-7 16:58
  • 签到天数: 366 天

    [LV.9]以坛为家II

    邮箱绑定达人 社区QQ达人

    群组2012HIMCM培训群组

    群组第四届数学中国美赛实

    群组第三届数模基础实训

    群组高数系列公益培训

    群组物联网工程师培训

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2025-5-23 00:45 , Processed in 0.530388 second(s), 61 queries .

    回顶部