CrossDraw class

This class implements methods to plot graphical results from the Cross process of continuous beams.

Contents

Author

Luiz Fernando Martha

History

@version 1.00

Initial version (1.00): September 2026

Initially prepared for version Cross02 application of course CIV 2801 - Fundamentos de Computação Gráfica, 2026, second term, Department of Civil Engineering, PUC-Rio. Created model canvas and display of continuous beam model.

Class definition

classdef CrossDraw < handle

Public properties

    properties
        solver = []; % handle to an object of the CrossSolver class
    end

Class (constant) properties

    properties (Constant)
        supsize_fac = 0.02; % factor for support size
        loadsize_fac = 0.70; % factor for maximum load size in relation to
                             % half vertical window size
        minloadsize_fac = 0.012 % factor for minimum load size
        arrowsize_fac = 0.01; % factor for load arrow size
        loadstep_fac = 0.05; % factor for load step
        dimlineshift_fac = 0.85; % factor for down shift of dimension lines
                                 % with respect to half Y size
        dimlinetick_fac = 0.15; % factor for dimension line tick size
                                % with respect to half Y size
        maxdisplsize_fac = 0.60; % factor for maximum transversal size in
                                 % relation to half vertical window size
    end

Private properties

    properties (Access = private)
    end

Constructor method

    methods
        %------------------------------------------------------------------
        function draw = CrossDraw(solver)
            if (nargin > 0)
                draw.solver = solver;
            end
        end
    end

Class (static) auxiliary functions

    methods (Static)
        %------------------------------------------------------------------
        % Plots a square with defined center coordinates, side length and
        % color.
        % Input arguments:
        %  cnv: graphics context (axes)
        %  x: center coordinate on the X axis
        %  y: center coordinate on the Y axis
        %  l: side length
        %  c: color (RGB vector)
        function square(cnv,x,y,l,c)
            X = [x - l/2, x + l/2, x + l/2, x - l/2];
            Y = [y - l/2, y - l/2, y + l/2, y + l/2];
            fill(cnv, X, Y, c);
        end

        %------------------------------------------------------------------
        % Plots a draft version of a square with defined center coordinates,
        % side length and color.
        % It draws a hollow square and sets its parent property as the
        % given handle to the group of graphics objects.
        % Input arguments:
        %  cnv: graphics context (axes)
        %  hnd: handle to group of graphics objects
        %  x: center coordinate on the X axis
        %  y: center coordinate on the Y axis
        %  l: side length
        %  c: color (RGB vector)
        function draftSquare(cnv,hnd,x,y,l,c)
            X = [x - l/2, x + l/2, x + l/2, x - l/2, x - l/2];
            Y = [y - l/2, y - l/2, y + l/2, y + l/2, y - l/2];
            plot(cnv, X, Y, 'color', c, 'Parent', hnd);
        end

        %------------------------------------------------------------------
        % Plots a triangle with defined top coordinates, height, base,
        % orientation, and color.
        % Input arguments:
        %  cnv: graphics context (axes)
        %  x: top coordinate on the X axis
        %  y: top coordinate on the Y axis
        %  h: triangle height
        %  b: triangle base
        %  ang: angle (in radian) between the axis of symmetry and the
        %       horizontal direction (counterclockwise) - 0 rad when
        %       triangle is pointing left
        %  c: color (RGB vector)
        function triangle(cnv,x,y,h,b,ang,c)
            cx = cos(ang);
            cy = sin(ang);

            X = [x, x + h * cx + b/2 * cy, x + h * cx - b/2 * cy];
            Y = [y, y + h * cy - b/2 * cx, y + h * cy + b/2 * cx];
            fill(cnv, X, Y, c);
        end

        %------------------------------------------------------------------
        % Plots a draft version of a triangle with defined top coordinates,
        % height, base, orientation, and color.
        % It draws a hollow triangle and sets its parent property as the
        % given handle to the group of graphics objects.
        % Input arguments:
        %  cnv: graphics context (axes)
        %  hnd: handle to group of graphics objects
        %  x: top coordinate on the X axis
        %  y: top coordinate on the Y axis
        %  h: triangle height
        %  b: triangle base
        %  ang: angle (in radian) between the axis of symmetry and the
        %       horizontal direction (counterclockwise) - 0 rad when
        %       triangle is pointing left
        %  c: color (RGB vector)
        function draftTriangle(cnv,hnd,x,y,h,b,ang,c)
            cx = cos(ang);
            cy = sin(ang);

            X = [x, x + h * cx + b/2 * cy, x + h * cx - b/2 * cy, x];
            Y = [y, y + h * cy - b/2 * cx, y + h * cy + b/2 * cx, y];
            plot(cnv, X, Y, 'color', c, 'Parent', hnd);
        end

        %------------------------------------------------------------------
        % Plots a circle with defined center coordinates, radius and color.
        % This method is used to draw hinges on 2D models.
        % Input arguments:
        %  cnv: graphics context (axes)
        %  x: center coordinate on the X axis
        %  y: center coordinate on the Y axis
        %  r: circle radius
        %  c: color (RGB vector)
        function circle(cnv,x,y,r,c)
            circ = 0 : pi/50 : 2*pi;
            xcirc = x + r * cos(circ);
            ycirc = y + r * sin(circ);
            plot(cnv, xcirc, ycirc, 'color', c);
        end

        %------------------------------------------------------------------
        % Plots an arrow with defined beggining coordinates, length,
        % arrowhead height, arrowhead base, orientation, and color.
        % This method is used to draw load symbols on 2D models.
        % Input arguments:
        %  cnv: graphics context (axes)
        %  x: beggining coordinate on the X axis
        %  y: beggining coordinate on the Y axis
        %  l: arrow length
        %  h: arrowhead height
        %  b: arrowhead base
        %  ang: pointing direction (angle in radian with the horizontal
        %       direction - counterclockwise) - 0 rad when pointing left
        %  c: color (RGB vector)
        function arrow2D(cnv,x,y,l,h,b,ang,c)
            cx = cos(ang);
            cy = sin(ang);

            X = [x, x + l * cx];
            Y = [y, y + l * cy];
            line(cnv, X, Y, 'Color', c);
            CrossDraw.triangle(cnv, x, y, h, b, ang, c);
        end

        %------------------------------------------------------------------
        % Snap a value to the closest step value.
        function snap_val = snapToStepValue(val,step)
            fp = val / step;   % "fraction" part
            ip = floor(fp);    % integer part
            fp = fp - ip;
            if fp > 0.5
                snap_val = (ip + 1.0) * step;
            elseif fp < -0.5
                snap_val = (ip - 1.0) * step;
            else
                snap_val = ip * step;
            end
        end
    end

