www.gusucode.com > mbcdesign 工具箱 matlab 源码程序 > mbcdesign/+xregdesgui/ConView2d.m

    classdef ConView2d < xregdesgui.DesignView
    %xregdesgui.ConView2d class
    %   xregdesgui.ConView2d extends xregdesgui.DesignView.
    %
    %    xregdesgui.ConView2d properties:
    %       Parent - Property is of type 'MATLAB array'
    %       Position - Property is of type 'rect'
    %       Enable - Property is of type 'on/off'
    %       Visible - Property is of type 'on/off'
    %       UserData - Property is of type 'MATLAB array'
    %       Tag - Property is of type 'string'
    %       MessageService - Property is of type 'handle'
    %       Options - Property is of type 'handle vector'
    %       Actions - Property is of type 'handle vector'
    %       UIContextMenu - Property is of type 'MATLAB array'
    %       Resolution - Property is of type 'double'
    %       Xaxis - Property is of type 'double'
    %       Yaxis - Property is of type 'double'
    %       EvalPoint - Property is of type 'MATLAB array'
    %
    %    xregdesgui.ConView2d methods:
    %       gettitle - Return a suitable title for a window
    %       printCopy - Create a new component for printing the component display
    
    %  Copyright 2015-2016 The MathWorks, Inc. and Ford Global Technologies, Inc.

    properties (AbortSet, SetObservable)
        %RESOLUTION Property is of type 'double'
        Resolution = 30;
    end
    properties (Dependent,AbortSet)
        %XAXIS Property is of type 'double'
        Xaxis
        %YAXIS Property is of type 'double'
        Yaxis
        %EVALPOINT Property is of type 'MATLAB array'
        EvalPoint = [];
    end
    
    properties (Access=protected, AbortSet)
        %HAXES Property is of type 'MATLAB array'
        hAxes = [];
        %HPATCH Property is of type 'MATLAB array'
        hPatch = [];
        %NODISPLAYTEXT Property is of type 'MATLAB array'
        nodisplaytext = [];
        %HRESOLUTION Property is of type 'handle'
        hResolution = [];
        %HSLICECONTROL Property is of type 'handle'
        hSliceControl = [];
    end
    
    
    methods  % constructor block
        function obj = ConView2d(varargin)
        %CONVIEW2D Constructor for conview2d objects
        %  CONVIEW2D(PROP, VALUE, ...) constructs a new conview2d object.
        
        obj@xregdesgui.DesignView(varargin{ : }); % converted super class constructor call
        
        % Generate GUI primitives and link together into a layout
        axlyt = mbcgui.widget.AxesContainer( ...
            'Parent',obj.Parent, ...
            'Visible',obj.Visible,...
            'PositionSetting','outer',...
            'Border', [10 10 10 10]);
        obj.hAxes = axlyt.AxesHandle;
        set(obj.hAxes, ...
            'Box','on',...
            'UIContextMenu',obj.UIContextMenu,...
            'XGrid','on',...
            'YGrid','on',...
            'Units','pixels',...
            'Layer','top');
        
        mbcxlabel(obj.hAxes, '', 'Interpreter', 'none', 'HitTest', 'off');
        mbcylabel(obj.hAxes, '', 'Interpreter', 'none', 'HitTest', 'off');
        obj.hPatch = patch('Parent',obj.hAxes, ...
            'XData', [], ...
            'YData', [], ...
            'EdgeColor','k',...
            'FaceColor',[0.5,0.5,1],...
            'HitTest','off');
        xregGui.setLegendData(obj.hPatch, 'Constrained region');
        obj.nodisplaytext = text('Parent',obj.hAxes,...
            'String','',...
            'Position',[.5 .5 0],...
            'HorizontalAlignment','center',...
            'VerticalAlignment','middle',...
            'Clipping','on',...
            'HitTest','off');
        
        hPanel = mbcgui.container.layoutpanel(...
            'Parent', obj.Parent, ...
            'BorderType', 'beveledout', ...
            'LayoutBorder', [5 5 5 5]);
        resedit = mbcgui.widget.Spinner('Parent',hPanel,...
            'Rule','int',...
            'Min',1,...
            'Max',100,...
            'Value', obj.Resolution, ...
            'ClickIncrement',1,...
            'Callback', @iSetResolutionFromSpinner);
        obj.hResolution = xregGui.labelcontrol('parent', hPanel, ...
            'String', 'Resolution:', ...
            'LabelAlignment', 'right', ...
            'ControlSize', 60, ...
            'Control', resedit);
        set(hPanel, 'LayoutComponent', obj.hResolution);
        
        obj.hSliceControl = xregdesgui.SliceControl('NumAxes', 2, ...
            'Parent', obj.Parent);
        obj.ContentHandle = xreggridbaglayout(obj.Parent,...
            'packgroup','XREGCONVIEWERS',...
            'dimension',[2 3],...
            'rowsizes',[-1 32],...
            'colsizes',[160 150 -1],...
            'mergeblock',{[1 2],[2 3]},...
            'elements',{obj.hSliceControl, hPanel, axlyt},...
            'position',obj.Position, ...
            'packstatus','on');
        
        obj.pPostSetMessageService;

        % Attach listeners to properties and slice control events
        obj.addListeners( ...
            [event.listener(obj.hSliceControl, 'AxisChanged', @iReDrawGraph), ...
            event.listener(obj.hSliceControl, 'PointChanged', @iReDrawGraph)] ...
            );
        
            function iSetResolutionFromSpinner(src, ~)
            obj.Resolution = src.Value;
            end
        
            function iReDrawGraph(~, ~)
            busy(obj.MessageService)
            obj.pDrawGraph;
            idle(obj.MessageService);
            end
        end
        
        
    end  % constructor block
    
    methods
        function set.Resolution(obj,value)
        % DataType = 'double'
        validateattributes(value,{'double'}, {'scalar'},'','Resolution')
        obj.Resolution = value;
        
        busy(obj.MessageService)
        obj.pDrawGraph;
        idle(obj.MessageService);
        end
        
        function fact = get.Xaxis(obj)
        if ~isempty(obj.hSliceControl)
            fact = obj.hSliceControl.Axes(1);
        else
            fact = 0;
        end

        end
        function set.Xaxis(obj,fact)
        % DataType = 'double'
        
        if ~isempty(obj.hSliceControl)
            obj.hSliceControl.Axes(1) = fact;
            obj.pDrawGraph;
        end        
        
        end
        
        function fact = get.Yaxis(obj)
        
        if ~isempty(obj.hSliceControl)
            fact = obj.hSliceControl.Axes(2);
        else
            fact = 0;
        end

        end
        function set.Yaxis(obj,fact)
        % DataType = 'double'
        if ~isempty(obj.hSliceControl)
            obj.hSliceControl.Axes(2) = fact;
            obj.pDrawGraph;
        end        
        end
        
        function pt = get.EvalPoint(obj)
        if ~isempty(obj.hSliceControl)
            pt = obj.hSliceControl.SlicePoint;
        else
            pt = [];
        end
        end
        function set.EvalPoint(obj,pt)
        if ~isempty(obj.hSliceControl)
            obj.hSliceControl.SlicePoint = pt;
            obj.pDrawGraph;
        end        
        end
        
        function set.hResolution(obj,value)
        % DataType = 'handle'
        validateattributes(value,{'handle'}, {'scalar'},'','hResolution')
        obj.hResolution = value;
        end
        
        function set.hSliceControl(obj,value)
        % DataType = 'handle'
        validateattributes(value,{'handle'}, {'scalar'},'','hSliceControl')
        obj.hSliceControl = value;
        end
        
    end   % set and get functions
    
    methods  % public methods
        %----------------------------------------
        function s = gettitle(obj) %#ok<MANU>
        %GETTITLE Return a suitable title for a window
        %  GETTITLE(OBJ) returns a string that can be sued as a title for the view.
        
        s = '2D Constraints';
        
        end  % gettitle
        
        %----------------------------------------
        function pDrawGraph(obj)
        %PDRAWGRAPH Draw constraint region on graph
        %
        %  PDRAWGRAPH(obj) updates the constraint graph.
        
        
        
        if obj.hSliceControl.hasSlice
            d = obj.MessageService.getdesign;
            sc = obj.hSliceControl;
            
            Xax = sc.Axes(1);
            Yax = sc.Axes(2);
            
            % set axes labels
            fstr = factors(d);
            xlabel(obj.hAxes, fstr{Xax});
            ylabel(obj.hAxes, fstr{Yax});
            
            m = model(d);
            lims = designlimits(d);
            codedlims = cat(1,lims{:});
            lims = invcode(m,codedlims')';
            % generate and constrain points
            c = constraints(d);
            if isempty(c);
                xl = lims(Xax,:);
                yl = lims(Yax,:);
                verts = [xl(1) yl(1) 0; xl(2) yl(1) 0; xl(2) yl(2) 0; xl(1) yl(2) 0];
                faces = [1 2 3 4];
            else
                res = max(3,floor(obj.Resolution*5));
                pt = sc.SlicePoint; %>> code(m, sc.SlicePoint);
                ncols = min(max(1,floor(2^19/(8*res*nfactors(d)))),res);      % number of cols to do at once
                niter = floor((res./ncols));
                nover = res-(niter*ncols);
                % allocate some stuff
                contourmat(res+2,res+2) = uint8(0);
                constrainpts = repmat(pt(:)',res*ncols,1);
                xpts = linspace(lims(Xax,1),lims(Xax,2),res); %>> linspace(codedlims(Xax,1),codedlims(Xax,2),res);
                ypts = linspace(lims(Yax,1),lims(Yax,2),res); %>> linspace(codedlims(Yax,1),codedlims(Yax,2),res);
                for n=1:niter
                    [Y, X] = ndgrid(ypts,xpts((1:ncols)+((n-1)*ncols))); 
                    constrainpts(:,Xax)= X(:);
                    constrainpts(:,Yax)= Y(:);
                    
                    contourmat(2:end-1,(1:ncols)+((n-1)*ncols)+1) = ...
                        reshape(isInsideNoMemory(c,constrainpts),res,ncols);
                end
                
                % final smaller iteration
                if nover
                    [Y,X]= ndgrid(ypts,xpts(end-nover+1:end));
                    constrainpts(1:res*nover,Xax) = X(:);
                    constrainpts(1:res*nover,Yax) = Y(:);
                    
                    contourmat(2:end-1,end-nover:end-1) = ...
                        reshape(isInsideNoMemory(c,constrainpts(1:res*nover,:)),res,nover);
                end
                % clean out unused memory before "double"ing contourmat
                clear('constrainpts');
                
                % contour the 0/1 matrix (note - it is buffered with a line of zeros to ensure the
                % contour line is contiguous.
                
                % convert to double and smooth first
                K=[1 1 1
                    1 1 1
                    1 1 1];
                K = K./9;
                contourmat = conv2(double(contourmat),K,'same');
                
                % put buffer zeros back on
                contourmat(:,[1 end]) = 0;
                contourmat([1 end],:) = 0;
                
                %>> xpts = invcode(m,xpts(:), Xax)';
                %>> ypts = invcode(m,ypts(:), Yax)';
                C = contourc([xpts(1)-eps(xpts(1)) xpts xpts(end)+eps(xpts(end))],...
                    [ypts(1)-eps(ypts(1)) ypts ypts(end)+eps(ypts(end))],contourmat,[0.5 0.5])';
                verts = [C zeros(size(C,1),1)];
                % join up contours
                n = 1;
                torem = [];
                facesizes = [];
                while n<size(C,1)
                    torem = [torem n]; %#ok<AGROW>
                    nextn = C(n,2);
                    facesizes = [facesizes nextn]; %#ok<AGROW>
                    n = n+nextn+1;
                end
                
                verts(torem,:) = [];
                faces = NaN(length(facesizes),max(facesizes));
                st = 1;
                for n = 1:length(facesizes)
                    faces(n,1:facesizes(n)) = st:st+facesizes(n)-1;
                    st = st+facesizes(n);
                end
            end
            
            % inverse code the points and set into patch
            set(obj.hAxes,'XLim',lims(Xax,:),...
                'YLim',lims(Yax,:),...
                'XGrid','on','YGrid','on');
            set(obj.hPatch,'Vertices',verts,'Faces',faces);
            set(obj.nodisplaytext,'String','');
        else
            xlabel(obj.hAxes, '');
            ylabel(obj.hAxes, '');
            set(obj.hPatch,'XData',[],'YData',[]);
            set(obj.hAxes,'XLim',[0 1],'YLim',[0 1],'XGrid','off','YGrid','off');
            set(obj.nodisplaytext,'String','2 or more factors required');
        end
        
        end  % pDrawGraph
        
        %----------------------------------------
        function pUpdate(obj, ~,~)
        %PUPDATE Update display
        %  PUPDATE(OBJ) refreshes the view's display.
        
        if obj.hasData
            obj.hSliceControl.Design = obj.MessageService.getdesign;
        else
            obj.hSliceControl.Design = [];
        end
        obj.pDrawGraph;
        
        end  % pUpdate
        
        %----------------------------------------
        function newobj = printCopy(obj, fig)
        %PRINTCOPY Create a new component for printing the component display
        %  NEWOBJ = PRINTCOPY(OBJ, FIG) creates and returns a handle to a new
        %  component, NEWOBJ, parented by the specified figure, FIG.  The new
        %  object will be used for printing a copy of the component OBJ.
        
        varinfo = printCopy(obj.hSliceControl, fig);
        
        % copy main axes
        ax = xregGui.HGPlotCopy(obj.hAxes, fig);
        set(ax, 'UIContextMenu', []);
        ax = mbcgui.widget.AxesContainer(...
            'AxesHandle', ax, ...
            'Border', [60 50 10 10]);
        
        layout = xreggridbaglayout(fig, ...
            'dimension',[1 2],...
            'colsizes',[130 -1],...
            'elements',{varinfo,ax});
        
        newobj = obj.addPrintTitle(layout);
        
        end  % printcopy
        
    end  % public methods
    
    methods(Access=protected)
        %----------------------------------------
        function pPostSetMessageService(obj)
        %PPOSTSETMESSAGESERVICE Respond to change of MessageService
        %  PPOSTSETMESSAGESERVICE(OBJ) is called when the MessageService property is
        %  changed.
        
        % Clear the listeners and add new ones
        obj.clearMessageServiceListeners;
        if ~isempty(obj.MessageService)
            addMessageServiceListener(obj,event.listener(obj.MessageService,'ConstraintChange',@obj.pUpdate))
        end
        obj.pUpdate;
        
        end  % pPostSetMessageService
    end
        
    
end  % classdef