Canvas_2D class
This is a sub-class of the Canvas class, to deal especifically with axes that present only 2D behavior.
Contents
Authors
- Pedro Cortez F Lopes (pedrocortez@id.uff.br)
- Rafael Lopez Rangel (rafaelrangel@tecgraf.puc-rio.br)
- Luiz Fernando Martha (lfm@tecgraf.puc-rio.br)
History
@version 1.00
Initial version: September 2020
Initially prepared for the course CIV 2801 - Fundamentos de Computação Gráfica, 2020, second term, Department of Civil Engineering, PUC-Rio.
Class definition
classdef Canvas_2D < Canvas
Constructor method
methods function this = Canvas_2D(ax,fig,fcn) if (nargin == 0) ax = []; fig = []; fcn = []; elseif (nargin <= 2) fcn = []; end this = this@Canvas(ax,fig,fcn); end end
Public methods
Implementation of the abstract methods declared in super-class Canvas.
methods %------------------------------------------------------------------ % Fits axis limits to display everything drawn on canvas function fit2view(this,bBox) % Set axes units to pixels dfltUnits = get(this.ax, 'Units'); set(this.ax, 'Units', 'pixels'); % Compute canvas height/width ratio h_w = this.ax.Position(4)/this.ax.Position(3); % Set axes units back to what they were set(this.ax, 'Units', dfltUnits); % Check if a bounding box was already provided if (nargin == 2) if ~isempty(bBox) % Get x and y vectors x = [bBox(1),bBox(3)]; xmin = min(x); xmax = max(x); y = [bBox(2),bBox(4)]; ymin = min(y); ymax = max(y); % Compute window sizes based on model bounding box size % increased by current free border factor. % Place window center at model bounding box center pos. %%%%% COMPLETE HERE - CANVAS_2D: 01 %%%%% Lx = (xmax - xmin) * (1.0 + this.freeBorder); Mx = (xmax + xmin) * 0.5; Ly = (ymax - ymin) * (1.0 + this.freeBorder); My = (ymax + ymin) * 0.5; %%%%% COMPLETE HERE - CANVAS_2D: 01 %%%%% y_x = Ly / Lx; % If axIsEq, make sure bound box fits while respecting % proportional limits if this.axIsEq %%%%% COMPLETE HERE - CANVAS_2D: 02 %%%%% if y_x > h_w Lx = Ly / h_w; else Ly = Lx * h_w; end %%%%% COMPLETE HERE - CANVAS_2D: 02 %%%%% end % Set limits and return %%%%% COMPLETE HERE - CANVAS_2D: 03 %%%%% xmin = Mx - (Lx * 0.5); xmax = Mx + (Lx * 0.5); ymin = My - (Ly * 0.5); ymax = My + (Ly * 0.5); %%%%% COMPLETE HERE - CANVAS_2D: 03 %%%%% this.ax.XLim = [xmin,xmax]; this.ax.YLim = [ymin,ymax]; % Set flag to indicate that bounding box was provided this.bBoxWasSet = true; return; end end % Get list of handles to graphic objects drawn on this.ax plots = this.ax.Children; % If there is nothing drawn on this.ax, return if isempty(plots) if ~this.axIsEq this.ax.XLim = [-5,5]; this.ax.YLim = [-5,5]; elseif h_w > 1 this.ax.XLim = [-5,5]; this.ax.YLim = [-5*h_w,5*h_w]; else this.ax.XLim = [-5/h_w,5/h_w]; this.ax.YLim = [-5,5]; end return end % Get maximum and minimum coordinates if ~strcmp(plots(1).Type,'text') xmax = max(plots(1).XData); xmin = min(plots(1).XData); ymax = max(plots(1).YData); ymin = min(plots(1).YData); else xmax = max(plots(1).Position(1)); xmin = min(plots(1).Position(1)); ymax = max(plots(1).Position(2)); ymin = min(plots(1).Position(2)); end for i = 2:length(plots) if ~strcmp(plots(i).Type,'text') xmax = max([xmax,max(plots(i).XData)]); xmin = min([xmin,min(plots(i).XData)]); ymax = max([ymax,max(plots(i).YData)]); ymin = min([ymin,min(plots(i).YData)]); else xmax = max([xmax,max(plots(i).Position(1))]); xmin = min([xmin,min(plots(i).Position(1))]); ymax = max([ymax,max(plots(i).Position(2))]); ymin = min([ymin,min(plots(i).Position(2))]); end end % Compute window sizes based on model bounding box size % increased by current free border factor. % Place window center at model bounding box center position %%%%% COMPLETE HERE - CANVAS_2D: 01 (REPEAT CANVAS_2D: 01 ABOVE %%%%% Lx = (xmax - xmin) * (1.0 + this.freeBorder); Mx = (xmax + xmin) * 0.5; Ly = (ymax - ymin) * (1.0 + this.freeBorder); My = (ymax + ymin) * 0.5; %%%%% COMPLETE HERE - CANVAS_2D: 01 (REPEAT CANVAS_2D: 01 ABOVE %%%%% y_x = Ly/Lx; % Adjust window limits such that window rectangle has same % aspect ratio of viewport rectangle if this.axIsEq %%%%% COMPLETE HERE - CANVAS_2D: 02 (REPEAT CANVAS_2D: 02 ABOVE) %%%%% if y_x > h_w Lx = Ly / h_w; else Ly = Lx * h_w; end %%%%% COMPLETE HERE - CANVAS_2D: 02 (REPEAT CANVAS_2D: 02 ABOVE) %%%%% end % Compute adjusted window limits %%%%% COMPLETE HERE - CANVAS_2D: 03 (REPEAT CANVAS_2D: 03 ABOVE) %%%%% xmin = Mx - (Lx * 0.5); xmax = Mx + (Lx * 0.5); ymin = My - (Ly * 0.5); ymax = My + (Ly * 0.5); %%%%% COMPLETE HERE - CANVAS_2D: 03 (REPEAT CANVAS_2D: 03 ABOVE) %%%%% this.ax.XLim = [xmin,xmax]; this.ax.YLim = [ymin,ymax]; % Set flag to indicate that bounding box was provided this.bBoxWasSet = true; end %------------------------------------------------------------------ % Mouse button down callback - related to axes object % Input: % * this = handle to this canvas object % * obj = handle to axes associated to canvas % * event = struct with event data function ax_onButtonDown(~,~,~) end %------------------------------------------------------------------ % Mouse button down callback - generic callback, called from an % Emouse object. % Input: % * this = handle to this canvas object % * pt = current cursor coordinates % * whichMouseButton = 'left', 'right', 'center', 'double click' function onButtonDown(~,~,~) end %------------------------------------------------------------------ % Mouse button up callback - generic callback, called from an % Emouse object. % Input: % * this = handle to this canvas object % * pt = current cursor coordinates % * whichMouseButton = 'left', 'right', 'center', 'double click' function onButtonUp(~,~,~) end %------------------------------------------------------------------ % Mouse move callback - generic callback, called from an % Emouse object. % Input: % * this = handle to this canvas object % * pt = current cursor coordinates function onMouseMove(~,~) end %------------------------------------------------------------------ % Mouse scroll callback - generic callback, called from an % Emouse object. % Input: % * this = handle to this canvas object % * pt = current cursor coordinates function onMouseScroll(~,~) end end
end