Protect methods

    methods (Access = protected) % Access from methods in subclasses
        function max_load = getMaxLoad(draw)
            max_load = 0;
            for i = 1:draw.solver.nmemb
                if(abs(draw.solver.membs(i).q) > max_load)
                    max_load = abs(draw.solver.membs(i).q);
                end
            end
        end

        %------------------------------------------------------------------
        % Draws a continuous beam model.
        % Input:
        % - posy: Y position of continuous beam axis.
        % - unbalanced_node: flag for unbalanced node.
        %      if  set, display corresponding support in red color.
        function beam(draw,cnv,posy,unbalanced_node)
            len = draw.solver.totalLen;
            line(cnv, [0, len], [posy, posy], 'Color', [0 0 0]);

%%%%%%% COMPLETE HERE - CROSSDRAW: 01 %%%%%%%
        end

        %------------------------------------------------------------------
        % Draw the uniform load of a member.
        % Input arguments:
        %  cnv: graphics context (axes)
        %  init_pos: initial position of load
        %  len: length of load
        %  q: uniform load value
        %  load_size: size of load
        %  load_step: step size for drawing arrows
        %  arrowsize: size of arrow head
        function memberLoad(~,cnv,init_pos,len,q,...
                            load_size,load_step,arrowsize)

%%%%%%% COMPLETE HERE - CROSSDRAW: 02 %%%%%%%
        end

        %------------------------------------------------------------------
        % Draw the dimension line of a beam span.
        % Input arguments:
        %  cnv: graphics context (axes)
        %  init_pos: initial position of dimension line
        %  len: length of dimension line
        %  dimline_shift: down shift of dimension line
        %  dimline_tick: size of dimension line tick
        function dimLine(~,cnv,init_pos,len,dimline_shift,dimline_tick)

%%%%%%% COMPLETE HERE - CROSSDRAW: 03 %%%%%%%
        end
    end

Public methods

    methods
        %------------------------------------------------------------------
        % Returns the bounding box (x and y limits) of a continuous beam
        % model. The returned box has xmin = 0, xmax = totalLen,
        % ymin = -totalLen * 0.05, ymax = +totalLen * 0.05, in which
        % totalLen is the length of the entire beam model.
        % The y limits are fictitious. They are equal in module and
        % equal to a small percentage of the total length to force
        % the adjustment of the box in the y direction, keeping y = 0
        % in the center of the canvas.
        function bbox = crossBoundBox(draw)
            totalLen = draw.solver.totalLen;
            bbox(1) =  0;
            bbox(2) = -totalLen * 0.05;
            bbox(3) =  totalLen;
            bbox(4) =  totalLen * 0.05;
        end

        %------------------------------------------------------------------
        % Draws a continuous beam model with applied loads.
        % Input:
        % - cnv: graphics context (owning canvas)
        function model(draw,cnv)
            % Clear canvas
            cla(cnv);

            % Draw continuous beam without highlighting unbalanced nodes
            draw.beam(cnv,0,false);

            % Draw applied loads
            halfYsize = diff(cnv.YLim) * 0.5;
            max_load = draw.getMaxLoad();
            arrowsize = draw.solver.totalLen * CrossDraw.arrowsize_fac;
            minload_size = draw.solver.totalLen * CrossDraw.minloadsize_fac;
            load_step = draw.solver.totalLen * CrossDraw.loadstep_fac;
            init_pos = 0;
            for i = 1:draw.solver.nmemb
                len = draw.solver.membs(i).len;
                load_size = CrossDraw.loadsize_fac * halfYsize * ...
                            (abs(draw.solver.membs(i).q) / max_load);
                if load_size < minload_size
                    load_size = minload_size;
                end
                q = draw.solver.membs(i).q;
                draw.memberLoad(cnv,init_pos,len,q,load_size,load_step,arrowsize);
                init_pos = init_pos + len;
            end

            % Draw dimension lines
            dimline_shift = halfYsize * CrossDraw.dimlineshift_fac;
            dimline_tick = halfYsize * CrossDraw.dimlinetick_fac;
            init_pos = 0;
            for i = 1:draw.solver.nmemb
                len = draw.solver.membs(i).len;
                draw.dimLine(cnv,init_pos,len,dimline_shift,dimline_tick);
                init_pos = init_pos + len;
            end
        end

        %------------------------------------------------------------------
        % Cleans data structure of a CrossSolver object.
        function draw = clean(draw)
            draw.solver = [];
        end
    end
end