Contents

%       CÀLCUL MATRICIAL D'ESTRUCTURES 2.0 "AKA CME2"
%
%               PER SERGIO GUERRERO MIRALLES
%
% TREBALL DE FINAL DE CARRERA D'ENGINYERIA TÉCNICA D'OBRES PÚBLIQUES
%       UNIVERSITAT POLITÉCNICA DE CATALUNYA, CURS 2011-2012
%
%
% Creació, edició, càlcul estàtic i mostra de resultats amb interfase
% gràfica d'estructures de barres articulades i reticulades, 2D i 3D, amb
% carregues a les barres.
%
%            Darrera versió 13 d'octubre de 2.012.
%

function cme2()

FUNCIÓ QUE S'EXECUTA A L'INICI, DEFINICIÓ DE L'ENTORN GRAFÌC:

% Inicialitza variables del programa i carrega les opcions.
[nusos,contnus,barres,diagrames,hgreaccions,contbarra,vista,flagbarra,primernusbarra,artprimernusbarra,artnusant,hbarra,flagclic,flagmourenus,posini,flagcalculat,s,xmin,xmax,ymin,ymax,zmin,zmax,xm,ym,zm,xmed,ymed,zmed,angle3d,grafica,sD,mov_extrems,TL2G,Retorn_reaccions,Retorn_moviments,Retorn_esforcos_barres,diag_presxy,diag_presxz,nom,fmax,qmax,contRotula,dadesRotules,numeroRotules,factorsCarrega,maximsBarres]=inicialitza_variables;
[editalcrear,barraalcrearnus,fontnusos,tamanyfontnusos,fontcarregues,tamanyfontcarregues,factorzoom,tamanynus,distnumnus,precini,XLimini,YLimini,ZLimini,colormodificar,coloresborrar,colorcarregues,colorreaccions,colordeformada,colorN,colorTy,colorTz,colorMx,colorMy,colorMz,direst]=loadopcions; % Carrega les opcions.

[figcme2,tm,bg]=creacio_finestra; % Crea la finestra principal del programa.
[barraeines,botobarracrear,botobarramodificar,botobarraesborrar,botobarranus,botobarrabarra,botobarracarreganus,botobarracarregabarra,botobarrarotula,botobarramoure,botobarraapropar,botobarraallunyar,botoEdicio,botoCentrar,botoXY,botoXZ,botoYZ,boto3D]=creacio_barra_eines; % Crea la barra d'eines.
creacio_menus % Crea la barra de menús.
[panel1,logo,grafica_resxy,grafica_resxz,txtbox_res,grafica_est,editx,edity,editz,editprec]=creacio_panell_grafica; % Crea el panell amb les grafiques i les caixes amb les coordenades i la precisió.
%[panel2,botoedicio,botoxy,botoxz,botoyz,boto3d]=panell_botons_vista; % Crea el panel amb els botons que controlen les vistes i els modes d'edició/presentació de resultats.
[panel3,botocarregues,botoreaccions,botodeformada,botoaxils,bototallantY,bototallantZ,botomomentX,botomomentY,botomomentZ]=panell_botons_grafica; % Panell amb els botons per seleccionar els elements que es mostrin en la presentació de resultats.
[panelPlastic,panelResultats,factorTotalResultat,factorParcialResultat,numeroTotalRotula,numeroRotula]=panell_botons_plastic(contRotula); %Crea el panell càlcul plàstic amb els corresponents botons.


botocalcular1=boto_calcular; % Botó per executar el càlcul.
[hg_nusos,hg_barres,hg_carreguesbarres,hg_carreganusos,hg_diagrames]=inicialitza_hg(grafica_est);
[panel4,botoCalculEstatic,botoCalculDinamic,botoCalculPlastic,botoCalculInestabilitat]=panell_botons_calcul;

% Un cop creats els objectes, el programa espera la interacció amb l'usuari
% i executa les accions programades als diferents objectes.

CREACIÓ I ACCIONS SOBRE LA FINESTRA PRINCIPAL, REDIMENSIONAMENT, CONTROL DEL RATOLÍ I TECLAT, ETC:

    function [nusos,contnus,barres,diagrames,hgreaccions,contbarra,vista,flagbarra,primernusbarra,artprimernusbarra,artnusant,hbarra,flagclic,flagmourenus,posini,flagcalculat,s,xmin,xmax,ymin,ymax,zmin,zmax,xm,ym,zm,xmed,ymed,zmed,angle3d,grafica,sD,mov_extrems,TL2G,Retorn_reaccions,Retorn_moviments,Retorn_esforcos_barres,diag_presxy,diag_presxz,nom,fmax,qmax,contRotula,dadesRotules,numeroRotules,factorsCarrega,maximsBarres]=inicialitza_variables
        % Funció que defineix les variables globals dels programa amb els
        % valors inicials. Aquestes variables són accesibles dins de l'espai de
        % treball de la funció principal del programa i les seves sub-funcions.
        % Apareixen de color blau a l'editor de Matlab.

        nusos=nus.empty(1,0); % Llista de nusos.
        contnus=0; % Comptador de nusos.
        barres=barra.empty(1,0); % Llista de barres.
        %Aixo es nou
        maximsBarres=maximsBarra.empty(1,0);
        factorsCarrega=minimFactorCarrega.empty(1,0);
        dadesRotules=dadesRotula.empty(1,0); %Llista de dades asignada a cada rotula
        contRotula=0;
        numeroRotules=0;
        %**********

        contbarra=0; % Comptador de barres.
        diagrames=diagrama.empty(1,0); % Llista de diagrames (1 objecte diagrama per a cada barra).
        hgreaccions=[]; % Llista d'objectes gràfics de reaccions.
        vista='xy'; % Mode de vista actual.
        flagbarra=0; % Flag que controla el proces de crear barres. S'activa quan s'ha clicat el primer nus a l'espera del segon.
        primernusbarra=0; % Primer nus clicat en el proces de crear barres.
        artprimernusbarra=0; % Estat del botó articulació en el moment de clicar el primer nus d'una barra.
        artnusant=0; % Estat del botó articulació en el moment de crear l'ultim nus creat.
        hbarra=0; % Linia temporal que representa la barra en construcció.
        flagclic=0; % Flag que indica si s'ha clicat un boto del ratoli i quin ha estat.
        flagmourenus=0; % Falg que indica a la funcio que detecta moviment del nus que s'ha clicat un nus amb el botó dret i s'ha de desplaçar.
        posini=zeros(2,6); % Posicio inicial del ratoli al moure la pantalla.
        flagcalculat=0; % Flag que indica que hi ha una estructura calculada.
        s=0; % Factor d'escala per als objectes gràfics que es mostren en pantalla: nusos, carregues, etc.
        xmin=[]; % Coordenada x minima de l'estructura.
        xmax=[]; % Coordenada x maxima de l'estructura.
        ymin=[]; % Coordenada y minima de l'estructura.
        ymax=[]; % Coordenada y maxima de l'estructura.
        zmin=[]; % Coordenada z minima de l'estructura.
        zmax=[]; % Coordenada z maxima de l'estructura.
        xmed=[]; % Mitjana de les coordenades x mínima i màxima de l'estructura.
        ymed=[]; % Mitjana de les coordenades y mínima i màxima de l'estructura.
        zmed=[]; % Mitjana de les coordenades z mínima i màxima de l'estructura.
        angle3d=0; % Angle de rotació a la vista 3d.
        xm=0; % Mitjana de les coordenades x de l'estructura.
        ym=0; % Mitjana de les coordenades y de l'estructura.
        zm=0; % Mitjana de les coordenades z de l'estructura.
        grafica=0; % grafica que s'esta mostrant, grafica de l'estructura o grafiques de resultats detallats per barra.
        sD=1; % Escala de la deformada.
        mov_extrems=[]; % Moviments en extrems de barra en eixos locals.
        TL2G=[]; % Matrius de canvi de base de les barres.
        Retorn_reaccions=[]; % Reaccions en eixos globals.
        Retorn_moviments=[]; % Moviments en eixos locals.
        Retorn_esforcos_barres=[]; % Esforços en extrems de barra en eixos locals.
        diag_presxy=diagrama; % Objecte diagrama que conte els diagrames detallats per barra en xy.
        diag_presxz=diagrama; % Objecte diagrama que conte els diagrames detallats per barra en xz.
        nom=''; % Nom de l'estructura actual
        fmax=0; % Força aplicada als nusos o puntual maxima.
        qmax=0; % Càrrega repartida o projectada maxima.
    end

    function [figcme2,tm,bg]=creacio_finestra
        % Creació de la finestra:
        set(0,'Units','pixels') % Per obtenir el tamany de la pantalla en pixels i no en cap altre messura extraña.
        sc=get(0,'ScreenSize'); % Obté el tamany de la pantalla.
        tm=[1272 618]; % Tamany de la finestra a la pantalla.
        ps=(sc(3:4)-tm)/2-[0,18];% Posicio de la finestra, centrada a la pantalla.
        bg=get(0,'defaultUicontrolBackgroundColor'); % Obté el color de fons per defecte.
        figcme2=figure('Units','pixels','Position',[ps,tm],'NumberTitle','off','Name','Càlcul Matricial d´Estructures 2.0','Resize','on','color',bg,'Toolbar','figure','MenuBar','none','ResizeFcn',@figcme2_resize,'WindowButtonMotionFcn',@moviment_ratoli,'WindowButtonDownFcn',@clic_figure,'WindowButtonUpFcn',@unclic_figure,'WindowScrollWheelFcn',@roda_ratoli,'CloseRequestFcn',@sortir,'KeyPressFcn',@tecla); % Crea la finestra principal del programa.
    end

    function figcme2_rename
        if nom
            set(figcme2,'Name',['Càlcul Matricial d´Estructures 2.0 - ',nom])
        else
            set(figcme2,'Name','Càlcul Matricial d´Estructures 2.0')
        end
    end

    function figcme2_resize(hObject,eventdata,handles)
    % Recoloca els panells quan es redimensiona la finestra principal del
    % programa.
        sc=get(figcme2,'Position'); % Posicio i tamany de la pantalla despres de redimensionar.
        tm=sc(3:4); % Tamany de la finestra a la pantalla.
        if tm(1)<500 % Limita el mínim horitzontal a 500 píxels.
            tm(1)=500;
            set(figcme2,'Position',[sc(1:2),tm]);
        end
        if tm(2)<425 % Limita el mínim Vertical a 425 píxels.
            sc(2)=sc(2)+tm(2)-425;
            tm(2)=425;
            set(figcme2,'Position',[sc(1:2),tm]);
        end
        % Canvia posició i tamany dels panells i elements.
        set(panel1,'Position',[5,5,tm-[125,35]]); % Panell de la grafica.
        %set(panel2,'Position',[tm-[120,190],115,195]); % Panell dels botons de les vistes.
        set(panel3,'Position',[tm-[115,195],115,200]); % Panell dels botons de la gràfica.
        set(panelPlastic,'Position',[tm-[115,625],115,430]); %Panell de càlcul plàstic
        set(panel4,'Position',[tm-[1360,25],115,200]); % Panell dels botons de la gràfica.
        set(botocalcular1,'Position',[tm(1)-115,5,115,25]); % Boto calcular.
        set(grafica_est,'Position',[36,50,tm-[176,70]]);
        set(logo,'Position',[36,50,tm-[176,70]]);
        set(grafica_resxy,'Position',[36,(tm(2)+30)/2,(tm-[182,70])/2]);
        set(grafica_resxz,'Position',[36,50,(tm-[182,70])/2]);
        set(txtbox_res,'Position',[tm(1)/2-49,50,tm(1)/2-87,tm(2)-70]);
        centrar
    end

    function clic_figure(hObject,eventdata,handles)
        % S'executa sempre que es premi el botó del ratoli.
        % No confondre amb la funció clic_ratoli ni altres, clic_figure
        % s'executa sempre abans i es cliqueji sobre la grafica o qualsevol
        % altre objecte, és més genèrica i complementa les altres funcions.
        % Discrimina segons el tipus de pulsació i l'enmagatzema a la
        % variable flagclic de manera que al pitjar sobre un element gràfic
        % es puguin programar diferents efectes.

        switch get(figcme2,'SelectionType')
            case 'normal' % Botó esquerre
                flagclic=1;
                if strcmp(get(botobarramoure,'State'),'on')
                    posini=get(grafica_est,'currentpoint');
                end
            case 'open' % Doble clic
                flagclic=2;
            case 'alt'
                flagclic=3; % Control i botó esquerre o botó dret
            case 'extend'
                flagclic=4; % Shift i botó esquerre, botó central o ambdós botons
                posini=get(grafica_est,'currentpoint');
                set(figcme2,'Pointer','hand');
        end
    end

    function unclic_figure(hObject,eventdata,handles)
        % S'executa a l'alliberar el botó del ratolí.

        flagclic=0; % Restitueix la variable que defineix el tipus de clic.
        flagmourenus=0; % Si s'estava movent un nus, restitueix el flag perque no es mogui el nus amb el moviment del ratoli.

        % Per si estava movent la pantalla (cursor amb forma de ma) torna
        % al cursor de fletxa o al que correspongui.
        if strcmp(get(botobarramoure,'State'),'on')
            set(figcme2,'Pointer','hand');
        elseif strcmp(get(botobarraapropar,'State'),'on') || strcmp(get(botobarraallunyar,'State'),'on')
            set(figcme2,'Pointer','circle');
        else
            set(figcme2,'Pointer','arrow');
        end
    end

    function roda_ratoli(hObject,eventdata)
        % Amplia i redueix la grafica al fer rodar la rodeta del ratolí.

        zom(eventdata.VerticalScrollCount/factorzoom)
    end

    function [] = zom(factor)
        % Amplia i redueix la gràfica.

        %disp('Zoom')
        %tic_zom=tic;
        if grafica==grafica_est
            posbruta=get(grafica_est,'currentpoint'); % Posició del cursor.
            lim=[get(grafica_est,'XLim');get(grafica_est,'YLim');get(grafica_est,'ZLim')]; % Llegeix l'escala dels eixos.

            frac = (posbruta(1,:)'-lim(:,1))./(lim(:,2)-lim(:,1));
            an=(lim(:,2)-lim(:,1))*2^factor; % Amplada multiplicada per 2 elevat al factor d'ampliació.
            lim(:,1) = posbruta(1,:)' - an.*frac;
            lim(:,2) = posbruta(1,:)' + an.*(1-frac);

            % med=(lim(:,2)+lim(:,1))/2; % Punt mig.
            % an=(lim(:,2)-lim(:,1))*2^factor; % Amplada multiplicada per 2 elevat al factor d'ampliació.
            % lim=[med-an/2, med+an/2]; % Nova escala dels eixos.

            set(grafica_est,'XLim',lim(1,:),'YLim',lim(2,:),'ZLim',lim(3,:)); % Fixa la nova escala.
            escala % Calcula el factor d'escala s.
            escalar_nusos % Reescala els nusos i les seves carregues.
            redibuixar_carregues_barres % Redibuixa les càrregues sobre les barres amb la nova escala.
            clicable % Estableix quins objectes responen al ratoli segons els botons de la barra.
        end
        %disp(['/Zoom: ',num2str(toc(tic_zom))])
    end

    function moviment_ratoli(hObject,eventdata,handles)
        % S'executa quan es mou el ratolí sobre la finestra de l'aplicació.
        % Actualitza els valors de les caixes de texte que mostren la posició
        % del ratolí.
        % Al crear una barra crea l'efecte de que la línia segueix el cursor.
        % Si es prem la rodeta permet moure la gràfica.
        % Si es prem el botó dret mou nusos.
        set(botoCentrar,'State','off');%Desactiva el botoCentrar kuan el ratoli ja no esta sobre el mateix
        posbruta=get(grafica_est,'currentpoint'); % Posició del cursor.
        precisio=str2double(get(editprec,'String')); % Precisió definida a la seva caixa de texte.
        posicio=round(posbruta(1,1:3)/precisio)*precisio; % Redondeja la posició a la precisió establerta.

        % Actualitza la posició a les caixes de texte.
        switch vista
            case 'xy'
                set(editx,'String',num2str(posicio(1))); % A la vista al plànol xy actualitza posicions x i y.
                set(edity,'String',num2str(posicio(2)));
                posicio(3)=str2double(get(editz,'String'));
            case 'xz'
                set(editx,'String',num2str(posicio(1))); % A la vista al plànol xz actualitza posicions x i z.
                posicio(2)=str2double(get(edity,'String'));
                set(editz,'String',num2str(posicio(3)));
            case 'yz'
                posicio(1)=str2double(get(editx,'String')); % A la vista al plànol yz actualitza posicions y i z.
                set(edity,'String',num2str(posicio(2)));
                set(editz,'String',num2str(posicio(3)));
            case '3d'
                set(editx,'String','');
                set(edity,'String','');
                set(editz,'String','');
        end

        % Si s'està creant una bara actualitza les coordenades amb la posició del cursor.
        if flagbarra
            x=get(hbarra,'XData');
            y=get(hbarra,'YData');
            z=get(hbarra,'ZData');
            set(hbarra,'XData',[x(1) posbruta(1,1)],'YData',[y(1) posbruta(1,2)],'ZData',[z(1) posbruta(1,3)]);
        end

        % Si s'ha pres la rodeta del ratolí o el botó moure modifica els
        % límits de la gràfica creant l'efecte de moviment.
        if flagclic ==4 || (flagclic ==1 && strcmp(get(botobarramoure,'State'),'on'))
            mov=posbruta-posini; % posini es la posició anterior.
            mov=mov(1,:);
            if ~strcmp(vista,'3d')
                xl=get(grafica_est,'XLim');
                xl=xl-[mov(1),mov(1)];
                yl=get(grafica_est,'YLim')-[mov(2),mov(2)];
                zl=get(grafica_est,'ZLim')-[mov(3),mov(3)];
                set(grafica_est,'XLim',xl,'YLim',yl,'ZLim',zl);
            end
        end

        % Amb el botó dret pres sobre un nus permet moure'l sobre la
        % gràfica.
        if flagmourenus && ~get(boto3d,'Value')
            nusos(flagmourenus).posicio=posicio; % flagmourenus conte el handle del nus.
            escala % Calcula el factor d'escala s.
            redibuixar_nusos % Redibuixa els nusos per tal de que es reorientin segons els nous extrems.
            redibuixar_barres % Actualitza el dibuix de les barres.
            escalar_nusos % Reescala els nusos i les seves carregues.
            redibuixar_carregues_barres % Redibuixa les càrregues sobre les barres amb la nova escala.
            clicable % Estableix quins objectes responen al ratoli segons els botons de la barra.
        end
    end

    function tecla(hObject,eventdata,handles)
        % S'executa cada cop que es pitja una tecla.
        % Permet diferents accions en diferents moments.

        % Si s'està creant una barra permet abortar prement escapament.
        if flagbarra && strcmp(eventdata.Key,'escape')
            flagbarra=0; % Posa a 0 el flag de que s'està creant barra.
            delete(hbarra) % Esborra la línia.
            hbarra=[];
        elseif strcmp(eventdata.Key,'escape') && grafica~=grafica_est
            clic_grafica_res
        else  %Si estem a grafica_est, cas general, desactiva els botons d'accio
            botons_accions('off','off','off','off','off','off')
        end


        % Amplia o redueix l'escala de la deformada prement '+' o '-'.
        if ~strcmp(get(botoEdicio,'State'),'on') && get(botodeformada,'Value') && flagcalculat
            if strcmp(eventdata.Character,'-')
                sD=sD/2^(1/4); % Divideix l'escala per l'arrel quarta de 2, amb 4 pulsacions es divideix l'escala per 2.
            elseif strcmp(eventdata.Character,'+')
                sD=sD*2^(1/4); % Multiplica l'escala per l'arrel quarta de 2, amb 4 pulsacions es duplica l'escala.
            end
            for i=1:numel(diagrames)
                escala_deformada(TL2G(:,:,i),i,sD); % Actualitza la deformada a totes les barres.
            end
        end

        % Si es pitja return en qualsevol moment equival a pitjar el botó
        % calcular.
        if strcmp(eventdata.Key,'return')
            calcular
        end

        %Si es pitja C, botó crear
        if strcmp(eventdata.Key,'c')
             botocrear
        end
        %m modificar
        if strcmp(eventdata.Key,'m')
             botomodificar
        end
        %e esborrar
        if strcmp(eventdata.Key,'e')
             botoesborrar
        end
        %n nus
        if strcmp(eventdata.Key,'n')
             botonus
        end
        %b barra
        if strcmp(eventdata.Key,'b')
             botobarra
        end
        %p puntual
        if strcmp(eventdata.Key,'p')
             botocarreganus
        end
        %q distribuida
        if strcmp(eventdata.Key,'q')
             botocarregabarra
        end


        % Moviment dels cursor al mode de vista 3d per rotar, apropar i
        % allunyar l'estructura.
        if strcmp(vista,'3d')
            switch eventdata.Key
                case 'leftarrow' % Si es prem la tecla de fletxa esquerra.
                    mov=-pi/36; % Gira l'estructura 5º.
                    angle3d=angle3d+mov; % angle de rotació.
                    ct=[xm,ym,zm]; % Punt 'camera target' centre de l'estructura.
                    set(grafica_est,'CameraPosition',ct+[cos(angle3d),1,sin(angle3d)]); % Vista isomètrica.
                case 'rightarrow' % Si es prem la tecla de fletxa dreta.
                    mov=pi/36; % Gira l'estructura 5º.
                    angle3d=angle3d+mov; % angle de rotació.
                    ct=[xm,ym,zm]; % Punt 'camera target' centre de l'estructura.
                    set(grafica_est,'CameraPosition',ct+[cos(angle3d),1,sin(angle3d)]); % Vista isomètrica.
                case 'uparrow' % Si es prem la tecla de fletxa a dalt.
                    zom(-3/factorzoom); % Apropa l'estuctura.
                case 'downarrow' % Si es prem la tecla de fletxa a baix.
                    zom(3/factorzoom); % Allunya l'estructura.
            end
        end

    end

CREACIÓ I ACCIONS DE LA BARRA D'EINES I ELS SEUS BOTONS:

    function [barraeines,botobarracrear,botobarramodificar,botobarraesborrar,botobarranus,botobarrabarra,botobarracarreganus,botobarracarregabarra,botobarrarotula,botobarramoure,botobarraapropar,botobarraallunyar,botoEdicio,botoCentrar,botoXY,botoXZ,botoYZ,boto3D]=creacio_barra_eines
        % Crea una nova barra d'eines i defineix els botons.
        % Per als botons de zoom i moviment en copia l'imatge de la barra
        % per defecte de Matlab, però només la imatge, les accions estan
        % reprogramades per tal de tenir el control i que Matlab no faci
        % accions extrañes.

        barraperdefecte=findall(figcme2,'Type','uitoolbar'); % Handle de la barra d'eines per defecte de Matlab, es manté activa mentre es copien alguns botons.
        barraeines=uitoolbar; % Creació d'una barra d'eines pròpia.
        botobarracrear=uitoggletool('TooltipString','Crear (C)','CData',imread('lapiz.png','BackgroundColor',bg),'State','on','ClickedCallback',@botocrear); % Defineix el botó crear.
        botobarramodificar=uitoggletool('TooltipString','Modificar (M)','Cdata',imread('editar.png','BackgroundColor',bg),'ClickedCallback',@botomodificar); % Defineix el botó modificar.
        botobarraesborrar=uitoggletool('TooltipString','Esborrar (E)','CData',imread('goma.png','BackgroundColor',bg),'ClickedCallback',@botoesborrar); % Defineix el boto esborrar.
        botobarranus=uitoggletool('Separator','on','TooltipString','Nus (N)','CData',imread('nudo.png','BackgroundColor',bg),'State','on','ClickedCallback',@botonus); % Defineix el botó nus.
        botobarrabarra=uitoggletool('TooltipString','Barra (B)','CData',imread('barra.png','BackgroundColor',bg),'ClickedCallback',@botobarra); % Defineix el botó barres.
        botobarracarreganus=uitoggletool('TooltipString','Càrrega en nus (P)','CData',imread('carganudo.png','BackgroundColor',bg),'ClickedCallback',@botocarreganus); % Defineix el botó carrega als nusos.
        botobarracarregabarra=uitoggletool('TooltipString','Càrrega en barra (Q)','CData',imread('cargabarra.png','BackgroundColor',bg),'ClickedCallback',@botocarregabarra); % Defineix el botó càrrega a les barres.
        botobarrarotula=uitoggletool('Separator','on','TooltipString','Extrems de barra articulats','CData',imread('rotula.png','BackgroundColor',bg)); % Extrem de barra articulat.
        botobarramoure=uitoggletool('Separator','on','TooltipString','Moure''s','CData',get(findall(barraperdefecte,'TooltipString','Pan'),'CData'),'ClickedCallback',@botomoure); % Defineix el botó moure copiant l'aspecte de la barra d'eines original.
        botobarraapropar=uitoggletool('TooltipString','Apropar-se','CData',get(findall(barraperdefecte,'TooltipString','Zoom In'),'CData'),'ClickedCallback',@botoapropar); % Defineix el botó apropar copiant l'aspecte de la barra d'eines original.
        botobarraallunyar=uitoggletool('TooltipString','Allunyar-se','CData',get(findall(barraperdefecte,'TooltipString','Zoom Out'),'CData'),'ClickedCallback',@botoallunyar);% Defineix el botó allunyar copiant l'aspecte de la barra d'eines original.

        botoEdicio=uitoggletool('Separator','on','TooltipString','Edició','CData',imread('edit.png','BackgroundColor',bg),'State','on','ClickedCallback',@edicio);
        botoReixeta=uitoggletool('TooltipString','Reixeta','CData',imread('grid.png','BackgroundColor',bg),'ClickedCallback',@reixeta);
        botoCentrar=uitoggletool('TooltipString','Centrar','CData',imread('target.png','BackgroundColor',bg),'ClickedCallback',@centrar);

        botoXY=uitoggletool('TooltipString','XY','CData',imread('XY.png','BackgroundColor',bg),'ClickedCallback',@vistaxy);
        botoXZ=uitoggletool('TooltipString','XZ','CData',imread('XZ.png','BackgroundColor',bg),'ClickedCallback',@vistaxz);
        botoYZ=uitoggletool('TooltipString','YZ','CData',imread('YZ.png','BackgroundColor',bg),'ClickedCallback',@vistayz);
        boto3D=uitoggletool('TooltipString','3D','CData',imread('3D.png','BackgroundColor',bg),'ClickedCallback',@vista3d);

        set(figcme2,'Toolbar','none'); % Es desactiva la barra d'eines original.
    end

    function botocrear(hObject,eventdata,handles)
        % S'executa quan s'activa el botó crear.
        %disp('boto crear')
        botons_accions('on','off','off','off','off','off')
    end
    function botomodificar(hObject,eventdata,handles)
        % S'executa quan s'activa el botó modificar.
        %disp('boto modificar')
        botons_accions('off','on','off','off','off','off')
    end
    function botoesborrar(hObject,eventdata,handles)
        % S'executa quan s'activa el botó esborrar.
        %disp('boto esborrar')
        botons_accions('off','off','on','off','off','off')
    end
    function botomoure(hObject,eventdata,handles)
        % S'executa quan s'activa el botó moure.
        botons_accions('off','off','off','on','off','off')
    end
    function botoapropar(hObject,eventdata,handles)
        % S'executa quan s'activa el botó zoom apropar.
        botons_accions('off','off','off','off','on','off')
    end
    function botoallunyar(hObject,eventdata,handles)
        % S'executa quan s'activa el botó zoom allunyar.
        botons_accions('off','off','off','off','off','on')
    end
    function botonus(hObject,eventdata,handles)
        % S'executa quan s'activa el botó nus.
        botons_elements('on','off','off','off')
    end
    function botobarra(hObject,eventdata,handles)
        % S'executa quan s'activa el botó barra.
        botons_elements('off','on','off','off')
    end
    function botocarreganus(hObject,eventdata,handles)
        % S'executa quan s'activa el botó càrrega sobre nus.
        botons_elements('off','off','on','off')
    end
    function botocarregabarra(hObject,eventdata,handles)
        % S'executa quan s'activa el botó càrrega sobre barra.
        botons_elements('off','off','off','on')
    end
    function botons_accions(bcrear,bmodificar,besborrar,bmoure,bapropar,ballunyar)
        % Es desactiven la resta de botons del grup.
        set(botobarracrear,'State',bcrear);
        set(botobarramodificar,'State',bmodificar);
        set(botobarraesborrar,'State',besborrar);
        if strcmp('off',bmoure)
            set(botobarramoure,'State',bmoure);
        end
        if strcmp('off',bapropar)
            set(botobarraapropar,'State',bapropar);
        end
        if strcmp('off',ballunyar)
            set(botobarraallunyar,'State',ballunyar);
        end
        colors
        clicable % Modifica colors dels elements gràfics i hi defineix si es poden cliquejar, segons el cas.
    end
    function botons_elements(bnus,bbarra,bcarreganus,bcarregabarra)
        % Esdesactiven la resta de botons del grup.
        set(botobarranus,'State',bnus);
        set(botobarrabarra,'State',bbarra);
        set(botobarracarreganus,'State',bcarreganus);
        set(botobarracarregabarra,'State',bcarregabarra)
        colors
        clicable % Modifica colors dels elements gràfics i hi defineix si es poden cliquejar, segons el cas.
    end
    function clicable(hObject,eventdata,handles)
        % Modifica l'estat dels objectes gràfics que representen nusos,
        % barres i càrregues, perque acceptin clic de ratolí o no, de
        % manera que els que no s'hagin de clicar no interfereixin
        % entorpint el programa.

        %disp('Clicable')
        %tic_clicable=tic;
        if strcmp(get(botoEdicio,'State'),'on')
            if strcmp(get(botobarracrear,'State'),'on') % Si s'esta creant...
                if strcmp(get(botobarranus,'State'),'on') % nusos, es cliqueja directament sobre la gràfica, es desactiven els clics als objectes gràfics.
                    canviestat('off','off','off','off')
                    %canviestat('on','off','off','off')
                elseif strcmp(get(botobarrabarra,'State'),'on') % barres, s'activen els clics als nusos.
                    canviestat('on','off','off','off')
                    %canviestat('on','on','off','off')
                elseif strcmp(get(botobarracarreganus,'State'),'on') % carregues en nusos, s'activen els clics als nusos.
                    canviestat('on','off','off','off')
                elseif strcmp(get(botobarracarregabarra,'State'),'on')% càrregues a les barres, s'activen clics a les barres.
                    canviestat('off','on','off','off')
                end
            elseif strcmp(get(botobarramodificar,'State'),'on') || strcmp(get(botobarraesborrar,'State'),'on') % Si s'està modificant o esborrant...
                if strcmp(get(botobarranus,'State'),'on') % nusos, s'activen els clics als nusos.
                    canviestat('on','off','off','off')
                elseif strcmp(get(botobarrabarra,'State'),'on') % barres, s'activen els clics a les barres.
                    canviestat('off','on','off','off')
                elseif strcmp(get(botobarracarreganus,'State'),'on') % càrregues en nusos, s'activen els clics a les càrregues als nusos.
                    canviestat('off','off','on','off')
                elseif strcmp(get(botobarracarregabarra,'State'),'on') % càrregues a les barres, s'activen els clics a les càrregues a les barres.
                   canviestat('off','off','off','on')
                end
            else
                canviestat('on','off','off','off') % Per defecte, que es pugui cliquejar als nusos per moure'ls.
            end
        else
            canviestat('off','on','off','on') % S'activen clics a les barres.
        end
        if strcmp(get(botobarramoure,'State'),'on') % Canvia el cursor.
            set(figcme2,'Pointer','hand')
        elseif strcmp(get(botobarraapropar,'State'),'on') || strcmp(get(botobarraallunyar,'State'),'on')
            set(figcme2,'Pointer','circle')
        else
            set(figcme2,'Pointer','arrow')
        end
        %set(grafica,'Children',sort(get(grafica,'Children'))); % Reordena els objectes de la grafica.
        %colors % Canvia els colors dels elements.
        %disp(['/Clicable: ',num2str(toc(tic_clicable))])
    end
    function canviestat(clicnus,clicbarra,cliccarreganus,cliccarregabarra)
        % Canvia l'estat de si es poden clicar o no els objectes gràfics.
        for j=1:contnus
            set(nusos(j).hg,'HitTest',clicnus) % Objectes que representen els nusos.
            set(nusos(j).hgc,'HitTest',cliccarreganus) % Objectes que representen les carregues als nusos.
        end
        for j=1:contbarra
            set(barres(j).hg,'HitTest',clicbarra) % Objectes línies que representen les barres.
            set(barres(j).hgpuntual,'HitTest',cliccarregabarra); % Objectes que representen les càrregues puntuals sobre les barres.
            set(barres(j).hgmoment,'HitTest',cliccarregabarra); % Objectes que representen les càrregues moment sobre les barres.
            set(barres(j).hgrepartida,'HitTest',cliccarregabarra); % Objectes que representen les càrregues repartides sobre les barres.
            set(barres(j).hgprojectada,'HitTest',cliccarregabarra); % Objectes que representen les càrregues projectades sobre les barres.
        end
    end
    function colornusos(hObject,eventdata,handles)
        % Actualitza el color dels nusos segons la situació.

        %disp('Color nusos')
        %tic_cn=tic;
        if strcmp(get(botobarranus,'State'),'on') && strcmp(get(botoEdicio,'State'),'on') % Si esta activat el botó nusos i el mode edició.
            if strcmp(get(botobarramodificar,'State'),'on') % Si està activat el botó modificar.
                color=colormodificar; % Assigna als nusos amb el color definit.
            elseif strcmp(get(botobarraesborrar,'State'),'on') % Si està activat el botó esborrar.
                color=coloresborrar; % Assigna als nusos amb el color definit.
            else
                color='k'; % Color d'edicio per defecte negre.
            end
        else
            color='k'; % Color presentacio per defecte negre.
        end
        for i=1:contnus
            chgcolor(nusos(i).hg,color) % Canvia el color.
        end
        %disp(['/Color nusos: ',num2str(toc(tic_cn))])
    end
    function colorbarres(hObject,eventdata,handles)
        % Actualitza el color de les barres segons la situació.

        %disp('Color barres')
        %tic_cb=tic;
        if strcmp(get(botobarrabarra,'State'),'on') && strcmp(get(botoEdicio,'State'),'on') % Si esta activat el botó barres i el mode edició.
            if strcmp(get(botobarramodificar,'State'),'on') % Si està activat el botó modificar.
                color=colormodificar; % Assigna a les barres el color definit.
            elseif strcmp(get(botobarraesborrar,'State'),'on') % Si està activat el botó esborrar.
                color=coloresborrar; % Assigna a les barres el color definit.
            else
                color='k'; % Color per defecte al mode d'edicio.
            end
        else
            color='k'; % Color per defecte al mode de presentació.
        end
        if strcmp(color,'k') % Si s'ha assignat el color per defecte, el substitueix pel color definit a les propietats de la barra.
            for i=1:contbarra
                set(barres(i).hg,'color',barres(i).color) % Canvia el color.
            end
        else
            for i=1:contbarra
                set(barres(i).hg,'color',color) % Canvia el color pel negre.
            end
        end
        %disp(['/Color barres: ',num2str(toc(tic_cb))])
    end
    function colorcarreganusos(hObject,eventdata,handles)
        % Actualitza el color de les càrregues sobre els nusos segons la
        % situació.

        %disp('Color carrega nusos')
        %tic_cn=tic;
        if strcmp(get(botobarracarreganus,'State'),'on') && strcmp(get(botoEdicio,'State'),'on') % Si està activat el botó de càrregues als nusos i el mode edició.
            if strcmp(get(botobarramodificar,'State'),'on') % Si està activat el botó modificar.
                color=colormodificar; % Assigna a les càrregues el color definit.
            elseif strcmp(get(botobarraesborrar,'State'),'on') % Si està activat el botó esborrar.
                color=coloresborrar; % Assigna a les càrregues el botó definit.
            else
                color='k'; % Color d'edicio per defecte negre.
            end
        elseif strcmp(get(botoEdicio,'State'),'on')
            color='k'; % Color d'edicio per defecte negre.
        else
            color=colorcarregues; % Color presentacio definit.
        end
        for i=1:contnus
            chgcolor(nusos(i).hgc,color) % Canvia el color.
        end
        %disp(['/Color carrega nusos: ',num2str(toc(tic_cn))])
    end
    function colorcarregabarres(hObject,eventdata,handles)
        % Actualitza el color de les càrregues sobre les barres segons la
        % situació.

        %disp('Color carrega barres')
        %tic_cb=tic;
        if strcmp(get(botobarracarregabarra,'State'),'on') && strcmp(get(botoEdicio,'State'),'on') % Si està activat el botó de càrregues a les barres i el mode edició.
            if strcmp(get(botobarramodificar,'State'),'on') % Si està activat el botó modificar.
                color=colormodificar; % Assigna a les càrregues el color definit.
            elseif strcmp(get(botobarraesborrar,'State'),'on') % Si està activat el botó esborrar.
                color=coloresborrar; % Assigna a les càrregues el botó definit.
            else
                color='k'; % Color d'edicio per defecte negre.
            end
        elseif strcmp(get(botoEdicio,'State'),'on')
            color='k'; % Color d'edicio per defecte negre.
        else
            color=colorcarregues; % Color presentacio definit.
        end
        for i=1:contbarra
            chgcolor(barres(i).hgpuntual,color) % Canvia el color de les càrregues puntuals.
            chgcolor(barres(i).hgmoment,color) % Canvia el color dels moments.
            chgcolor(barres(i).hgrepartida,color) % Canvia el color de les càrregues repartides.
            chgcolor(barres(i).hgprojectada,color) % Canvia el color de les càrregues projectades.
        end
        %disp(['/Color carrega barres: ',num2str(toc(tic_cb))])
    end
    function colors(hObject,eventdata,handles)
        % Actualitza color de nusos, barres i càrregues.

        %disp('Colors')
        %tic_col=tic;
        colornusos
        colorbarres
        colorcarreganusos
        colorcarregabarres
        %disp(['/Colors: ',num2str(toc(tic_col))])
    end
    function chgcolor(h,color)
        % Funció que canvia els colors dels objectes continguts en un
        % objecte hgtransform.

        set(findobj(h,'Type','line'),'color',color) % Color de les línines.
        set(findobj(h,'Type','text'),'color',color) % Color dels textos.
        set(findobj(h,'Type','patch'),'FaceColor',color,'EdgeColor',color) % Color dels patch.
    end

CREACIÓ I ACCIONS DE LA BARRA DE MENÚS:

    function creacio_menus
        % Crea la barra de menús.

        menuarxiu=uimenu(figcme2,'Label','Arxiu'); % Menú principal 'arxiu'.
        uimenu(menuarxiu,'Label','Nou','Callback',@menunou); % Sub-menú 'nou'.
        uimenu(menuarxiu,'Label','Carregar','Callback',@menucarregar);% Sub-menú 'carregar'.
        uimenu(menuarxiu,'Label','Guardar','Callback',@menuguardar,'Separator','on'); % Sub-menú 'guardar'.
        uimenu(menuarxiu,'Label','Guardar com a...','Callback',@menuguardarcom); % Sub-menu 'guardar com'.
        uimenu(menuarxiu,'Label','Sortir','Callback',@sortir,'Separator','on'); % Sub-menú 'sortir'.
        menuopcions=uimenu(figcme2,'Label','Opcions'); % Menú princiapl 'opcions'.
        uimenu(menuopcions,'Label','Editar opcions','Callback',@opcions); % Sub-menú 'editar opcions'.
    end
    function menunou(hObject,eventdata,handles)
        % S'executa amb el menú 'nou'
        % Pregunta si es vol guardar i esborra l'estructura.

        resp=questdlg('Guardar abans d''esborrar l''estructura?','Nova estructura','Si','No','Cancelar','Si');
        switch resp
            case 'Si'
                menuguardar
                nou
            case 'No'
                nou
        end
    end
    function nou
        % Esborra les dades.

        %disp('Nou')
        %tic_nou=tic;
        if grafica~=grafica_est % Si s'esta presentant resultats de barra.
            clic_grafica_res
        end
        %Aixo es nou
        maximsBarres=maximsBarra.empry(1,0);
        factorsCarrega=minimFactorCarrega.empty(1,0); %nova llista d'objectes factor càrrega
        dadesRotules=dadesRotula.empty(1,0); %nova llista d'objectes rotula
        numeroRotules=0;
        contRotula=0;
        popupMenu = uicontrol(panelPlastic,'Style','popupmenu','String',numeroRotules,'Position',[5 205 100 200], 'callback', @popupcallback); %Actualitza el popupmenu de càlcul plàstic
        %******************************************************************
        nusos=nus.empty(1,0); % nova llista d'objectes nus.
        contnus=0; % comptador de nusos a zero.
        barres=barra.empty(1,0); % nova llista d'objectes barra.
        contbarra=0; % comptador de barres a zero.
        hgreaccions=[]; % esborra la llista de reaccions.
        diagrames=diagrama.empty(1,0); % nova llista d'objectes diagrama.
        delete(get(grafica,'Children')) % esborra tots els objectes gràfics.
        %set(grafica_est,'XLim',XLimini,'YLim',YLimini,'ZLim',ZLimini) % Estableix els límits originals.
        [hg_nusos,hg_barres,hg_carreguesbarres,hg_carreganusos,hg_diagrames]=inicialitza_hg(grafica_est);
        centrar
       set(botoEdicio,'State','on'); % Torna al mode edició.
        edicio % Esborra diagrames, etc..
        nom=''; % Esborra el nom de l'estructura.
        figcme2_rename % Canvia el títol.
        fmax=0;
        qmax=0;
        %disp(['/Nou: ',num2str(toc(tic_nou))])
    end
    function menucarregar(hObject,eventdata,handles)
        % Carrega una estructura previament guardada.

        carpetaactual=cd(direst); % Es coloca a la carpeta on es guarden els treballs i guarda la carpeta actual de Matlab.
        [arxiu,carpeta]=uigetfile('*.cme2','Carregar'); % Obre la finestra per seleccionar arxiu.
        cd(carpetaactual) % Un cop seleccionat l'arxiu torna a la carpeta de Matlab.

        %disp('Carregar')
        %tic_carregar=tic;
        if arxiu % Si s'ha seleccionat un arxiu...
            direst = carpeta;  %emmagatzema l'última carpeta d'on s'ha carregat
            if grafica~=grafica_est % Si s'esta presentant resultats de barra.
                clic_grafica_res
            end
            [nusos,barres,contnus,contbarra]=carregararxiu(fullfile(carpeta,arxiu)); % Carrega les dades.
            % Esborra les dades de treballs anteriors.
            delete(get(grafica,'Children'))
            hgreaccions=[];
            diagrames=diagrama;
            for i=1:contnus
                nusos(i).hg=[];
                nusos(i).hgc=[];
            end

            for i=1:contbarra
                barres(i).hg=[];
                barres(i).hgpuntual=[];
                barres(i).hgmoment=[];
                barres(i).hgrepartida=[];
                barres(i).hgprojectada=[];
            end
            [hg_nusos,hg_barres,hg_carreguesbarres,hg_carreganusos,hg_diagrames]=inicialitza_hg(grafica_est);
            flagcalculat=0;
            maxpuntual % Calcula carrega puntual maxima.
            maxrepartida % Calcula carrega repartida o projectada maxima.
            redibuixar_nusos % Dibuixa els nusos.
            redibuixar_barres % Dibuixa les barres.
            redibuixa_carreganusos % Dibuixa les càrregues als nusos.
            centrar % Centra l'estructura a la pantalla.
            set(botoEdicio,'State','on'); % Torna al mode edició.
            edicio
            nom=arxiu; % Nom de l'estructura.
            figcme2_rename % Canvia el títol.
        end
        figure(figcme2) % Retorna el focus a la finestra del programa, si no es fa el programa no respondrà fins que no es cliqueji sobre la finestra.
        %disp(['/Carregar: ',num2str(toc(tic_carregar))])
    end
    function menuguardar(hObject,eventdata,handles)
        % Guarda les dades sobre l'estructura actual per recuperar-la més
        % endavant.

        %disp('Guardar')
        %tic_guardar=tic;
        if nom
            carpetaactual=cd(direst); % Es coloca a la carpeta on es guarden els treballs i guarda la carpeta actual de Matlab.
            save(fullfile(direst,nom),'nusos','barres','-mat'); % Guarda les llistes de nusos i de barres que formen l'estructura.
            cd(carpetaactual) % Torna a la carpeta de Matlab.
            figure(figcme2) % Retorna el focus a la finestra del programa, si no es fa el programa no respondrà fins que no es cliqueji sobre la finestra.
        else
            menuguardarcom
        end
        %disp(['/Guardar: ',num2str(toc(tic_guardar))])
    end
    function menuguardarcom(hObject,eventdata,handles)
        % Guarda les dades sobre l'estructura actual per recuperar-la més
        % endavant.

        %disp('Guardar com')
        %tic_guardar=tic;
        carpetaactual=cd(direst); % Es coloca a la carpeta on es guarden els treballs i guarda la carpeta actual de Matlab.
        [arxiu,carpeta]=uiputfile('*.cme2','Guardar com a...',nom); % Obre el diàleg per seleccionar o crear un arxiu.
        if arxiu % Si s'ha seleccionat un arxiu
            nom=arxiu; % N'assigna el nom a l'estructura
            figcme2_rename % Canvia el títol.
            save(fullfile(carpeta,arxiu),'nusos','barres','-mat'); % Guarda les llistes de nusos i de barres que formen l'estructura.
            direst = carpeta;
        end
        cd(carpetaactual) % Torna a la carpeta de Matlab.
        figure(figcme2) % Retorna el focus a la finestra del programa, si no es fa el programa no respondrà fins que no es cliqueji sobre la finestra.
        %disp(['/Guardar com: ',num2str(toc(tic_guardar))])
    end
    function sortir(hObject,eventdata,handles)
        % Surt del programa.
        % S'executa al pitjar sobre l'aspa o al premer el menú sortir.
        % Executa un msgbox per confirmar i guardar l'estructura.

        resp=questdlg('Guardar abans de sortir?','Sortir de CME2','Si','No','Cancelar','Si');
        switch resp
            case 'Si'
                menuguardar
                delete(figcme2) % Esborra la finestra.
            case 'No'
                delete(figcme2) % Esborra la finestra.
        end
        save('opcions','editalcrear','barraalcrearnus','fontnusos','tamanyfontnusos','fontcarregues','tamanyfontcarregues','factorzoom','tamanynus','distnumnus','precini','XLimini','YLimini','ZLimini','colormodificar','coloresborrar','colorcarregues','colorreaccions','colordeformada','colorN','colorTy','colorTz','colorMx','colorMy','colorMz','direst')

    end
    function opcions(hObject,eventdata,handles)
        % S'executa al seleccionar el menú d'edició de les opcions del
        % programa.

        dlgopcions % Obre la finestra per modificar les opcions, que les guardara a l'arxiu opcions.mat.
        [editalcrear,barraalcrearnus,fontnusos,tamanyfontnusos,fontcarregues,tamanyfontcarregues,factorzoom,tamanynus,distnumnus,precini,XLimini,YLimini,ZLimini,colormodificar,coloresborrar,colorcarregues,colorreaccions,colordeformada,colorN,colorTy,colorTz,colorMx,colorMy,colorMz,direst]=loadopcions; % Carrega les opcions de l'arxiu opcions.mat.

        %disp('Opcions')
        %tic_opcions=tic;
        % Modifica els colors dels botons segons les opcions.
        set(botocarregues,'Foregroundcolor',colorcarregues);
        set(botoreaccions,'Foregroundcolor',colorreaccions);
        set(botodeformada,'Foregroundcolor',colordeformada);
        set(botoaxils,'Foregroundcolor',colorN);
        set(bototallantY,'Foregroundcolor',colorTy);
        set(bototallantZ,'Foregroundcolor',colorTz);
        set(botomomentX,'Foregroundcolor',colorMx);
        set(botomomentY,'Foregroundcolor',colorMy);
        set(botomomentZ,'Foregroundcolor',colorMz);

        for i=1:contnus
            set(findobj(nusos(i).hg,'type','text'),'FontName',fontnusos,'FontSize',tamanyfontnusos)
            set(findobj(nusos(i).hgc,'type','text'),'FontName',fontcarregues,'FontSize',tamanyfontcarregues)
            if flagcalculat
                set(findobj(hgreaccions(i),'type','text'),'FontName',fontcarregues,'FontSize',tamanyfontcarregues)
            end
        end

        colors
        clicable % Estableix quins objectes responen al ratoli segons els botons de la barra.
        %disp(['/Opcions: ',num2str(toc(tic_opcions))])
    end

CREACIÓ I ACCIONS SOBRE EL PANELL QUE CONTÉ LES GRÀFIQUES, LES COORDENADES I LA PRECISIÓ.

    function [panel1,logo,grafica_resxy,grafica_resxz,txtbox_res,grafica_est,editx,edity,editz,editprec]=creacio_panell_grafica
        % Creació de la pantalla gràfica:
        panel1=uipanel(figcme2,'Units','pixels','Position',[5,5,tm-[130,40]],'BorderType','etchedin','BorderWidth',1); % Creacio del panell.
        logo=axes('Parent',panel1,'Units','pixels','Position',[36,50,tm-[176,70]]); % Objecte axes on es carreguen els logos.
        imagesc(imread('logo.jpg'),'ButtonDownFcn',@clic_grafica_res); % Carrega dels logos.
        set(logo,'handlevisibility','off','Visible','off'); % S'oculten els marges i es fa inaccessible. Queda com a imatge de fons sense alterar al treballar amb l'estructura, ampliar, reduïr, moure, etc.
        grafica_resxy=axes('Parent',panel1,'Units','pixels','Position',[36,(tm(2)+30)/2,(tm-[182,50])/2],'Box','on','color','none','NextPlot','add','Visible','off','ButtonDownFcn',@clic_grafica_res); % Pantalla de presentació de resultats de barra en eixos xy locals.
        grafica_resxz=axes('Parent',panel1,'View',[0,0],'Units','pixels','Position',[36,50,(tm-[182,50])/2],'Box','on','color','none','NextPlot','add','Visible','off','ButtonDownFcn',@clic_grafica_res); % Pantalla de presentació de resultats de barra en eixos xz locals.
        txtbox_res=uicontrol(panel1,'Units','pixels','Position',[tm(1)/2-49,50,tm(1)/2-182,tm(2)-70],'Style','edit','max',2,'FontName','default','FontUnits','pixels','FontSize',12,'HorizontalAlignment','left','BackgroundColor','white','Visible','off'); % Editbox on es presenta l'informe de resultats.
        grafica_est=axes('Parent',panel1,'Units','pixels','Position',[36,50,tm-[176,10]],'color','none','MinorGridLineStyle',':','ButtonDownFcn',@clic_ratoli,'NextPlot','add','XLim',XLimini,'YLim',YLimini,'Box','on'); % Pantalla de treball amb la gràfica de l'estructura.
        uicontrol(panel1,'Units','pixels','Position',[36,5,15,20],'Style','text','FontName','default','FontUnits','pixels','FontSize',14,'HorizontalAlignment','left','String','X:'); % Etiqueta.
        editx=uicontrol(panel1,'Units','pixels','Position',[51,5,50,20],'Style','edit','FontName','default','FontUnits','pixels','FontSize',14,'HorizontalAlignment','right','BackgroundColor','white','Enable','off'); % Caixa on s'indica o introueix la coordenada x.
        uicontrol(panel1,'Units','pixels','Position',[111,5,15,20],'Style','text','FontName','default','FontUnits','pixels','FontSize',14,'HorizontalAlignment','left','String','Y:'); % Etiqueta.
        edity=uicontrol(panel1,'Units','pixels','Position',[126,5,50,20],'Style','edit','FontName','default','FontUnits','pixels','FontSize',14,'HorizontalAlignment','right','BackgroundColor','white','Enable','off'); % Caixa on s'indica o introdueix la coordenada y.
        uicontrol(panel1,'Units','pixels','Position',[186,5,15,20],'Style','text','FontName','default','FontUnits','pixels','FontSize',14,'HorizontalAlignment','left','String','Z:'); % Etiqueta.
        editz=uicontrol(panel1,'Units','pixels','Position',[201,5,50,20],'Style','edit','FontName','default','FontUnits','pixels','FontSize',14,'HorizontalAlignment','right','BackgroundColor','white','String','0'); % Caixa on s'indica o introdueix la coordenada z.
        uicontrol(panel1,'Units','pixels','Position',[256,5,59,20],'Style','text','FontName','default','FontUnits','pixels','FontSize',14,'HorizontalAlignment','left','String','Precisió:'); % Etiqueta.
        editprec=uicontrol(panel1,'Units','pixels','Position',[315,5,50,20],'Style','edit','FontName','default','FontUnits','pixels','FontSize',14,'HorizontalAlignment','right','BackgroundColor','white','String',num2str(precini));  % Caixa on s'introdueix la precisió a l'introduïr punts amb el ratolí.
        grafica=grafica_est;
    end
   function clic_ratoli(hObject,eventdata,handles)
        % S'executa quan es cliqueja sobre la pantalla gráfica.
        % flagclic es la variable que crea la funció clic_figure, que s'executa
        % just abans i indica el botó que s'ha pres.

        % Si es cliqueja el botó esquere sobre el planol amb els botons de
        % la barra crear i nus en mode edició crea un nus.
        if flagclic==1 &&strcmp(get(botoEdicio,'State'),'on') && strcmp(get(botobarracrear,'State'),'on') && strcmp(get(botobarranus,'State'),'on') && ~strcmp(vista,'3d')
            crearnus
        % Si s'està en mode zoom amplia o redueix segons el cas.
        elseif (flagclic==1 && strcmp(get(botobarraapropar,'State'),'on')) || (flagclic==3 && strcmp(get(botobarraallunyar,'State'),'on'))
            zom(-3/factorzoom);
        elseif (flagclic==1 && strcmp(get(botobarraallunyar,'State'),'on')) || (flagclic==3 && strcmp(get(botobarraapropar,'State'),'on'))
            zom(3/factorzoom);
        end
   end
    function clic_nus(gcbo,eventdata,handles)
        % S'executa quan es cliqueja sobre un nus.
        % Dins del camp 'UserData' de l'objecte gràfic que representa al
        % nus hi ha enmagatzemat el seu número per tal d'identificar-lo.

        n=get(gcbo,'UserData'); % Número de nus.
        if flagclic==1 && strcmp(get(botoEdicio,'State'),'on') % Si s'ha pres el botó esquerre i s'està en mode d'edició, depenent dels botons de la barra s'excuta una acció o una altra.
            if strcmp(get(botobarraesborrar,'State'),'on') && strcmp(get(botobarranus,'State'),'on')
                esborrarnus(n)
            elseif strcmp(get(botobarramodificar,'State'),'on') && strcmp(get(botobarranus,'State'),'on')
                modificarnus(n)
            elseif strcmp(get(botobarracrear,'State'),'on') && strcmp(get(botobarrabarra,'State'),'on')
                crearbarra(n)
            elseif strcmp(get(botobarracrear,'State'),'on') && strcmp(get(botobarracarreganus,'State'),'on')
                crearmodificarcarreganus(n)
            end
        elseif flagclic==3 && ~flagbarra && strcmp(get(botoEdicio,'State'),'on') % Si s'ha pres el botó dret sobre el nus permet moure'l.
            flagmourenus=n; % Activa el flag que indica que es modifiqui la posició del nus amb el moviment del ratolí, a mes el flag conté el handle de l'objecte grafic que representa el nus.
        end
    end
    function clic_carreganus(gcbo,eventdata,handles)
        % S'executa quan es cliqueja sobre la carrega d'un nus.
        % Dins del camp 'UserData' de l'objecte gràfic que representa la
        % carrega hi ha enmagatzemat el número de nus per tal
        % d'identificar-lo.

        n=get(gcbo,'UserData'); % Número de nus.
        if flagclic==1 && strcmp(get(botoEdicio,'State'),'on') && strcmp(get(botobarracarreganus,'State'),'on')% Si s'ha pres el botó esquerre i s'està en mode d'edició, depenent dels botons de la barra s'excuta una acció o una altra.
            if strcmp(get(botobarraesborrar,'State'),'on')
                esborrarcarreganus(n)
            elseif strcmp(get(botobarramodificar,'State'),'on')
                crearmodificarcarreganus(n)
            end
        end
    end
    function clic_barra(gcbo,eventdata,handles)
        % S'executa quan es cliqueja sobre una barra.
        % Dins del camp 'UserData' de la línia que representa la
        % barra hi ha enmagatzemat el seu número per tal d'identificar-la.

        n=get(gcbo,'UserData'); % Número de barra.
        if flagclic==1 && strcmp(get(botoEdicio,'State'),'on') % Si s'ha pres el botó esquerre i s'està en mode edició, depenent dels botons de la barra s'executa una acció o una altra.
            if strcmp(get(botobarraesborrar,'State'),'on') && strcmp(get(botobarrabarra,'State'),'on')
                esborrarbarra(n)
                redibuixar_nusos
                escalar_nusos
            elseif strcmp(get(botobarramodificar,'State'),'on') && strcmp(get(botobarrabarra,'State'),'on')
                modificarbarra(n)
            elseif strcmp(get(botobarracrear,'State'),'on') && strcmp(get(botobarracarregabarra,'State'),'on')
                crearmodificarcarregabarra(n)
            end
         elseif flagclic==1 % Si es pren sobre la barra en el mode de presentacio de resultats, presenta els resultats per a la barra seleccionada.
            resultat_barra(n)
        end
    end
    function clic_carregabarra(gcbo,eventdata,handles)
        % S'executa quan es cliqueja sobre la càrrega d'una barra.
        % Dins del camp 'UserData' de l'objecte grafic que representa la
        % càrrega hi ha enmagatzemat el seu número per tal d'identificar-la.

        n=get(gcbo,'UserData'); % Número de barra.
        if flagclic==1 && strcmp(get(botoEdicio,'State'),'on') % Si s'ha pres el botó esquerre i s'està en mode edició, depenent dels botons de la barra s'executa una acció o una altra.
            if strcmp(get(botobarraesborrar,'State'),'on') && strcmp(get(botobarracarregabarra,'State'),'on')
                esborrarcarregabarra(n)
            elseif strcmp(get(botobarramodificar,'State'),'on') && strcmp(get(botobarracarregabarra,'State'),'on')
                crearmodificarcarregabarra(n)
            end
        elseif flagclic==1 % Si s'ha pres el botó esquerre en la presentacio de resultats.
            resultat_barra(n)
        end
    end
    function [hg_nusos,hg_barres,hg_carreguesbarres,hg_carreganusos,hg_diagrames]=inicialitza_hg(graficaest)
       hg_diagrames = hgtransform('Parent',graficaest);
       hg_carreguesbarres = hgtransform('Parent',graficaest);
       hg_carreganusos = hgtransform('Parent',graficaest);
       hg_barres = hgtransform('Parent',graficaest);
       hg_nusos = hgtransform('Parent',graficaest);
    end

%%CREACIÓ I ACCIONS SOBRE EL PANELL QUE CONTÉ ELS BOTONS DELS DIFERENTES
%%TIPUS DE CÁLCUL

    function  [panel4,botoCalculEstatic,botoCalculDinamic,botoCalculPlastic,botoCalculInestabilitat]=panell_botons_calcul
         panel4=uipanel(figcme2,'Units','pixels','Position',[tm-[1100,25],115,30],'BorderType','etchedin','BorderWidth',0,'FontName','default','FontUnits','pixels','FontSize',14,'Title',''); % Creacio del panell.
         botoCalculEstatic=uicontrol(panel4,'Units','pixels','Position',[-1,-1,310,25],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','Càlcul estàtic','Value',1,'Callback',@calcul_estatic,'KeyPressFcn',@tecla); % Creació botó calcul estàtic
         botoCalculDinamic=uicontrol(panel4,'Units','pixels','Position',[310,-1,310,25],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','Càlcul dinàmic','Value',0,'Callback',@calcul_dinamic,'KeyPressFcn',@tecla); % Creació botó càlcul dinàmic
         botoCalculPlastic=uicontrol(panel4,'Units','pixels','Position',[621,-1,310,25],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','Càlcul plàstic','Value',0,'Callback',@calcul_plastic,'KeyPressFcn',@tecla); % Creació botó càlcul plàstic
         botoCalculInestabilitat=uicontrol(panel4,'Units','pixels','Position',[932,-1,310,25],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','Càlcul inestabilitat','Value',0,'Callback',@calcul_inestabilitat,'KeyPressFcn',@tecla); % Creació botó càlcul inestabilitat
    end

    function calcul_estatic(hObject,eventdata,handles) %Opcions que s'activen al apretar el botó càlcul estàtic
        if get(hObject,'Value')
             %Posa les altres pestanyes en off
             set(botoCalculPlastic,'Value',0);
             set(botoCalculDinamic','Value',0);
             set(botoCalculInestabilitat,'Value',0);
             %Desactiva els panells que no corresponguin al càlcul estàtic
             set(panelPlastic,'Visible','off');
         end
    end
    function calcul_dinamic(hObject,eventdata,handles)%Opcions que s'activen al apretar el botó càlcul dinàmic
        if get(hObject,'Value')
             %Posa les altres pestanyes en off
             set(botoCalculEstatic,'Value',0);
             set(botoCalculPlastic','Value',0);
             set(botoCalculInestabilitat,'Value',0);
             %Desactiva els panells que no corresponguin al càlcul dinàmic
             set(panelPlastic,'Visible','off');
        end
    end
    function calcul_plastic(hObject,eventdata,handles)%Opcions que s'activen al apretar el botó càlcul plàstic
        if get(hObject,'Value')
             %Posa les altres pestanyes en off
            set(botoCalculEstatic,'Value',0);
            set(botoCalculDinamic','Value',0);
            set(botoCalculInestabilitat,'Value',0);
            %Desactiva els panells que no corresponguin al càlcul plastic

            %Activa el panell corresponent al càlcul plàstic
            set(panelPlastic,'Visible','on');

            esborra_diagramesireaccions %esborra reaccions i diagrames si n'hi han.
        end
    end
    function calcul_inestabilitat(hObject,eventdata,handles)  %Opcions que s'activen al apretar el botó càlcul inestabilitat
        if get(hObject,'Value')
             %Posa les altres pestanyes en off
             set(botoCalculPlastic,'Value',0);
             set(botoCalculDinamic','Value',0);
             set(botoCalculEstatic','Value',0);

             %Desactiva els panells que no corresponguin al càlcul
             %inestabilitat
             set(panelPlastic,'Visible','off');

        end
    end

CREACIÓ I ACCIONS SOBRE EL PANELL QUE CONTÉ ELS BOTONS QUE CONTROLEN LES VISTES I EL MODE EDICIÓ/PRESENTACIÓ DE RESULTATS.

    function [panel2,botoedicio,botoxy,botoxz,botoyz,boto3d]=panell_botons_vista
        % Creació del panell amb els botons.
        panel2=uipanel(figcme2,'Units','pixels','Position',[tm-[120,190],115,195],'BorderType','etchedin','BorderWidth',1,'FontName','default','FontUnits','pixels','FontSize',14,'Title','Vista:'); % Creacio del panell.
        botoedicio=uicontrol(panel2,'Units','pixels','Position',[5,150,105,25],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','Edició','Value',1,'Callback',@edicio,'KeyPressFcn',@tecla); % Creació botó edició.
        botoreixeta=uicontrol(panel2,'Units','pixels','Position',[5,120,105,25],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','Reixeta','Callback',@reixeta,'KeyPressFcn',@tecla); % Creació boto reixeta.
        botocentrar=uicontrol(panel2,'Units','pixels','Position',[5,90,105,25],'Style','pushbutton','FontName','default','FontUnits','pixels','FontSize',14,'String','Centrar','Callback',@centrar,'KeyPressFcn',@tecla); % Creació botó centrar.
        botoxy=uicontrol(panel2,'Units','pixels','Position',[5,45,50,35],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','XY','Callback',@vistaxy,'Value',1,'KeyPressFcn',@tecla); % Creació botó vista XY.
        botoxz=uicontrol(panel2,'Units','pixels','Position',[60,45,50,35],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','XZ','Callback',@vistaxz,'KeyPressFcn',@tecla); % Creació botó vista XZ.
        botoyz=uicontrol(panel2,'Units','pixels','Position',[5,5,50,35],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','YZ','Callback',@vistayz,'KeyPressFcn',@tecla); % Creació botó vista YZ.
        boto3d=uicontrol(panel2,'Units','pixels','Position',[60,5,50,35],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','3D','Callback',@vista3d,'KeyPressFcn',@tecla); % Creació vista 3D.
    end

    function edicio(hObject,eventdata,handles)
        % Mode edicio/presentació
        % Si s'ha pitjat el botó edició esborra els diagrames, fa visibles
        % les carregues i torna als colors d'edició.

        %disp('Edicio')
        %tic_edicio=tic;
        if strcmp(get(botoEdicio,'State'),'on') % Si el boto edició esta pitjat.
            flagcalculat=0; % Es restableix el flag que indica que hi ha una estrucuctura ja calculada.
            set(get(panel3,'Children'),'Enable','off') % Es desactiven els botons que controlen els resultats.
            set(get(barraeines,'Children'),'Enable','on') % S'activen els botons de la barra d'eines.
            esborra_diagramesireaccions % Esborra els diagrames
            maxpuntual % Calcula maxima força puntual sense tenir en compte reaccions
            redibuixar_carregues_barres % Redibuixa les carregues a les barres
            redibuixa_carreganusos % Redibuixa les carregues als nusos
            escalar_nusos % Escala els nusos
        else % Si el botó edició no està pitjat...
            set(get(panel3,'Children'),'Enable','on') % Activa els botons que controlen la mostra de resultats.
            set(botobarracrear,'Enable','off') % Desactiven els botons de la barra d'eines.
            set(botobarramodificar,'Enable','off')
            set(botobarraesborrar,'Enable','off')
            set(botobarranus,'Enable','off')
            set(botobarrabarra,'Enable','off')
            set(botobarracarreganus,'Enable','off')
            set(botobarracarregabarra,'Enable','off')

            diagcarregues % Mostra les càrregues si estan seleccionades.
            diagreaccions % Mostra les reaccions si estan seleccionades.
            visibilitat_diagrames % Mostra els diagrames i la deformade si estan seleccionats.
        end
        clicable % Estableix quins objectes son susceptibles de ser cliquejats segons l'estat de la bara d'eines
        colors
        %disp(['/Edicio: ',num2str(toc(tic_edicio))])
    end

    function reixeta(hObject,eventdata,handles)
        % Activa i desactiva la reixeta.

        if  strcmp(get(hObject,'State'),'on')
            grid on
            %grid minor % Reixeta més tupida.
        else
            grid off
        end
    end

    function centrar(hObject,eventdata,handles)
        % Centra l'estructura a la gràfica i estableix els límits.

        %disp('Centrar')
        %tic_centrar=tic;
        if grafica==grafica_est % Si s'estan mostrant els resultats en detall per barra no es fa res.
            calcul_cord_extrems % Càlcul de les coordenades extremes de la estructura.

            tam=get(grafica_est,'Position'); % Posició i tamany de la grafica. Valors de tamany horitzontal en tam(3), i en Vertical en tam(4).

            switch vista
                case 'xy'
                    if (xmax-xmin)*tam(4)/tam(3)<(ymax-ymin) % Si la relació alçada/amplada de l'estructura es mes gran que la de la gràfica...
                        ampx=(ymax-ymin)*tam(3)/tam(4); % Amplada horitzontal en funció de l'alçada Vertical.
                        ampy=(ymax-ymin);
                        XL=[xmed-ampx/1.5,xmed+ampx/1.5];
                        YL=[ymed-ampy/1.5,ymed+ampy/1.5];
                    elseif xmax==xmin && ymax==ymin
                        XL=XLimini+[xmed,xmed];
                        YL=XLimini*tam(4)/tam(3)+[ymed,ymed];
                    else % Si la relació alçada/amplada és menor que la de la gràfica...
                        ampx=(xmax-xmin);
                        ampy=(xmax-xmin)*tam(4)/tam(3); % Alçada en funció de l'amplada
                        XL=[xmed-ampx/1.5,xmed+ampx/1.5];
                        YL=[ymed-ampy/1.5,ymed+ampy/1.5];
                    end
                    set(grafica_est,'XLim',XL,'YLim',YL,'ZLim',ZLimini); % Assigna els valors als eixos de la gràfica.
                case 'xz'
                    if (xmax-xmin)*tam(4)/tam(3)<(zmax-zmin) % Si la relació alçada/amplada de l'estructura es mes gran que la de la gràfica...
                        ampx=(zmax-zmin)*tam(3)/tam(4); % Amplada horitzontal en funció de l'alçada Vertical.
                        ampz=zmax-zmin;
                        XL=[xmed-ampx/1.5,xmed+ampx/1.5];
                        ZL=[zmed-ampz/1.5,zmed+ampz/1.5];
                    elseif xmax==xmin && zmax==zmin
                        XL=XLimini+[xmed,xmed];
                        ZL=XLimini*tam(4)/tam(3)+[zmed,zmed];
                    else % Si la relació alçada/amplada és menor que la de la gràfica...
                        ampx=xmax-xmin;
                        ampz=(xmax-xmin)*tam(4)/tam(3); % Alçada en funció de l'amplada
                        XL=[xmed-ampx/1.5,xmed+ampx/1.5];
                        ZL=[zmed-ampz/1.5,zmed+ampz/1.5];
                    end
                    set(grafica_est,'XLim',XL,'YLim',YLimini,'ZLim',ZL); % Assigna els valors als eixos de la gràfica.
                case 'yz'
                    if (ymax-ymin)*tam(4)/tam(3)<(zmax-zmin) % Si la relació alçada/amplada de l'estructura es mes gran que la de la gràfica...
                        ampy=(zmax-zmin)*tam(3)/tam(4); % Amplada horitzontal en funció de l'alçada Vertical.
                        ampz=zmax-zmin;
                        YL=[ymed-ampy/1.5,ymed+ampy/1.5];
                        ZL=[zmed-ampz/1.5,zmed+ampz/1.5];
                    elseif ymax==ymin && zmax==zmin
                        YL=YLimini+[ymed,ymed];
                        ZL=YLimini*tam(4)/tam(3)+[zmed,zmed];
                    else % Si la relació alçada/amplada és menor que la de la gràfica...
                        ampy=ymax-ymin;
                        ampz=(ymax-ymin)*tam(4)/tam(3); % Alçada en funció de l'amplada
                        YL=[ymed-ampy/1.5,ymed+ampy/1.5];
                        ZL=[zmed-ampz/1.5,zmed+ampz/1.5];
                    end
                    set(grafica_est,'XLim',XLimini,'YLim',YL,'ZLim',ZL); % Assigna els valors als eixos de la gràfica.
                case '3d'
                    ct=[xm,ym,zm]; % Punt 'camera target' centre de l'estructura.
                    minlim=min([xmin,ymin,zmin]); % Mínim
                    maxlim=max([xmax,ymax,zmax]); % Màxim
                    angle3d=pi/4;
                    set(grafica_est,'XLim',[minlim,maxlim],'YLim',[minlim,maxlim],'ZLim',[minlim,maxlim],'CameraPosition',ct+[cos(angle3d),1,sin(angle3d)]); % Vista isomètrica.
            end
            escala % Calcula el factor d'escala s.
            escalar_nusos % Reescala els nusos i les seves carregues.
            redibuixar_carregues_barres % Redibuixa les càrregues sobre les barres amb la nova escala.
            clicable % Estableix quins objectes responen al ratoli segons els botons de la barra.
        end
        %disp(['/Centrar: ',num2str(toc(tic_centrar))])
    end

    function calcul_cord_extrems
        % Calcula les coordenades extremes i mitjes de l'estructura.

        if contnus % Si hi ha nusos definits...
            xmin=nusos(1).posicio(1);
            xmax=nusos(1).posicio(1);
            ymin=nusos(1).posicio(2);
            ymax=nusos(1).posicio(2);
            zmin=nusos(1).posicio(3);
            zmax=nusos(1).posicio(3);
            xm=nusos(1).posicio(1);
            ym=nusos(1).posicio(2);
            zm=nusos(1).posicio(3);
            for i=2:contnus % Si hi ha més d'un nus...
                xmin=min(xmin,nusos(i).posicio(1)); % x mínima
                xmax=max(xmax,nusos(i).posicio(1)); % x màxima
                xm=xm+nusos(i).posicio(1); % sumatori de x
                ymin=min(ymin,nusos(i).posicio(2));
                ymax=max(ymax,nusos(i).posicio(2));
                ym=ym+nusos(i).posicio(2);
                zmin=min(zmin,nusos(i).posicio(3));
                zmax=max(zmax,nusos(i).posicio(3));
                zm=zm+nusos(i).posicio(3);
            end
            xm=xm/contnus; % crea la mitja de x
            ym=ym/contnus;
            zm=zm/contnus;
        else % Si no hi ha nusos definits...
            xmin=XLimini(1)*0.75;
            xmax=XLimini(2)*0.75;
            ymin=YLimini(1)*0.75;
            ymax=YLimini(2)*0.75;
            zmin=ZLimini(1)*0.75;
            zmax=ZLimini(2)*0.75;
            xm=(XLimini(1)+XLimini(2))*0.75/2;
            ym=(YLimini(1)+YLimini(2))*0.75/2;
            zm=(ZLimini(1)+ZLimini(2))*0.75/2;
        end
        xmed=(xmin+xmax)/2; % mitja dels extrems de x
        ymed=(ymin+ymax)/2;
        zmed=(zmin+zmax)/2;
    end

    function vistaxy(hObject,eventdata,handles)
        % S'executa quan es selecciona la vista XY.

        %disp('Vista XY')
        %tic_xy=tic;
        if strcmp(get(hObject,'State'),'on') && grafica==grafica_est
            vista='xy'; % Variable global vista controla el mode de vista actual del programa.
            set(botoYZ,'State','off');
            set(botoXZ,'State','off');
            set(boto3D,'State','off');


            set(grafica_est,'View',[0,90],'Box','on'); % Vista del plànol XY.
            set(editx,'Enable','off'); % Desactiva la caixa de text amb la coordenada en x perque no es pugui editar.
            set(edity,'Enable','off'); % Desactiva la caixa de text amb la coordenada en y perque no es pugui editar.
            set(editz,'Enable','on','String','0'); % Activa la caixa de text amb la coordenada z per editar la profunditat.
            redibuixar_nusos
            redibuixar_barres
            redibuixa_carreganusos
            %redibuixar_carregues_barres
            if flagcalculat
                esborra_diagramesireaccions
                dibuixa_reaccions
                dibuixa_diagramesideformada
                diagcarregues
                diagreaccions
                visibilitat_diagrames % Mostra els diagrames i la deformade si estan seleccionats.
            end
            centrar % Centra l'estructura a la gràfica.
        else
            set(hObject,'Value',abs(get(hObject,'Value')-1)); % Evita que es deseleccioni la vista, el que faria que no hi hagués cap seleccionada.
        end
        %disp(['/Vista XY: ',num2str(toc(tic_xy))])
    end

    function vistaxz(hObject,eventdata,handles)
        % S'executa quan es selecciona la vista XZ.

        %disp('Vista XZ')
        %tic_xz=tic;
        if strcmp(get(hObject,'State'),'on') && grafica==grafica_est
            vista='xz'; % Variable global vista controla el mode de vista actual del programa.
            set(botoXY,'State','off'); % Deselecciona les altres vistes.
            set(botoYZ,'State','off');
            set(boto3D,'State','off');

            set(grafica_est,'View',[0,0],'Box','on'); % Vista del plànol XZ.
            set(editx,'Enable','off'); % Desactiva la caixa de text amb la coordenada en x perque no es pugui editar.
            set(edity,'Enable','on','String','0'); % Activa la caixa de text amb la coordenada y per editar la profunditat.
            set(editz,'Enable','off'); % Desactiva la caixa de text amb la coordenada en z perque no es pugui editar.
            redibuixar_nusos
            redibuixar_barres
            redibuixa_carreganusos
            %redibuixar_carregues_barres
            if flagcalculat
                esborra_diagramesireaccions
                dibuixa_reaccions
                dibuixa_diagramesideformada
                diagcarregues
                diagreaccions
                visibilitat_diagrames % Mostra els diagrames i la deformade si estan seleccionats.
            end
            centrar % Centra l'estrcutura a la grafica.
        else
            set(hObject,'Value',abs(get(hObject,'Value')-1)); % Evita que es deseleccioni la vista, el que faria que no hi hagués cap seleccionada.
        end
        %disp(['/Vista XY: ',num2str(toc(tic_xz))])
    end

    function vistayz(hObject,eventdata,handles)
        % S'executa quan es selecciona la vista YZ.

        %disp('Vista YZ')
        %tic_yz=tic;
        if strcmp(get(hObject,'State'),'on') && grafica==grafica_est
            vista='yz'; % Variable global vista controla el mode de vista actual del programa.
            set(botoXY,'State','off'); % Deselecciona les altres vistes.
            set(botoXZ,'State','off');
            set(boto3D,'State','off');

            set(grafica_est,'View',[90,0],'Box','on'); % Vista del plànol YZ.
            set(editx,'Enable','on','String','0'); % Activa la caixa de text amb la coordenada x per editar la profunditat.
            set(edity,'Enable','off'); % Desactiva la caixa de text amb la coordenada en y perque no es pugui editar.
            set(editz,'Enable','off'); % Desactiva la caixa de text amb la coordenada en z perque no es pugui editar.
            redibuixar_nusos
            redibuixar_barres
            redibuixa_carreganusos
            %redibuixar_carregues_barres
            if flagcalculat
                esborra_diagramesireaccions
                dibuixa_reaccions
                dibuixa_diagramesideformada
                diagcarregues
                diagreaccions
                visibilitat_diagrames % Mostra els diagrames i la deformade si estan seleccionats.
            end
            centrar % Centra l'estrcutura a la grafica.
        else
            set(hObject,'Value',abs(get(hObject,'Value')-1)); % Evita que es deseleccioni la vista, el que faria que no hi hagués cap seleccionada.
        end
        %disp(['/Vista XY: ',num2str(toc(tic_yz))])
    end

    function vista3d(hObject,eventdata,handles)
        % S'executa quan es selecciona la vista 3D.
        % Es defineix que la càmara apunti al punt mig de l'estructura, i el punt d'observació a la mateixa distància a tots els eixos per obtenir una vista isomètrica.
        % Es defineixen els limits iguals a tots els eixos.

        %disp('Vista 3D')
        %tic_3d=tic;
        if strcmp(get(hObject,'State'),'on') && grafica==grafica_est
            vista='3d'; % Variable global vista controla el mode de vista actual del programa.
            set(botoXY,'State','off'); % Deselecciona les altres vistes.
            set(botoXZ,'State','off');
            set(botoYZ,'State','off');

            set(editx,'Enable','off'); % Desactiva les caixes de text amb les coordenades.
            set(edity,'Enable','off');
            set(editz,'Enable','off');
            redibuixar_nusos
            redibuixar_barres
            redibuixa_carreganusos
            %redibuixar_carregues_barres
            if flagcalculat
                esborra_diagramesireaccions
                dibuixa_reaccions
                dibuixa_diagramesideformada
                diagcarregues
                diagreaccions
                visibilitat_diagrames % Mostra els diagrames i la deformade si estan seleccionats.
            end

            ct=[xm,ym,zm]; % Punt 'camera target' centre de l'estructura.
            minlim=min([xmin,ymin,zmin]); % Mínim
            maxlim=max([xmax,ymax,zmax]); % Màxim
            angle3d=pi/4;

            set(grafica_est,'XLim',[minlim,maxlim],'YLim',[minlim,maxlim],'ZLim',[minlim,maxlim],'CameraTarget',ct,'CameraPosition',ct+[cos(angle3d),1,sin(angle3d)],'CameraUpVector',[0,1,0],'Box','off'); % Vista isomètrica.
            axis equal % Mante la relació entre els eixos.

            centrar
        else
            set(hObject,'Value',abs(get(hObject,'Value')-1)); % Evita que es deseleccioni la vista, el que faria que no hi hagués cap seleccionada.
        end
        %disp(['/Vista XY: ',num2str(toc(tic_3d))])
    end

CREACIÓ I ACCIONS SOBRE EL PANELL QUE CONTÉ ELS BOTONS QUE CONTROLEN EL CÀLCUL PLÀSTIC

    function [panelPlastic,panelResultats,factorTotalResultat,factorParcialResultat,numeroTotalRotula,numeroRotula]=panell_botons_plastic(contRotula)
        contRotula1=contRotula+1;
        numeroRotules=zeros(contRotula1,1);

        panelPlastic=uipanel(figcme2,'Units','pixels','Position',[tm-[300,390],115,200],'BorderType','etchedin','BorderWidth',1,'FontName','default','FontUnits','pixels','FontSize',14,'Title','Càlcul Plàstic:'); % Creacio del panell.
        popupMenu = uicontrol(panelPlastic,'Style','popupmenu','String',numeroRotules,'Position',[5 205 100 200], 'callback', @popupcallback);
        panelResultats=uipanel(panelPlastic,'Units','pixels','Position',[5,250,105,130],'BorderType','etchedin','BorderWidth',1,'FontName','default','FontUnits','pixels','FontSize',12,'Title','Resultats:'); % Creacio del panell.

        %Creem les etiquetes de resultats:
        %text(0,1.4,0,['Hola'],'VerticalAlignment','top','Parent',panelResultats) % Texte títol vista xy.
        numeroRotula=uicontrol(panelResultats,'style','text','String','Num Ròtula:','Position',[0,90,70,15]);
        numeroTotalRotula=uicontrol(panelResultats,'style','text','String','Total Ròtules:','Position',[0,70,78,15]);
        factorTotalResultat=uicontrol(panelResultats,'style','text','String','FC total: ','Position',[0,30,85,15]);
        factorParcialResultat=uicontrol(panelResultats,'style','text','String','FC Ròtula: ','Position',[0,50,100,15]);

        %botoResultatsPlastics=uicontrol(panelPlastic,'Units','pixels','Position',[2,350,105,25],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','Resultats','Foregroundcolor',colorcarregues,'Enable','off','Callback',@diagcarregues,'Value',0,'KeyPressFcn',@tecla);
        set(panelResultats,'Visible','off'); %El panell esta desactivat fins que no hi han resultats per mostrar
        set(panelPlastic,'Visible','off'); %El panell esta desactivat fins que no es pitja la pestanya calcul plastic
    end

CREACIÓ I ACCIONS SOBRE EL PANELL QUE CONTÉ ELS BOTONS QUE CONTROLEN ELS RESULTATS QUE ES MOSTREN.

    function [panel3,botocarregues,botoreaccions,botodeformada,botoaxils,bototallantY,bototallantZ,botomomentX,botomomentY,botomomentZ]=panell_botons_grafica
        % Creació del panell amb els botons.
        panel3=uipanel(figcme2,'Units','pixels','Position',[tm-[300,390],115,200],'BorderType','etchedin','BorderWidth',1,'FontName','default','FontUnits','pixels','FontSize',14,'Title','Gràfica:'); % Creacio del panell.

        botocarregues=uicontrol(panel3,'Units','pixels','Position',[5,155,105,25],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','Càrregues','Foregroundcolor',colorcarregues,'Enable','off','Callback',@diagcarregues,'Value',1,'KeyPressFcn',@tecla); % Creacio botó vista de càrregues.
        botoreaccions=uicontrol(panel3,'Units','pixels','Position',[5,125,105,25],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','Reaccions','Foregroundcolor',colorreaccions,'Enable','off','Callback',@diagreaccions,'Value',1,'KeyPressFcn',@tecla); % Creacio botó vista de reaccions.
        botodeformada=uicontrol(panel3,'Units','pixels','Position',[5,95,105,25],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','Deformada','Foregroundcolor',colordeformada,'Enable','off','Callback',@diagdeformada,'Value',1,'KeyPressFcn',@tecla); % Creacio botó vista de deformada.
        botoaxils=uicontrol(panel3,'Units','pixels','Position',[5,65,50,25],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','N','Foregroundcolor',colorN,'Enable','off','Callback',@diagN,'Value',1,'KeyPressFcn',@tecla); % Creacio botó vista de diagrama d'axils.
        bototallantY=uicontrol(panel3,'Units','pixels','Position',[5,35,50,25],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','Ty','Foregroundcolor',colorTy,'FontWeight','demi','Enable','off','Callback',@diagTy,'Value',1,'KeyPressFcn',@tecla); % Creacio botó vista de diagrama de tallants en y.
        bototallantZ=uicontrol(panel3,'Units','pixels','Position',[5,5,50,25],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','Tz','Foregroundcolor',colorTz,'FontWeight','demi','Enable','off','Callback',@diagTz,'KeyPressFcn',@tecla); % Creacio botó vista de diagrama de tallants en z.
        botomomentX=uicontrol(panel3,'Units','pixels','Position',[60,65,50,25],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','Mx','Foregroundcolor',colorMx,'FontWeight','demi','Enable','off','Callback',@diagMx,'KeyPressFcn',@tecla); % Creacio botó vista de diagrama de moments en x.
        botomomentY=uicontrol(panel3,'Units','pixels','Position',[60,35,50,25],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','My','Foregroundcolor',colorMy,'FontWeight','demi','Enable','off','Callback',@diagMy,'KeyPressFcn',@tecla); % Creacio botó vista de diagrames de moments en Y.
        botomomentZ=uicontrol(panel3,'Units','pixels','Position',[60,5,50,25],'Style','togglebutton','FontName','default','FontUnits','pixels','FontSize',14,'String','Mz','Foregroundcolor',colorMz,'FontWeight','demi','Enable','off','Callback',@diagMz,'Value',1,'KeyPressFcn',@tecla); % Creacio botó vista de diagrames de moments en z.
    end

    function diagcarregues(hObject,eventdata,handles)
        % Oculta o mostra les càrregues a la representacio de resultats amb
        % el seu color corresponent.

        %disp('Oculta o mostra diagrames carregues')
        %tic_dc=tic;

        if ~strcmp(get(botoEdicio,'State'),'on')
            if get(botocarregues,'Value') % Si les càrregues estan seleccinades...
                vis='on';
            else
                vis='off';
            end
            if grafica==grafica_est
                for i=1:contnus
                    set(nusos(i).hgc,'Visible',vis) % Visibilitat de les càrregues als nusos.
                end

                %redibuixar_carregues_barres % Redibuixa les càrregues.
                for i=1:contbarra
                    set(barres(i).hgpuntual,'Visible',vis) % Visibilitat de les càrregues a les barres.
                    set(barres(i).hgmoment,'Visible',vis)
                    set(barres(i).hgrepartida,'Visible',vis)
                    set(barres(i).hgprojectada,'Visible',vis)
                end
            end
        end
        %disp(['/Oculta o mostra diagrames carregues: ',num2str(toc(tic_dc))])
    end

    function diagreaccions(hObject,eventdata,handles)
        % Oculta o mostra les reaccions a la representació de resultats.

        %disp('Oculta o mostra reaccions')
        %tic_r=tic;
        if grafica==grafica_est
            if get(botoreaccions,'Value')
                set(hgreaccions,'Visible','on')
            else
                set(hgreaccions,'Visible','off')
            end
        end
        %disp(['/Oculta o mostra reaccions: ',num2str(toc(tic_r))])
    end

    function diagdeformada(hObject,eventdata,handles)
        % Oculta o mostra la deformada a la representació de resultats.

        %disp('Oculta o mostra la deformada')
        %tic_d=tic;
        if get(botodeformada,'Value')
            vis='on';
        else
            vis='off';
        end
        if grafica==grafica_est
            for i=1:numel(diagrames)
                set(diagrames(i).hgdeformada,'Visible',vis)
            end
        else
            set(diag_presxy.hgdeformada,'Visible',vis)
            set(diag_presxz.hgdeformada,'Visible',vis)
        end
        %disp(['/Oculta o mostra la deformada: ',num2str(toc(tic_d))])
    end

    function diagN(hObject,eventdata,handles)
        % Oculta o mostra el diagrama d'axils a la representació de
        % resultats.

        %disp('Oculta o mostra el diagrama d''axils')
        %tic_N=tic;
        if get(botoaxils,'Value')
            vis='on';
        else
            vis='off';
        end
        if grafica==grafica_est
            for i=1:numel(diagrames)
                set(diagrames(i).hgN,'Visible',vis)
            end
        else
            set(diag_presxy.hgN,'Visible',vis)
            set(diag_presxz.hgN,'Visible',vis)
        end
        %disp(['/Oculta o mostra el diagrama d''axils: ',num2str(toc(tic_N))])
    end

    function diagTy(hObject,eventdata,handles)
        % Oculta o mostra el diagrama de tallants en y a la representació
        % de resultats.

        %disp('Oculta o mostra el diagrama de tallants en y')
        %tic_Ty=tic;
        if get(bototallantY,'Value')
            vis='on';
        else
            vis='off';
        end
        if grafica==grafica_est
            for i=1:numel(diagrames)
                set(diagrames(i).hgTy,'Visible',vis)
            end
        else
            set(diag_presxy.hgTy,'Visible',vis)
        end
        %disp(['/Oculta o mostra el diagrama de tallants en y: ',num2str(toc(tic_Ty))])
    end

    function diagTz(hObject,eventdata,handles)
        % Oculta o mostra el diagrama de tallants en z a la representació
        % de resultats.

        %disp('Oculta o mostra el diagrama de tallants en z')
        %tic_Tz=tic;
        if get(bototallantZ,'Value')
            vis='on';
        else
            vis='off';
        end
        if grafica==grafica_est
            for i=1:numel(diagrames)
                set(diagrames(i).hgTz,'Visible',vis)
            end
        else
            set(diag_presxz.hgTz,'Visible',vis)
        end
        %disp(['/Oculta o mostra el diagrama de tallants en z: ',num2str(toc(tic_Tz))])
    end

    function diagMx(hObject,eventdata,handles)
        % Oculta o mostra el diagrama de moments en x a la representació
        % de resultats.

        %disp('Oculta o mostra el diagrama de moments torsors')
        %tic_Mx=tic;
        if get(botomomentX,'Value')
            vis='on';
        else
            vis='off';
        end
        if grafica==grafica_est
            for i=1:numel(diagrames)
                set(diagrames(i).hgMx,'Visible',vis)
            end
        else
           set(diag_presxy.hgMx,'Visible',vis)
           set(diag_presxz.hgMx,'Visible',vis)
        end
        %disp(['/Oculta o mostra el diagrama de moments torsors: ',num2str(toc(tic_Mx))])
    end

    function diagMy(hObject,eventdata,handles)
        % Oculta o mostra el diagrama de moments en y a la representació
        % de resultats.

        %disp('Oculta o mostra el diagrama de moments flectors en y')
        %tic_My=tic;
        if get(botomomentY,'Value')
            vis='on';
        else
            vis='off';
        end
        if grafica==grafica_est
            for i=1:numel(diagrames)
                set(diagrames(i).hgMy,'Visible',vis)
            end
        else
            set(diag_presxz.hgMy,'Visible',vis)
        end
        %disp(['/Oculta o mostra el diagrama de moments flectors en y: ',num2str(toc(tic_My))])
    end

    function diagMz(hObject,eventdata,handles)
        % Oculta o mostra el diagrama de moments en z a la representació
        % de resultats.

        %disp('Oculta o mostra el diagrama de moments flectors en z')
        %tic_Mz=tic;
        if get(botomomentZ,'Value')
            vis='on';
        else
            vis='off';
        end
        if grafica==grafica_est
            for i=1:numel(diagrames)
                set(diagrames(i).hgMz,'Visible',vis)
            end
        else
            set(diag_presxy.hgMz,'Visible',vis)
        end
        %disp(['/Oculta o mostra el diagrama de moments flectors en z: ',num2str(toc(tic_Mz))])
    end

    function visibilitat_diagrames
        % Oculta o mostra el conjunt de diagrames i deformada.

        %disp('Visaibilitat diagrames')
        %tic_vd=tic;
        diagN
        diagTy
        diagTz
        diagMx
        diagMy
        diagMz
        diagdeformada
        %disp(['/Visibilitat diagrames: ',num2str(toc(tic_vd))])
    end

CREACIÓ I ACCIONS QUE S'EXECUTEN AMB EL BOTÓ CALCULAR.

    function botocalcular1=boto_calcular
        % Creació del boto calcular.
        botocalcular1=uicontrol(figcme2,'Units','pixels','Position',[tm(1)-120,5,115,25],'Style','pushbutton','FontName','default','FontUnits','pixels','FontSize',14,'String','Calcular','Callback',@tipus_calcul,'KeyPressFcn',@tecla);
    end

    function tipus_calcul(hObject,eventdata,handles)%Hem serveix per veure a quina pestanya em trobo.
       if get(botoCalculEstatic,'Value') %Si esta seleccionada la pestanya de calcul estatic pasa a la funcio calcular
            calcular
       end

     if get(botoCalculPlastic,'Value')
         iteracio=1;
         ierr=0;
         factorCarregaTotal=0;
      while ierr==0
         Mp=1;
         Mmax1=0;
         novaRotula=0;
         factorCarrega=1;


         while Mp-0.001>=Mmax1
           % [Retorn_reaccions,Retorn_moviments,Retorn_esforcos_barres,TL2G,ierr]=cme2_calcul_plastic(contnus,nusos,contbarra,barres,diagrames);

         esborra_diagramesireaccions      %Esborra els diagrames i les reaccions anteriors si n'hi han.

         [Ncoord,Ncond,Nextfor,Lnods,Lartyp,Lmecp,barra_carrega_rep,barra_carrega_rep_proj,barra_carrega_punt,barra_carrega_mom]=prepara_dades_calcul2(factorCarrega); % Adapta les dades al format de la funcio de càlcul.

         [Mmax1,Mp,posicioMmax1,barraNum,Retorn_reaccions2,Retorn_moviments2,Retorn_esforcos_barres2,TL2G2,ierr,factorCarregaFinal,mateixFactorCarrega,numFactors,numMaximsIguals,vectorEquacioMz,equacioMx,equacioMy]=calcular2(Ncoord,Ncond,Nextfor,Lnods,Lartyp,Lmecp,barra_carrega_rep,barra_carrega_rep_proj,barra_carrega_punt,barra_carrega_mom,factorCarrega,iteracio); %Calculo el moment maxim generat i retorna el seu valor.

         iteracio=iteracio+1;

                if ierr==0

                          if Mmax1>=Mp-0.001                %Si s'ha superat el moment plàstic es crea una nova ròtula

                             novaRotula=1;              %Asigna un 1 a la variable per tal que entri a la funcio crear ròtula


                           % if mateixFactorCarrega==0
                                contRotula=contRotula+1;   %Contador del número de ròtules creades
                                guardarDades(1,Retorn_reaccions2,Retorn_moviments2,Retorn_esforcos_barres2,TL2G2,factorCarregaFinal,contRotula,barraNum,Mmax1,Mp,posicioMmax1,barres,nusos,barra_carrega_rep,barra_carrega_rep_proj,barra_carrega_punt,barra_carrega_mom,vectorEquacioMz,equacioMx,equacioMy); %Guarda les dades de la estructura en el moment on es crea la ròtula, per tal de poder visualitzar les dades al seleccionar els casos
                            %end
                           else %Si no es supera el moment plàstic:
                           if contRotula>0  %Si s'ha creat almenys una ròtula
                             if factorCarregaFinal<=dadesRotules(contRotula).factorCarrega %Si el factor de càrrega calculat es menor al calculat quan s'ha creat la ròtula, es pren el factor de càrrega pel càlcul igua al que ha creat la anterior ròtula (es creen dos ròtules al mateix temps pel mateix factor de càrrega).
                              factorCarrega=factorCarregaFinal;
                              if factorCarrega==0
                                 factorCarrega=1*10^-16;
                              end
                             else
                               factorCarrega=factorCarregaFinal; %En cas de que el factor de càrrega calculat sigui superat al de la ròtula anterior creada, es defineix el factor de càrrega com aquest últim, doncs es superior, i les ròtules no s'han creat al mateix temps.

                             end
                            else %Si no s'ha creat ninguna ròtula
                               factorCarrega=factorCarregaFinal;
                               factorCarregaTotal=factorCarrega;
                           end
                          end

                  if iteracio>2
                    iteracio=1;
                  end

                end

%                     if mateixFactorCarrega>0 && Mmax1>=Mp-0.001  %Busco que barras tienen el mismo factor de carga cuando se ha superado el momento plastico.
%
%                             for i=1:numFactors-1        %Itero tots els factors de càrrega
%
%                                 if factorsCarrega(i).Mmax==Mmax1      %Busco quins factors de càrrega tenen el moment maxim calculat, per trobar els que es repeteixen
%                                   barraNum=factorsCarrega(i).numBarra ; %Guardo la barra, la posicio del moment màxim.
%                                   nusInferior=factorsCarrega(i).nusInferior;
%                                   nusSuperior=factorsCarrega(i).nusSuperior;
%
%                                   posicioMmax1=factorsCarrega(i).posicioMmax;
%
%                                   novaRotula=1;
%                                   if posicioMmax1==1 %ATENCIO AQUI VA LA LONGITUD DE LA BARRA %Hem de vigilar que el mateix factor de càrrega no correspongui a un mateix punt, es a dir, dues barres tenen el mateix factor de carrega per el seu punt d'unio i no es tenen que crear dues rótules.
%                                     factorsCarrega(i).nus=barres(barraNum).nussup; %Guardo en quin punt s'ha posat la ròtula
%                                       for x=1:numFactors-1
%                                          if factorsCarrega(x).nus==factorsCarrega(i).nus && x~=i %Comprobo que el nus en el que jo tinc el factor de carga maxim, no tingui ja una ròtula definida
%                                            novaRotula=0;
%
%                                          end
%                                       end
%                                   end
%                                   if posicioMmax1==0  %Hem de vigilar que el mateix factor de càrrega no correspongui a un mateix punt, es a dir, dues barres tenen el mateix factor de carrega per el seu punt d'unio i no es tenen que crear dues rótules.
%                                      factorsCarrega(i).nus=barres(barraNum).nusinf; %Guardo en quin punt s'ha posat la ròtula
%                                       for x=1:numFactors-1
%                                          if factorsCarrega(x).nus==factorsCarrega(i).nus && x~=i %Comprobo que el nus en el que jo tinc el factor de carga maxim, no tingui ja una ròtula definida
%                                            novaRotula=0; %Si es dona el mateix factor de c'arrefa al mateix punt, no es crea la rotula
%
%                                          end
%                                       end
%                                   end
%                                  %Si no es dona ningun dels dos casos pot
%                                  %ser per: 1. La ròtula no està als
%                                  %extrems. 2. Sigui la primera ròtula que
%                                  %es crea als extrems
%
%                                    if novaRotula==1
%                                        %contRotula=contRotula+1;
%
%                                           %Vigilo que la reordenació de
%                                            %barres no modifiqui el num de
%                                            %barra associat amb el factor de
%                                            %càrrega (aixo es produeix al
%                                            %esborrar una barra i
%                                            %sustituirla per dues i una
%                                            %ròtula)
%                                        if nusSuperior>0 && nusInferior>0  %En el cas de que vingui un parametre a la funcio, si son 0 no entra a la condició
%                                         if barres(barraNum).nusinf~=nusInferior || barres(barraNum).nussup~=nusSuperior %si no coincideixen els numeros dels nusos, vol dir que la barra ha sigut reordenada, y se li ha asignat un altre numero, cal buscarla
%                                             for z=1:contbarra %Busco per les barres quina te el mateix nus inferior i superior
%                                                if barres(z).nusinf==nusInferior && barres(z).nussup==nusSuperior
%                                                    factorsCarrega(barraNum).numBarra=z;%Actualitzo el valor anterior per l'actual
%                                                    barraNum=z;  %Defineixo la nova barra on s'ha d'introuir la ròtula
%                                                end
%                                             end
%                                         end
%                                        end
%
%                                            %contRotula=contRotula+1;
%
%                                             %guardarDades(1,Retorn_reaccions2,Retorn_moviments2,Retorn_esforcos_barres2,TL2G2,factorCarregaFinal,contRotula,barraNum,Mmax1,Mp,posicioMmax1,barres,nusos,barra_carrega_rep,barra_carrega_rep_proj,barra_carrega_punt,barra_carrega_mom,vectorEquacioMz,equacioMx,equacioMy); %Guarda les dades de la
%                                             display(factorCarregaFinal);
%                                             crearRotula(contRotula,barraNum,Mmax1,Mp,posicioMmax1); %executa la funció ròtula per crear la ròtula
%
%                                             guardarDades(2,Retorn_reaccions2,Retorn_moviments2,Retorn_esforcos_barres2,TL2G2,factorCarregaFinal,contRotula,barraNum,Mmax1,Mp,posicioMmax1,barres,nusos,vectorEquacioMz,equacioMx,equacioMy); %Guarda les dades de nou, per tal de guardar les dades despres de crear la ròtula. Faig aixó per poder dibuixar bé els resultats posteriorment. 1. es dibuixa la estructursa i els seus diagrames 2. es conserven els diagrames es sobredibuixa la nova estructura.
%
%                                             novaRotula=0;
%                                    end
%                                 end
%                             end
                   if Mmax1>=Mp-0.001
                           %contRotula=contRotula+1;
                        if ierr==0
                          if novaRotula==1                                                       %activa la entrada a la funció crear ròtula
                               display(factorCarregaFinal);
                              crearRotula(contRotula,barraNum,Mmax1,Mp,posicioMmax1); %executa la funció ròtula

                                guardarDades(2,Retorn_reaccions2,Retorn_moviments2,Retorn_esforcos_barres2,TL2G2,factorCarregaFinal,contRotula,barraNum,Mmax1,Mp,posicioMmax1,barres,nusos,vectorEquacioMz,equacioMx,equacioMy); %Guarda les dades de nou, per tal de guardar les dades despres de crear la ròtula. Faig aixó per poder dibuixar bé els resultats posteriorment. 1. es dibuixa la estructursa i els seus diagrames 2. es conserven els diagrames es sobredibuixa la nova estructura.

                          end
                        end
                    end
         end
        display('bucle');
      end

      end
    end

    function autopupupcallback(val)
         nusos=nus.empty(1,0); % nova llista d'objectes nus.
        contnus=0; % comptador de nusos a zero.
        barres=barra.empty(1,0); % nova llista d'objectes barra.
        contbarra=0; % comptador de barres a zero.
        hgreaccions=[]; % esborra la llista de reaccions.
        diagrames=diagrama.empty(1,0); % nova llista d'objectes diagrama.
        delete(get(grafica,'Children')) % esborra tots els objectes gràfics.
        %set(grafica_est,'XLim',XLimini,'YLim',YLimini,'ZLim',ZLimini) % Estableix els límits originals.
        [hg_nusos,hg_barres,hg_carreguesbarres,hg_carreganusos,hg_diagrames]=inicialitza_hg(grafica_est);
        centrar
        set(botoEdicio,'State','off'); % Torna al mode edició.
        edicio % Esborra diagrames, etc..


        Retorn_reaccions=dadesRotules(val).Retorn_reaccions;             %Recupera les reaccions del sistema
        Retorn_moviments=dadesRotules(val).Retorn_moviments;             %Recupera els moviments del sistema
        Retorn_esforcos_barres=dadesRotules(val).Retorn_esforcos_barres; %Recupera els esforcos del sistema
        TL2G=dadesRotules(val).TL2G;                                     %Recupera els esforcos del sistema


        factorCarrega=0;
        for x=1:val
            factorCarrega=factorCarrega+dadesRotules(x).factorCarrega;   %Recupera el factor de càrrega total fins la ròtula que es demana.
        end
        display(factorCarrega);

        %Mostra els resultats a les caixes de text
        %panelResultats,factorTotalResultat,factorParcialResultat,,numeroTotalRotula,numeroRotula
        set(panelResultats,'Visible','on');
        set(factorTotalResultat,'String',['FC total: ',num2str(factorCarrega)]);
        set(factorParcialResultat,'String',['FC Ròtula: ',num2str(factorCarrega)]);
        set(numeroTotalRotula,'String',['Total Ròtules: ',num2str(contRotula)]);
        set(numeroRotula,'String',['Num Ròtula: ',num2str(contRotula)]);

        barraNum=dadesRotules(val).barraNum;                             %Recupera el numero de barra on s'ha creat la ròtula.
        Mmax1=dadesRotules(val).Mmax1;                                   %Recupera el numero de barra on s'ha creat la ròtula.
        Mp=dadesRotules(val).Mp;                                         %Recupera el numero de barra on s'ha creat la ròtula.
        posicioMmax1=dadesRotules(val).posicioMmax1;                     %Recupera el numero de barra on s'ha creat la ròtula.
        barres=dadesRotules(val).barres;                                 %Recupera totes les barres existents
        nusos=dadesRotules(val).nusos;                                   %Recupera tots els nusos existents
        contnus=dadesRotules(val).contnus;
        contbarra=dadesRotules(val).contbarra;

         for i=1:contnus
            redibuixar_nus2(i) % Redibuixa cada nus.
        end
        for i=1:contnus %Asigna color a les ròtules

               if nusos(i).color(2) ==1
                chgcolor(nusos(i).hg,[0 1 0])
               end
        end

        for i=1:contbarra %Redibuixa les barres
        redibuixar_barra2(i);
        end
        colorbarres

         for i=1:contbarra %Redibuixa les càrregues
            redibuixar_carregues_barra2(i)
        end
        colorcarregabarres
        diagcarregues


      % dibuixa_reaccions; % Dibuixa les reaccions.

        for i=1:contnus
            redibuixa_carreganus2(i) % Redibuixa les càrregues.
        end
        colorcarreganusos

        escala % Calcula el factor d'escala s.
        escalar_nusos

        dibuixa_diagramesideformada3(factorCarrega,1); % Dibuixa els diagrames i la deformada.

        centrar

       %Fagi aquest canvi per dibuixar sobre el que hi havia anteriorment,
       %la nova estructura. Faig aixo per que el programa pugui dibuixar
       %correctament els diagrames.
        barres=dadesRotules(val).barres2;                                 %Recupera totes les barres existents
        nusos=dadesRotules(val).nusos2;                                   %Recupera tots els nusos existents
        contnus=dadesRotules(val).contnus2;
        contbarra=dadesRotules(val).contbarra2;


        for i=1:contnus
            redibuixar_nus2(i) % Redibuixa cada nus.
        end
        for i=1:contnus %Asigna color a les ròtules

               if nusos(i).color(2) ==1
                chgcolor(nusos(i).hg,[0 1 0])
               end
        end

        for i=1:contbarra %Redibuixa les barres
        redibuixar_barra2(i);
        end
        colorbarres

        escalar_nusos

    end

    function popupcallback(hObject, eventdata, handles) %Es la funcio que es crida cuan es selecciona alguna opcio del popup de calcul plàstic
        val = get(hObject,'Value'); %Agafa el valor del popup que correspon al numero de ròtula creada

        nusos=nus.empty(1,0); % nova llista d'objectes nus.
        contnus=0; % comptador de nusos a zero.
        barres=barra.empty(1,0); % nova llista d'objectes barra.
        contbarra=0; % comptador de barres a zero.
        hgreaccions=[]; % esborra la llista de reaccions.
        diagrames=diagrama.empty(1,0); % nova llista d'objectes diagrama.
        delete(get(grafica,'Children')) % esborra tots els objectes gràfics.
        %set(grafica_est,'XLim',XLimini,'YLim',YLimini,'ZLim',ZLimini) % Estableix els límits originals.
        [hg_nusos,hg_barres,hg_carreguesbarres,hg_carreganusos,hg_diagrames]=inicialitza_hg(grafica_est);
        centrar
        set(botoEdicio,'State','off'); % Torna al mode edició.
        edicio % Esborra diagrames, etc..



        Retorn_reaccions=dadesRotules(val).Retorn_reaccions;             %Recupera les reaccions del sistema
        Retorn_moviments=dadesRotules(val).Retorn_moviments;             %Recupera els moviments del sistema
        Retorn_esforcos_barres=dadesRotules(val).Retorn_esforcos_barres; %Recupera els esforcos del sistema
        TL2G=dadesRotules(val).TL2G;                                     %Recupera els esforcos del sistema
        factorCarrega=0;
        for x=1:val
            factorCarrega=factorCarrega+dadesRotules(x).factorCarrega;   %Recupera el factor de càrrega total fins la ròtula que es demana.
        end
        display(factorCarrega);


        set(factorParcialResultat,'String',['FC Ròtula : ',num2str(factorCarrega)]);
        set(numeroRotula,'String',['Num Ròtula: ',num2str(val)]);

        barraNum=dadesRotules(val).barraNum;                             %Recupera el numero de barra on s'ha creat la ròtula.
        Mmax1=dadesRotules(val).Mmax1;                                   %Recupera el numero de barra on s'ha creat la ròtula.
        Mp=dadesRotules(val).Mp;                                         %Recupera el numero de barra on s'ha creat la ròtula.
        posicioMmax1=dadesRotules(val).posicioMmax1;                     %Recupera el numero de barra on s'ha creat la ròtula.
        barres=dadesRotules(val).barres;                                 %Recupera totes les barres existents
        nusos=dadesRotules(val).nusos;                                   %Recupera tots els nusos existents
        contnus=dadesRotules(val).contnus;
        contbarra=dadesRotules(val).contbarra;

         for i=1:contnus
            redibuixar_nus2(i) % Redibuixa cada nus.
        end
        for i=1:contnus %Asigna color a les ròtules

               if nusos(i).color(2) ==1
                chgcolor(nusos(i).hg,[0 1 0])
               end
        end

        for i=1:contbarra %Redibuixa les barres
        redibuixar_barra2(i);
        end
        colorbarres

         for i=1:contbarra %Redibuixa les càrregues
            redibuixar_carregues_barra2(i)
        end
        colorcarregabarres
        diagcarregues


      % dibuixa_reaccions; % Dibuixa les reaccions.

        for i=1:contnus
            redibuixa_carreganus2(i) % Redibuixa les càrregues.
        end
        colorcarreganusos

        escala % Calcula el factor d'escala s.
        escalar_nusos

        dibuixa_diagramesideformada3(factorCarrega,1); % Dibuixa els diagrames i la deformada.

        centrar

       %Fagi aquest canvi per dibuixar sobre el que hi havia anteriorment,
       %la nova estructura. Faig aixo per que el programa pugui dibuixar
       %correctament els diagrames.
        barres=dadesRotules(val).barres2;                                 %Recupera totes les barres existents
        nusos=dadesRotules(val).nusos2;                                   %Recupera tots els nusos existents
        contnus=dadesRotules(val).contnus2;
        contbarra=dadesRotules(val).contbarra2;


        for i=1:contnus
            redibuixar_nus2(i) % Redibuixa cada nus.
        end
        for i=1:contnus %Asigna color a les ròtules

               if nusos(i).color(2) ==1
                chgcolor(nusos(i).hg,[0 1 0])
               end
        end

        for i=1:contbarra %Redibuixa les barres
        redibuixar_barra2(i);
        end
        colorbarres

        escalar_nusos

    end

    function guardarDades(factor,Retorn_reaccions2,Retorn_moviments2,Retorn_esforcos_barres2,TL2G2,factorCarrega,contRotula,barraNum,Mmax1,Mp,posicioMmax1,barres,nusos,barra_carrega_rep,barra_carrega_rep_proj,barra_carrega_punt,barra_carrega_mom,vectorEquacioMz,vectorEquacioMx,vectorEquacioMy)
       if factor==1
        numeroRotules=zeros(contRotula,1); %Actualitza el vector del popup i el fa mes gran cada vegada que es crea una ròtula

        for i=1:contRotula   %Afegeix el numero de ròtules a cada valor del vector.
           numeroRotules(i,1)=i;
        end
        popupMenu = uicontrol(panelPlastic,'Style','popupmenu','String',numeroRotules,'Position',[5 205 100 200], 'callback', @popupcallback); %Actualitza el popup
        set(popupMenu,'value',(numeroRotules(contRotula,1))); %Poso el popup a la úiltima posicó

        dadesRotules(contRotula)=dadesRotula; % Nou objecte dades rotula a la lista dades rotules.
         dadesRotules(contRotula).numDades=contRotula; % Asigna numero de dades guardades a les dades.


            dadesRotules(contRotula).Retorn_reaccions=Retorn_reaccions2; % Guarda les reaccions del sistema
            dadesRotules(contRotula).Retorn_moviments=Retorn_moviments2; % Guarda els moviments del sistema
            dadesRotules(contRotula).Retorn_esforcos_barres=Retorn_esforcos_barres2; % Guarda els esforcos del sistema

        dadesRotules(contRotula).TL2G=TL2G2;
        dadesRotules(contRotula).factorCarrega=factorCarrega; % Guarda el factor de càrrega que ha generat una ròtula.
        dadesRotules(contRotula).barraNum=barraNum; %Guarda el numero de barra on s'ha creat la ròtula.
        dadesRotules(contRotula).Mmax1=Mmax1; %Guarda el numero de barra on s'ha creat la ròtula.
        dadesRotules(contRotula).Mp=Mp; %Guarda el numero de barra on s'ha creat la ròtula.
        dadesRotules(contRotula).posicioMmax1=posicioMmax1; %Guarda el numero de barra on s'ha creat la ròtula.
        dadesRotules(contRotula).barres=barres; %Guarda totes les barres existents
        dadesRotules(contRotula).nusos=nusos; %Guarda tots els nusos existents
        dadesRotules(contRotula).contnus=contnus;
        dadesRotules(contRotula).contbarra=contbarra;
        dadesRotules(contRotula).barra_carrega_rep=barra_carrega_rep;
        dadesRotules(contRotula).barra_carrega_rep_proj=barra_carrega_rep_proj;
        dadesRotules(contRotula).barra_carrega_punt=barra_carrega_punt;
        dadesRotules(contRotula).barra_carrega_mom=barra_carrega_mom;
        dadesRotules(contRotula).equacioMz=vectorEquacioMz;
        dadesRotules(contRotula).equacioMy=vectorEquacioMy;
        dadesRotules(contRotula).equacioMx=vectorEquacioMx;

       end
       if factor==2 %Guardo les dades despres d'haver creat les ròtules amb la finalitat de poder dibuixar els diagrames anteriors
        dadesRotules(contRotula).barres2=barres; %Guarda totes les barres existents
        dadesRotules(contRotula).nusos2=nusos; %Guarda tots els nusos existents
        dadesRotules(contRotula).contnus2=contnus;
        dadesRotules(contRotula).contbarra2=contbarra;

       end

    end

    function crearRotula(contRotula,barraNum,Mmax1,Mp,posicioMmax1)


        carregaSegonaBarraPuntual=0;
        carregaSegonaBarraMoment=0;
        nusInferior=barres(barraNum).nusinf;  %Obtenim el numero dels nusos de la barra on s'ha produit la ròtula
        nusSuperior=barres(barraNum).nussup;

        posInferior=nusos(nusInferior).posicio;     %obté la posició del nus inferior de la barra
        posSuperior=nusos(nusSuperior).posicio;     %obté la posició del nus superior de la barra

        posCalcul=posSuperior-posInferior;          %calcula el vector de posicioó de la barra
        modulo=(posCalcul(1)^2+posCalcul(2)^2+posCalcul(3)^2)^0.5;  %calcula el mòdul del vector per poder calcular el vector unitari (Longitud barra)
        vectorUnitario=posCalcul/modulo;                            %calcula el vector unitari
        vectorPosicio=vectorUnitario*posicioMmax1;                  %a partir del vector unitari, multiplican aquest per la distancia al nus inferior obtenim el vector posició del nou nus
        posicio=posInferior+vectorPosicio;                          %sumem les coordenades del nus inferior al vector posicio del nus on es situa la ròtula i així obtenim les coordenades del nus on es crea la ròtula.

        longNovaBarraInf=(vectorPosicio(1)^2+vectorPosicio(2)^2+vectorPosicio(3)^2)^0.5; %(modulVectorPosicio) Hem permet coneixer la longitud del punt inferior al punt o s'ha creat la ròtula (Longitud nova barra inferior)
        longNovaBarraSup=modulo-longNovaBarraInf;



        if longNovaBarraInf<=0.1 %Si la longitud de la barra creada es molt petita, es evident que la ròtula s'ha creat al nus. per tant, variarem les condicions de contorn del nus.
            barres(barraNum).artinf=1; %Definim una articulacio a la unio del punt amb la barra.
            nusos(nusInferior).color=[0 1 0]; %Pinto el nus inferior de color verd per indicar la situació d ela nova ròtula
            dadesRotules(contRotula).nusRotula=nusInferior;
            dadesRotules(contRotula).nusos=nusos; %Guarda tots els nusos existents

            %barres(barraNum).moment=[Mmax1,0,0,1,0]; %Al extrem de la nova barra aplico un moment igual al moment màxim amb la finalitat de que simuli el màxim valor que resisteix la ròtula plastificada

        elseif longNovaBarraSup<=0.1
            barres(barraNum).artsup=1; %Definim una articulacio a la unio del punt amb la barra si la longitud de la nova barra superior es menor a 0.1
            nusos(nusSuperior).color=[0 1 0]; %Pinto el nus superior de color verd per indicar la situació d ela nova ròtula
            dadesRotules(contRotula).nusRotula=nusSuperior;
            dadesRotules(contRotula).nusos=nusos; %Guarda tots els nusos existents
             %barres(barraNum).moment=[Mmax1,0,0,1,0];
        else

                %ara creem el nus a la posició obtinguda
                crearnus2(posicio);

                %ara creem les noves barres
                %guardem les propietats de la barra antiga


                barraAntigaArtInf=barres(barraNum).artinf;                   % Nus inferior articulat: 0=rígid, 1=articulat.
                barraAntigaArtSup=barres(barraNum).artsup;                   % No es necessari doncs el punt superior de la nova barra serà el punt on s'ha creat la ròtula.

                barraAntigaE=barres(barraNum).E;                        % Mòdul de Young.
                barraAntigaA=barres(barraNum).A;                        % Àrea de la secció.
                barraAntigaIz=barres(barraNum).Iz;                       % Inèrcia en eix z.
                barraAntigaIy=barres(barraNum).Iy;                       % Inèrcia en eix y.
                barraAntigaVectorIz=barres(barraNum).vectorIz;           % Vector direcció de l'eix z de la secció.
                barraAntigaGIt=barres(barraNum).GIt;                      % Inèrcia a torsió.
                barraAntigaMp=barres(barraNum).Mp;                       % Moment plàstic
                %hg                          % handle a l'objecte gràfic de la barra.
                %hgpuntual                   % handle a l'objecte gràfic de la càrrega puntual a la barra.
                %hgmoment                    % handle a l'objecte gràfic del moment a la barra.
                %hgrepartida                 % handle a l'objecte gràfic de la càrrega repartida.
                %hgprojectada                % handle a l'objecte gràfic de la càrrega repartida projectada.
                barraAntigaPuntual=barres(barraNum).puntual;       % Càrrega puntual: mòdul, vector direcció x,y,z i  distància al nus inferior.
                barraAntigaMoment=barres(barraNum).moment;         % Moment aplicat a la barra: mòdul, vector direcció x,y,z i  distància al nus inferior.
                barraAntigaRepartida=barres(barraNum).repartida;   % Càrrega repartida: mòdul, vector direcció x,y,z i distància al nus inferior i superior.
                barraAntigaProjectada=barres(barraNum).projectada;  % Càrrega repartida peojectada: mòdul, vector direcció x,y,z i distància al nus inferior i superior.


                %esborrem la barra antiga
                esborrarbarra(barraNum);

                %hem de crear una nova barra y copiar les propietats de la barra
                %antiga
                novabarra(nusInferior,contnus,0,1); % es crea la nova barra, el primer punt serà el mateix que la barra esborrada, el segon punt serà el nou punt creat(ròrula), (el segon punt estara articulat per aixo porta un 1)

                %asignem valors
                barres(contbarra).artinf=barraAntigaArtInf;              % Nus inferior articulat: 0=rígid, 1=articulat.
                barres(contbarra).E=barraAntigaE;                        % Mòdul de Young.
                barres(contbarra).A=barraAntigaA;                        % Àrea de la secció.
                barres(contbarra).Iz=barraAntigaIz;                       % Inèrcia en eix z.
                barres(contbarra).Iy=barraAntigaIy;                       % Inèrcia en eix y.
                barres(contbarra).vectorIz=barraAntigaVectorIz;           % Vector direcció de l'eix z de la secció.
                barres(contbarra).GIt=barraAntigaGIt;                      % Inèrcia a torsió.
                barres(contbarra).Mp=barraAntigaMp;                       % Moment plàstic
                %hg                          % handle a l'objecte gràfic de la barra.
                %hgpuntual                   % handle a l'objecte gràfic de la càrrega puntual a la barra.
                %hgmoment                    % handle a l'objecte gràfic del moment a la barra.
                %hgrepartida                 % handle a l'objecte gràfic de la càrrega repartida.
                %hgprojectada                % handle a l'objecte gràfic de la càrrega repartida projectada.

                      if barraAntigaPuntual(5)<=longNovaBarraInf                      %Comprova si la distancia de la càrrega al puntInferior, es menor a la longitud on s'ha produit la ròtula
                        barres(contbarra).puntual=barraAntigaPuntual;       %Càrrega puntual: mòdul, vector direcció x,y,z i  distància al nus inferior.
                      else
                        carregaSegonaBarraPuntual=1;                                 %Asignem 1 a la variable per tal de poder indicar, posteriorment, que es necessari introduir la carga puntual a la segona barra creada.
                      end
                      if barraAntigaMoment(5)<=longNovaBarraInf
                          barres(contbarra).moment=barraAntigaMoment;       %Moment aplicat a la barra: mòdul, vector direcció x,y,z i  distància al nus inferior.
                      else
                          carregaSegonaBarraMoment=1;
                      end
                      if barraAntigaRepartida(5)<=longNovaBarraInf
                          barres(contbarra).repartida=barraAntigaRepartida;                                 %Càrrega repartida: mòdul, vector direcció x,y,z i distància al nus inferior i superior.
                            if barraAntigaRepartida(6)>longNovaBarraSup                                     %En aquest cas, si la longitud de la nova barra superior, es menor a la distancia de la càrrega al punt superior de la antiga barra, s'ha d'asignar de nou la distancia entre: la carrega i el nou punt superior cret(rotula).
                               barres(contbarra).repartida(6)=barraAntigaRepartida(6)-longNovaBarraSup;
                            else                                                                            %En cas contrari, tenim la carrega repartida fins al final de la nova barra inferior, per tant asignem una distancia de la carga al nus superior de 0;
                                barres(contbarra).repartida(6)=0;
                            end

                      end

                      if barraAntigaProjectada(5)<=longNovaBarraInf
                          barres(contbarra).projectada=barraAntigaProjectada;                               %En aquest cas, si la longitud de la nova barra superior, es menor a la distancia de la càrrega al punt superior de la antiga barra, s'ha d'asignar de nou la distancia entre: la carrega i el nou punt superior cret(rotula).
                            if barraAntigaProjectada(6)>longNovaBarraSup
                                barres(contbarra).projectada(6)=barraAntigaProjectada(6)-longNovaBarraSup;  %En cas contrari, tenim la carrega repartida fins al final de la nova barra inferior, per tant asignem una distancia de la carga al nus superior de 0;
                            else
                               barres(contbarra).projectada(6)=0;
                            end
                      end

                 %Creem la segona barra i realitzem les mateixes operacions
                 novabarra(contnus,nusSuperior,1,0); % es crea la nova barra (el primer punt estara articulat per aixo porta un 1)

                 %asignem valors
                barres(contbarra).artsup=barraAntigaArtSup;              % Nus inferior articulat: 0=rígid, 1=articulat. (hem d'inclore les mateixes condicions de contorn a l'extrem de barra superior, que les que tenia la barra antiga)
                barres(contbarra).E=barraAntigaE;                        % Mòdul de Young.
                barres(contbarra).A=barraAntigaA;                        % Àrea de la secció.
                barres(contbarra).Iz=barraAntigaIz;                       % Inèrcia en eix z.
                barres(contbarra).Iy=barraAntigaIy;                       % Inèrcia en eix y.
                barres(contbarra).vectorIz=barraAntigaVectorIz;           % Vector direcció de l'eix z de la secció.
                barres(contbarra).GIt=barraAntigaGIt;                      % Inèrcia a torsió.
                barres(contbarra).Mp=barraAntigaMp;                       % Moment plàstic
                %hg                          % handle a l'objecte gràfic de la barra.
                %hgpuntual                   % handle a l'objecte gràfic de la càrrega puntual a la barra.
                %hgmoment                    % handle a l'objecte gràfic del moment a la barra.
                %hgrepartida                 % handle a l'objecte gràfic de la càrrega repartida.
                %hgprojectada                % handle a l'objecte gràfic de la càrrega repartida projectada.

                      if carregaSegonaBarraPuntual==1                         %En aquest cas, com la distancia a la càrrega es media desde el punt inferior, hem de verificar, que la càrrega ara queda situada pasada la ròtula
                        barres(contbarra).puntual=barraAntigaPuntual;       %Càrrega puntual: mòdul, vector direcció x,y,z i  distància al nus inferior.
                        barres(contbarra).puntual(5)=barraAntigaPuntual(5)-longNovaBarraInf; %La distancia del punt ròtula a la posició de la càrrega vindrà donada per la diferencia ente la distancia inical menys la longitud de la nova barra inf

                      end
                      if carregaSegonaBarraMoment==1
                          barres(contbarra).moment=barraAntigaMoment;       %Moment aplicat a la barra: mòdul, vector direcció x,y,z i  distància al nus inferior.
                          barres(contbarra).moment(5)=barraAntigaPuntual(5)-longNovaBarraInf;

                      end

                       if barraAntigaRepartida(6)<=longNovaBarraSup
                          barres(contbarra).repartida=barraAntigaRepartida;                                 %Càrrega repartida: mòdul, vector direcció x,y,z i distància al nus inferior i superior.
                            if barraAntigaRepartida(5)>longNovaBarraInf
                               barres(contbarra).repartida(5)=barraAntigaRepartida(5)-longNovaBarraInf;
                            else
                                barres(contbarra).repartida(5)=0;
                            end
                       end
                      if barraAntigaProjectada(6)<=longNovaBarraSup
                          barres(contbarra).projectada=barraAntigaProjectada;
                            if barraAntigaProjectada(5)>longNovaBarraInf
                                barres(contbarra).projectada(5)=barraAntigaProjectada(5)-longNovaBarraInf;
                            else
                               barres(contbarra).projectada(5)=0;
                            end
                      end
                nusos(contnus).color=[0 1 0];
                dadesRotules(contRotula).nusos=nusos; %Guarda tots els nusos existents
                redibuixar_nusos2 % Reorienta, gira, els nusos segons les barres connectades o la seva posició relativa.
                redibuixar_barres % Redibuixa les barres, per si el nus te barres connectades i s'ha modificat la posició.
        end
     end

    function calcular(hObject,eventdata,handles)
        % Surt del mode edició, elimina digrames anteriors.
        % Prepara les dades per cridar a la funcio de càlcul està%tic.
        % Representa les reaccions.
        % Amb el resultats del càlcul està%tic crida a la funció de càlcul i
        % dibuix dels diagrames i la deformada, els escala i col·loca al
        % seu lloc.


        %disp('Calcular')
        %tic_calc=tic;
        if grafica~=grafica_est % Si no s'esta presentant resultats de barra.
            clic_grafica_res
        end
        if contbarra % Si hi ha barres.
            esborra_diagramesireaccions % Esborra els diagrames i les reaccions anteriors si n'hi han.
            [Ncoord,Ncond,Nextfor,Lnods,Lartyp,Lmecp,barra_carrega_rep,barra_carrega_rep_proj,barra_carrega_punt,barra_carrega_mom]=prepara_dades_calcul; % Adapta les dades al format de la funcio de càlcul.
            [Retorn_reaccions,Retorn_moviments,Retorn_esforcos_barres,TL2G,ierr] = cme2_calcul_estatic(contnus,contbarra,Ncoord,Ncond,Nextfor,Lnods,Lartyp,Lmecp,barra_carrega_rep,barra_carrega_rep_proj,barra_carrega_punt,barra_carrega_mom); % Crida a la funció de càlcul està%tic.
            if ierr == 0
                flagcalculat=1; % Flag que indica que s'ha calculat una estructura. Permet a la funció que controla l'escala de la deformada amb el teclat coneixer si hi ha deformada.
                maxpuntual % Calcula forces puntuals o reaccions maximes.
                dibuixa_reaccions % Dibuixa les reaccions.
                redibuixar_carregues_barres
                redibuixa_carreganusos
                escalar_nusos
                dibuixa_diagramesideformada % Dibuixa els diagrames i la deformada.
                set(botoEdicio,'State','off'); % Botó edició en mode presentacio.
                edicio % Desactiva botons de la barra d'eines per a l'edició, activa els de mostra de resultats, etc.
            else
                h = errordlg('La matriu de rigidesa és singular. Comproveu les condicions de contorn.','Matriu singular');
            end
        end
        %disp(['/Calcular: ',num2str(toc(tic_calc))])
    end

    function [Mmax1,Mp,posicioMmax1,barraNum,Retorn_reaccions2,Retorn_moviments2,Retorn_esforcos_barres2,TL2G2,ierr,factorCarregaFinal,mateixFactorCarrega,numFactors,numMaximsIguals,vectorEquacioMz,equacioMx,equacioMy]=calcular2(Ncoord,Ncond,Nextfor,Lnods,Lartyp,Lmecp,barra_carrega_rep,barra_carrega_rep_proj,barra_carrega_punt,barra_carrega_mom,factorCarrega,iteracio) %hem permet fer modificacions a la funcio calcular per tant de treure els valors necesaris pel calcul plastic
        % Surt del mode edició, elimina digrames anteriors.
        % Prepara les dades per cridar a la funcio de càlcul està%tic.
        % Representa les reaccions.
        % Amb el resultats del càlcul està%tic crida a la funció de càlcul i
        % dibuix dels diagrames i la deformada, els escala i col·loca al
        % seu lloc.
        %disp('Calcular')
        %tic_calc=tic;
        if contbarra % Si hi ha barres.
            [Retorn_reaccions,Retorn_moviments,Retorn_esforcos_barres,TL2G,ierr] = cme2_calcul_estatic(contnus,contbarra,Ncoord,Ncond,Nextfor,Lnods,Lartyp,Lmecp,barra_carrega_rep,barra_carrega_rep_proj,barra_carrega_punt,barra_carrega_mom); % Crida a la funció de càlcul està%tic.
            Retorn_reaccions2=Retorn_reaccions;
            Retorn_moviments2=Retorn_moviments;
            Retorn_esforcos_barres2=Retorn_esforcos_barres;
            TL2G2=TL2G;
            if isnan(Retorn_esforcos_barres)
                ierr=1;
            end

            if ierr == 0
                flagcalculat=1; % Flag que indica que s'ha calculat una estructura. Permet a la funció que controla l'escala de la deformada amb el teclat coneixer si hi ha deformada.
                maxpuntual % Calcula forces puntuals o reaccions maximes.
                dibuixa_reaccions % Dibuixa les reaccions.
                redibuixar_carregues_barres
                redibuixa_carreganusos
                escalar_nusos

                [Mmax1,Mp,posicioMmax1,barraNum,factorCarregaFinal,mateixFactorCarrega,numFactors,numMaximsIguals,vectorEquacioMz,equacioMx,equacioMy]=dibuixa_diagramesideformada2(factorCarrega,iteracio); % Dibuixa els diagrames i la deformada.

                %Un cop calculat el factor de càrrega, aplico el principi
                %de superposició i sumo les reaccions, els moviments i els
                %esforços

                if contRotula>0
                  if contRotula>1
                   for z=2:1:contRotula
                       Retorn_reaccions2=Retorn_reaccions*factorCarregaFinal+dadesRotules(z).Retorn_reaccions*dadesRotules(z).factorCarrega+dadesRotules(1).Retorn_reaccions;
                       Retorn_moviments2=Retorn_moviments*factorCarregaFinal+dadesRotules(z).Retorn_moviments*dadesRotules(z).factorCarrega+dadesRotules(1).Retorn_moviments;
                       Retorn_esforcos_barres2=Retorn_esforcos_barres*factorCarregaFinal+dadesRotules(z).Retorn_esforcos_barres*dadesRotules(z).factorCarrega+dadesRotules(1).Retorn_esforcos_barres;
                   end
                  else
                    Retorn_reaccions2=Retorn_reaccions*factorCarregaFinal+dadesRotules(1).Retorn_reaccions;
                    Retorn_moviments2=Retorn_reaccions*factorCarregaFinal+dadesRotules(1).Retorn_moviments;
                    Retorn_esforcos_barres2=Retorn_esforcos_barres*factorCarregaFinal+dadesRotules(1).Retorn_esforcos_barres;
                  end
                end


                set(botoEdicio,'State','off'); % Botó edició en mode presentacio.
                edicio % Desactiva botons de la barra d'eines per a l'edició, activa els de mostra de resultats, etc.
            elseif contRotula>0
                message=contRotula;
                autopupupcallback(contRotula);
                %set(botoResultatsPlastics,'Value',1);
                h = msgbox({num2str(message);' ròtules formades'},'Càlcul plàstic');
                Mmax1=0;
                Mp=0;
                posicioMmax1=0;
                barraNum=0;
                Retorn_reaccions2=0;
                Retorn_moviments2=0;
                Retorn_esforcos_barres2=0;
                TL2G2=0;
                ierr=1;
                factorCarregaFinal=0;
                mateixFactorCarrega=0;
                numFactors=0;
                numMaximsIguals=0;
                vectorEquacioMz=0;
                equacioMx=0;
                equacioMy=0;
                return
            else
                h = errordlg('La matriu de rigidesa és singular. Comproveu les condicions de contorn.','Matriu singular');
            end
        end
        %disp(['/Calcular: ',num2str(toc(tic_calc))])
    end

    function esborra_diagramesireaccions
        % Esborra els diagrames i reaccions anteriors.

        %disp('Esborra diagrames i reaccions')
        %tic_esb=tic;
        for i=1:length(diagrames) % Esborra els diagrames anteriors.
            delete(diagrames(i).hgN)
            delete(diagrames(i).hgTy)
            delete(diagrames(i).hgTz)
            delete(diagrames(i).hgMx)
            delete(diagrames(i).hgMy)
            delete(diagrames(i).hgMz)
            delete(diagrames(i).hgdeformada)
        end
        for i=1:length(hgreaccions) % Esborra les reaccions anteriors.
            if hgreaccions(i)
                delete(hgreaccions(i))
            end
        end
       hgreaccions=[];
       diagrames=diagrama;
       %disp(['/Esborra diagrames i reaccions: ',num2str(toc(tic_esb))])
    end

    function [Ncoord,Ncond,Nextfor,Lnods,Lartyp,Lmecp,barra_carrega_rep,barra_carrega_rep_proj,barra_carrega_punt,barra_carrega_mom]=prepara_dades_calcul
        % Prepara les dades al format d'entrada de la funció de càlcul està%tic.

        %disp('Prepara dades calcul')
        %tic_prep=tic;
        Ncoord=zeros(contnus,3); % Coordenades dels nusos.
        Ncond=zeros(contnus,7); % Condicions de contorn.
        Nextfor=zeros(contnus*6,1); % Càrregues als nusos.
        for i=1:contnus
            Ncoord(i,:)=nusos(i).posicio; % Coordenades dels nusos.
            Ncond(i,1)=nusos(i).contorn; % Condicions de contorn.
            switch nusos(i).contorn
                case 1 % rodet
                    Ncond(i,2:4)=nusos(i).rodet; % Condició de contorn rodet.
                case {4,5,6} % moviments elàs%tics
                    Ncond(i,2:7)=nusos(i).rig; % Condició de contorn elas%ticitat.
                case {7,8,9} % moviments imposats
                    Ncond(i,2:7)=nusos(i).desp; % Condició de contorn moviment.
            end
            Nextfor(i*6-5:i*6-3)=nusos(i).puntual; % Càrregues puntuals als nusos.
            Nextfor(i*6-2:i*6)=nusos(i).moment; % Carregues moment als nusos.
        end

        Lnods=zeros(contbarra,2); % Connectivitat dels extrems de barra.
        Lartyp=zeros(contbarra,2); % articulació dels extrems de barra.
        Lmecp=zeros(contbarra,9); % Propietats mecàniques de les barres.
        barra_carrega_rep=zeros(contbarra,6); % Càrregues repartides.
        barra_carrega_rep_proj=zeros(contbarra,6); % Càrregues projectades.
        barra_carrega_punt=zeros(contbarra,5); % Càrregues puntuals.
        barra_carrega_mom=zeros(contbarra,5); % Càrregues moment.
        for i=1:contbarra
            Lnods(i,1)=barres(i).nusinf; % Connectivitat de l'extrem inferior de barra.
            Lnods(i,2)=barres(i).nussup; % Connectivitat de l'extrem superior de barra.
            Lartyp(i,1)=barres(i).artinf; % articulacio de l'extrem inferior de barra.
            Lartyp(i,2)=barres(i).artsup; % articulacio de l'extrem superior de barra.
            Lmecp(i,1)=barres(i).E; % Modul de Young.
            Lmecp(i,2)=9.81;  % Gravetat, herència de CME, de fet no s'utilitza.
            Lmecp(i,3)=barres(i).A; % Àrea de la secció.
            Lmecp(i,4)=barres(i).Iz; % Moment d'inèrcia Iz.
            Lmecp(i,5)=barres(i).Iy; % Moment d'inèrcia Iy.
            Lmecp(i,6:8)=barres(i).vectorIz; % Vector direcció inèrcia Iz.
            Lmecp(i,9)=barres(i).GIt; % Rigidesa a torsió.
            barra_carrega_rep(i,:)=barres(i).repartida; % Càrrega repartida.
            barra_carrega_rep_proj(i,:)=barres(i).projectada; % Càrrega projectada.
            barra_carrega_punt(i,:)=barres(i).puntual; % Càrrega puntual.
            barra_carrega_mom(i,:)=barres(i).moment; % Càrrega moment.
        end
        %disp(['/Prepara dades calcul: ',num2str(toc(tic_prep))])
    end
    function [Ncoord,Ncond,Nextfor,Lnods,Lartyp,Lmecp,barra_carrega_rep,barra_carrega_rep_proj,barra_carrega_punt,barra_carrega_mom]=prepara_dades_calcul2(factorCarrega)
        % Prepara les dades al format d'entrada de la funció de càlcul està%tic.

        %disp('Prepara dades calcul')
        %tic_prep=tic;
        Ncoord=zeros(contnus,3); % Coordenades dels nusos.
        Ncond=zeros(contnus,7); % Condicions de contorn.
        Nextfor=zeros(contnus*6,1); % Càrregues als nusos.
        for i=1:contnus
            Ncoord(i,:)=nusos(i).posicio; % Coordenades dels nusos.
            Ncond(i,1)=nusos(i).contorn; % Condicions de contorn.
            switch nusos(i).contorn
                case 1 % rodet
                    Ncond(i,2:4)=nusos(i).rodet; % Condició de contorn rodet.
                case {4,5,6} % moviments elàs%tics
                    Ncond(i,2:7)=nusos(i).rig; % Condició de contorn elas%ticitat.
                case {7,8,9} % moviments imposats
                    Ncond(i,2:7)=nusos(i).desp; % Condició de contorn moviment.
            end
            Nextfor(i*6-5:i*6-3)=nusos(i).puntual; % Càrregues puntuals als nusos.
            Nextfor(i*6-2:i*6)=nusos(i).moment; % Carregues moment als nusos.
        end

        Lnods=zeros(contbarra,2); % Connectivitat dels extrems de barra.
        Lartyp=zeros(contbarra,2); % articulació dels extrems de barra.
        Lmecp=zeros(contbarra,9); % Propietats mecàniques de les barres.
        barra_carrega_rep=zeros(contbarra,6); % Càrregues repartides.
        barra_carrega_rep_proj=zeros(contbarra,6); % Càrregues projectades.
        barra_carrega_punt=zeros(contbarra,5); % Càrregues puntuals.
        barra_carrega_mom=zeros(contbarra,5); % Càrregues moment.
        for i=1:contbarra
            Lnods(i,1)=barres(i).nusinf; % Connectivitat de l'extrem inferior de barra.
            Lnods(i,2)=barres(i).nussup; % Connectivitat de l'extrem superior de barra.
            Lartyp(i,1)=barres(i).artinf; % articulacio de l'extrem inferior de barra.
            Lartyp(i,2)=barres(i).artsup; % articulacio de l'extrem superior de barra.
            Lmecp(i,1)=barres(i).E; % Modul de Young.
            Lmecp(i,2)=9.81;  % Gravetat, herència de CME, de fet no s'utilitza.
            Lmecp(i,3)=barres(i).A; % Àrea de la secció.
            Lmecp(i,4)=barres(i).Iz; % Moment d'inèrcia Iz.
            Lmecp(i,5)=barres(i).Iy; % Moment d'inèrcia Iy.
            Lmecp(i,6:8)=barres(i).vectorIz; % Vector direcció inèrcia Iz.
            Lmecp(i,9)=barres(i).GIt; % Rigidesa a torsió.
            barra_carrega_rep(i,:)=barres(i).repartida; % Càrrega repartida.
            barra_carrega_rep(i,1)=barres(i).repartida(1)*factorCarrega;
            barra_carrega_rep_proj(i,:)=barres(i).projectada; % Càrrega projectada.
            barra_carrega_rep_proj(i,1)=barres(i).projectada(1)*factorCarrega; % Càrrega projectada.
            barra_carrega_punt(i,:)=barres(i).puntual; % Càrrega puntual.
            barra_carrega_punt(i,1)=barres(i).puntual(1)*factorCarrega; % Càrrega puntual.
            barra_carrega_mom(i,:)=barres(i).moment; % Càrrega moment.
            barra_carrega_mom(i,1)=barres(i).moment(1)*factorCarrega; % Càrrega moment.

        end
        %disp(['/Prepara dades calcul: ',num2str(toc(tic_prep))])
    end
    function dibuixa_reaccions
        % Dibuixa les reaccions.

        %disp('Dibuixa reaccions')
        %tic_dr=tic;
        hgreaccions=zeros(contnus,1); % Guarda l'objecte gràfic en una llista.
        for i=1:contnus % Repasa els nusos.
            if any(Retorn_reaccions(6*i-5:6*i)) % Si hi ha alguna reacció al nus...
                hgreaccions(i)=dibuix_carreganus(i,nusos(i).posicio,[xm,ym,zm],Retorn_reaccions(6*i-5:6*i-3)',Retorn_reaccions(6*i-2:6*i)',vista,fontcarregues,tamanyfontcarregues,fmax); % Dibuixa la reacció com una càrrega al nus.
                m=makehgtform('translate',nusos(i).posicio,'scale',s); % Escala i col·loca la càrrega a la posició del nus.
                set(hgreaccions(i),'UserData',i,'Matrix',m);
                chgcolor(hgreaccions(i),colorreaccions) % Dòna color a les reaccions.
                if strcmp(vista,'3d')
                    set(get(hgreaccions(i),'Children'),'Clipping','off') % Fa que els objectes gràfics sobresurtin de la grafica.
                else
                    set(get(hgreaccions(i),'Children'),'Clipping','on') % Fa que els objectes gràfics NO sobresurtin de la grafica.
                end
            end
        end
        %disp(['/Dibuixa reaccions: ',num2str(toc(tic_dr))])
    end

    function dibuixa_diagramesideformada
        % Dibuixa els diagrames i la deformada.

        %disp('Dibuixa diagrames i deformada')
        %tic_dd=tic;
        Tmax=0; % Tallant maxim.
        Mmax=0; % Moment maxim.
        Dmax=0; % Deformació màxima.
        mov_extrems=zeros(12,contbarra);
        for i=1:contbarra % Per a toes les barres...
            [long,esforcos,moviments,rep,proj,punt,mom,Iz,Iy]=dades_diagrama(i);
            [diagrames(i),varargout]=dibuix_diagrames(long,esforcos,moviments,rep,proj,punt,mom,barres(i).E,barres(i).A,Iz,Iy); % Calcula i dibuixa els diagrames.


            set(diagrames(i).hgN,'Parent',hg_diagrames)
            set(diagrames(i).hgTy,'Parent',hg_diagrames)
            set(diagrames(i).hgTz,'Parent',hg_diagrames)
            set(diagrames(i).hgMx,'Parent',hg_diagrames)
            set(diagrames(i).hgMy,'Parent',hg_diagrames)
            set(diagrames(i).hgMz,'Parent',hg_diagrames)
            set(diagrames(i).hgdeformada,'Parent',hg_diagrames)

            diagrames(i).num=i; % Número de barra a la qual pertany el diagrama.
            Tmax=max([Tmax,diagrames(i).Tmax/long]); % Calcula la relació tallant o axil/longitud màxima de totes les barres.
            Mmax=max([Mmax,diagrames(i).Mmax/long]); % Calcula la relació moment/longitud màxim de totes les barres.
            Dmax=max([Dmax,diagrames(i).Dmax/long]); % Calcula la relació deformació/longitud màxima de totes les barres.

        end

        sT=1/(2*Tmax); % Càlcul de l'escala dels diagrames d'axils i tallants.
        sM=1/(2*Mmax); % Càlcul de l'escala dels diagrames de moments.
        sD=1/(5*Dmax); % Càlcul de l'escala de la deformada.

        % Coloca, escala i coloreja els diagrames i la deformada.
        for i=1:numel(diagrames)
            pos=nusos(barres(i).nusinf).posicio; % El diagrama es col·loca a la posicio del nus inferior.
            vector_barra=nusos(barres(i).nussup).posicio-pos; % Vector direcció de la barra, per a calcular la matriu de rotacio dels diagrames. No s'utilitzen els eixos locals, perque poden no coincidir l'eix z local i global.
            mT=matbarra(vector_barra,pos,sT); % Càlcul de la matriu de rotació, posició i escala dels diagrames de tallant.
            mM=matbarra(vector_barra,pos,sM); % Càlcul de la matriu de rotació, posicio i escala dels diagrames de moments.
            set(diagrames(i).hgN,'Matrix',mT); % Col·locació del diagrama d'axils.
            set(diagrames(i).hgTy,'Matrix',mT); % Col·locació del diagrama de tallants en y.
            set(diagrames(i).hgTz,'Matrix',mT); % Col·locació del diagrama de tallants en z.
            set(diagrames(i).hgMx,'Matrix',mM); % Col·locació del diagrama de moments en x.
            set(diagrames(i).hgMy,'Matrix',mM); % Col·locació del diagrama de moments en y.
            set(diagrames(i).hgMz,'Matrix',mM); % Col·locació del diagrama de moments en z.
            if strcmp(vista,'3d')
                clip3d='off'; % Fa que els objectes gràfics sobresurtin de la grafica.
            else
                clip3d='on'; % Fa que els objectes gràfics NO sobresurtin de la grafica.
            end
            set(get(diagrames(i).hgN,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgTy,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgTz,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgMx,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgMy,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgMz,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgdeformada,'Children'),'Clipping',clip3d)

            escala_deformada(TL2G(:,:,i),i,sD) % Col·locació i rotació de la deformada. Aquí SI que s'utilitzen els eixos locals, ja que la deformacio es calcula en eixos locals.
            colordiagrama(diagrames(i))
        end
        %disp(['/Dibuixa diagrames i deformada: ',num2str(toc(tic_dd))])
    end

function [Mmax1,Mp,posicioMmax1,numBarra,factorCarregaFinal,mateixFactorCarrega,numFactors,numMaximsIguals,vectorEquacioMz,vectorEquacioMx,vectorEquacioMy]=dibuixa_diagramesideformada2(factorCarrega,iteracio)
        % Dibuixa els diagrames i la deformada.
        Mmax1=0;
        posicioMmax1=0;

        numBarra=0;
        factorCarregaFinal=factorCarrega;
        numMaximsIguals=-1;

        %disp('Dibuixa diagrames i deformada')
        %tic_dd=tic;
        Tmax=0; % Tallant maxim.
        Mmax=0;
        Dmax=0; % Deformació màxima.
        numFactors=1;
        momentMaxim=0;

        vectorEquacioMz=zeros(contbarra,5); %Creo una matriu amb totes les lleys de moments de la estructura
        vectorEquacioMx=zeros(contbarra,5);
        vectorEquacioMy=zeros(contbarra,5);

        mov_extrems=zeros(12,contbarra);
        for i=1:contbarra % Per a toes les barres...
            [long,esforcos,moviments,rep,proj,punt,mom,Iz,Iy]=dades_diagrama2(i,factorCarrega);

            [diagrames(i),varargout,Mmax0,posicioMmax,equacioMz,equacioMx,equacioMy]=dibuix_diagrames2(long,esforcos,moviments,rep,proj,punt,mom,barres(i).E,barres(i).A,Iz,Iy); % Calcula i dibuixa els diagrames.
            vectorSumaEquacioMz=0;
            %Busco els maxims a cada barra.

            nusInferior=barres(i).nusinf;
            nusSuperior=barres(i).nussup;
            nusInf=nusos(nusInferior).posicio;
            nusSup=nusos(nusSuperior).posicio;

            longitudBarra=((nusInf(1)-nusSup(1))^2+(nusInf(2)-nusSup(2))^2+(nusInf(3)-nusSup(3))^2)^0.5;

            %Afegeixo un vector amb la lley de moments de la barra
            %pertinent
            if contRotula>0
             %display(dadesRotules(contRotula));
            end


                vectorEquacioMz(i,:)=equacioMz(1,:);

            %vectorEquacioMz(i+1,:)=equacioMz(2,:);

            %vectorEquacioMy(i,:)=equacioMy;
            %vectorEquacioMx(i,:)=equacioMx;


            %Un cop afegit el vector a la matriu de lleys de moments, sumo
            %la nova lley amb la lley de la estructura anterior (la que
            %tenia abans de crear la ròtula)


            if contRotula>0 && iteracio==1 %Si al menys s'ha creat una ròtula i si estem a la segona iteracio, a la primera calcula el moment elastic y calcula el factor de càrrega, a la segona aplica el factor de càrrega i calcula moment final.
             if i<=length(dadesRotules(contRotula).equacioMz(i))
                 r=i;
               [posicioMmax,vectorEquacioMz,factorCarregaCalculat,Mp,Mmax0]=sumaDiagrames(vectorEquacioMz,i,Mmax0,r);
                factorCarregaCalculat=factorCarregaCalculat;

             else
                r=i;
               [posicioMmax,vectorEquacioMz,factorCarregaCalculat,Mp,Mmax0]=sumaDiagrames(vectorEquacioMz,i,Mmax0,r);
               factorCarregaCalculat=factorCarregaCalculat;

             end
            elseif contRotula>0 && iteracio==2
                Mp=barres(i).Mp;
                factorCarregaCalculat=factorCarrega;
            elseif contRotula==0 && iteracio==1
                Mp=barres(i).Mp;
                factorCarregaCalculat=Mp/Mmax0;
                Mmax0=0;
            elseif contRotula==0 && iteracio==2
                Mp=barres(i).Mp;
                factorCarregaCalculat=factorCarrega;
            end
             %display(factorCarregaCalculat);

            set(diagrames(i).hgN,'Parent',hg_diagrames)
            set(diagrames(i).hgTy,'Parent',hg_diagrames)
            set(diagrames(i).hgTz,'Parent',hg_diagrames)
            set(diagrames(i).hgMx,'Parent',hg_diagrames)
            set(diagrames(i).hgMy,'Parent',hg_diagrames)
            set(diagrames(i).hgMz,'Parent',hg_diagrames)
            set(diagrames(i).hgdeformada,'Parent',hg_diagrames)

            diagrames(i).num=i; % Número de barra a la qual pertany el diagrama.
            Tmax=max([Tmax,diagrames(i).Tmax/long]); % Calcula la relació tallant o axil/longitud màxima de totes les barres.
            Mmax=max([Mmax,diagrames(i).Mmax/long]); % Calcula la relació moment/longitud màxim de totes les barres.
            Dmax=max([Dmax,diagrames(i).Dmax/long]); % Calcula la relació deformació/longitud màxima de totes les barres.

            %Es crea un objecte factor de càrrega per cada una de les barres on es guarda el factor de carrega de cada una d'elles, amb la finaliat de trobar posteriorment el mínim factor de càrrega que crea una ròtula plàstica
            if abs(Mp-Mmax0)<=1*10^-6 || contRotula==0
                factorsCarrega(numFactors)=minimFactorCarrega; %Es crea un nou objecte minim factor càrrega, em servira per trobar el mínim.
                factorsCarrega(numFactors).numFactor=numFactors;
                factorsCarrega(numFactors).factorCarga=factorCarregaCalculat;
                factorsCarrega(numFactors).Mp=Mp;
                factorsCarrega(numFactors).Mmax=Mmax0;
                factorsCarrega(numFactors).posicioMmax=posicioMmax;
                factorsCarrega(numFactors).numBarra=i;
                factorsCarrega(numFactors).nusInferior=barres(i).nusinf;
                factorsCarrega(numFactors).nusSuperior=barres(i).nussup;
                numFactors=numFactors+1; %Sumo un per la propera barra.
                contador=0; %Aques contador em serveix per trobar el mínim despres, aquí només defineixo la variable en 0.
                mateixFactorCarrega=-1; %El defineixo menys 1 doncs al seüent bucle se li suma un més a a causa de la comparació amb el mateix terme a la primera iteració.
            else
                Mmax1=0;
                posicioMmax1=0;
                mateixFactorCarrega=-1;
            end

        end

        %Busco el minim dels factors de càrrega i la posibilitat que dues
        %barres tinguin el mateix factor de càrrega. (doncs pel mateix
        %valor es creen dos ròtules).
        display(contRotula);
        %if numFactors>0
            for i=1:numFactors-1 %Amb aquest contador busco el minim dels factors de carrega. (li resto un, ja que a la sortida del bucle anterior, li he sumat un que en teoria no s'ha creat)
               if contador==0 %Si el contador esta a 0, indica que encara no s'ha executat ninguna iteració, i per tant no tenim dos valors per comparar.
                factorCarregaAnalitzat2=factorsCarrega(i).factorCarga;%Definim els dos valors amb el mateix terme (la primera iteració)
                factorCarregaAnalitzat1=factorsCarrega(i).factorCarga;
                contador=1; %Posem el contador a 1 per evitar que torni a entrar a la següent itració.
               else
                factorCarregaAnalitzat1=factorsCarrega(i).factorCarga; %En aquest cas, ja s'ha efectuat la primera iteració i per tant ja tenim valor sper comparar.
               end

               if factorCarregaAnalitzat1<=factorCarregaAnalitzat2 %Comparem els valor,si es dona un valor de factor de càrrega menor al que teniem amb anterioritat, entra dintre del condicionant i defineix totes el factor de carrega mínim i dades que despres s'utuilitzaran.
                    factorCarregaFinal=factorCarregaAnalitzat1; %Defineix el factor de carrega final
                    Mp=factorsCarrega(i).Mp;                    %Defineix el moment plàstic de la barra, que em permetrà compararlo amb el moment màxim de la barra i veure si es supera. (En cas afirmatiu es crea una ròtula i torna a començar tot el procès)
                    Mmax1=factorsCarrega(i).Mmax;               %Defineix el moment màxim a la barra.
                    numBarra=factorsCarrega(i).numBarra;        %Defineix a quina barra s'ha produit el moment màxim
                    posicioMmax1=factorsCarrega(i).posicioMmax; %Defineix la posició del moment màxim sobre la barra en coordenades locals.

                    if abs(factorCarregaAnalitzat1-factorCarregaAnalitzat2)<=0.001 %si dos (o més) factors de càrrega son iguals i a l'hora aquests son mínims entra al bucle.
                        mateixFactorCarrega=mateixFactorCarrega+1;
                    end
               end

            end
       % end

        sT=1/(2*Tmax); % Càlcul de l'escala dels diagrames d'axils i tallants.
        sM=1/(2*Mmax); % Càlcul de l'escala dels diagrames de moments.
        sD=1/(5*Dmax); % Càlcul de l'escala de la deformada.

        % Coloca, escala i coloreja els diagrames i la deformada.
        for i=1:numel(diagrames)
            pos=nusos(barres(i).nusinf).posicio; % El diagrama es col·loca a la posicio del nus inferior.
            vector_barra=nusos(barres(i).nussup).posicio-pos; % Vector direcció de la barra, per a calcular la matriu de rotacio dels diagrames. No s'utilitzen els eixos locals, perque poden no coincidir l'eix z local i global.
            mT=matbarra(vector_barra,pos,sT); % Càlcul de la matriu de rotació, posició i escala dels diagrames de tallant.
            mM=matbarra(vector_barra,pos,sM); % Càlcul de la matriu de rotació, posicio i escala dels diagrames de moments.
            set(diagrames(i).hgN,'Matrix',mT); % Col·locació del diagrama d'axils.
            set(diagrames(i).hgTy,'Matrix',mT); % Col·locació del diagrama de tallants en y.
            set(diagrames(i).hgTz,'Matrix',mT); % Col·locació del diagrama de tallants en z.
            set(diagrames(i).hgMx,'Matrix',mM); % Col·locació del diagrama de moments en x.
            set(diagrames(i).hgMy,'Matrix',mM); % Col·locació del diagrama de moments en y.
            set(diagrames(i).hgMz,'Matrix',mM); % Col·locació del diagrama de moments en z.
            if strcmp(vista,'3d')
                clip3d='off'; % Fa que els objectes gràfics sobresurtin de la grafica.
            else
                clip3d='on'; % Fa que els objectes gràfics NO sobresurtin de la grafica.
            end
            set(get(diagrames(i).hgN,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgTy,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgTz,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgMx,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgMy,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgMz,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgdeformada,'Children'),'Clipping',clip3d)

            escala_deformada(TL2G(:,:,i),i,sD) % Col·locació i rotació de la deformada. Aquí SI que s'utilitzen els eixos locals, ja que la deformacio es calcula en eixos locals.
            colordiagrama(diagrames(i))
        end
        %disp(['/Dibuixa diagrames i deformada: ',num2str(toc(tic_dd))])

end

function dibuixa_diagramesideformada3(factorCarrega,iteracio)
        % Dibuixa els diagrames i la deformada.

        %disp('Dibuixa diagrames i deformada')
        %tic_dd=tic;
        Tmax=0; % Tallant maxim.
        Mmax=0;
        Dmax=0; % Deformació màxima.

        mov_extrems=zeros(12,contbarra);
        for i=1:contbarra % Per a toes les barres...

            [long,esforcos,moviments,rep,proj,punt,mom,Iz,Iy]=dades_diagrama2(i,factorCarrega);
            [diagrames(i),varargout,Mmax0,posicioMmax,equacioMz,equacioMx,equacioMy]=dibuix_diagrames2(long,esforcos,moviments,rep,proj,punt,mom,barres(i).E,barres(i).A,Iz,Iy); % Calcula i dibuixa els diagrames.

            set(diagrames(i).hgN,'Parent',hg_diagrames)
            set(diagrames(i).hgTy,'Parent',hg_diagrames)
            set(diagrames(i).hgTz,'Parent',hg_diagrames)
            set(diagrames(i).hgMx,'Parent',hg_diagrames)
            set(diagrames(i).hgMy,'Parent',hg_diagrames)
            set(diagrames(i).hgMz,'Parent',hg_diagrames)
            set(diagrames(i).hgdeformada,'Parent',hg_diagrames)

            diagrames(i).num=i; % Número de barra a la qual pertany el diagrama.
            Tmax=max([Tmax,diagrames(i).Tmax/long]); % Calcula la relació tallant o axil/longitud màxima de totes les barres.
            Mmax=max([Mmax,diagrames(i).Mmax/long]); % Calcula la relació moment/longitud màxim de totes les barres.
            Dmax=max([Dmax,diagrames(i).Dmax/long]); % Calcula la relació deformació/longitud màxima de totes les barres.

        end

        sT=1/(2*Tmax); % Càlcul de l'escala dels diagrames d'axils i tallants.
        sM=1/(2*Mmax); % Càlcul de l'escala dels diagrames de moments.
        sD=1/(5*Dmax); % Càlcul de l'escala de la deformada.

        % Coloca, escala i coloreja els diagrames i la deformada.
        for i=1:numel(diagrames)
            pos=nusos(barres(i).nusinf).posicio; % El diagrama es col·loca a la posicio del nus inferior.
            vector_barra=nusos(barres(i).nussup).posicio-pos; % Vector direcció de la barra, per a calcular la matriu de rotacio dels diagrames. No s'utilitzen els eixos locals, perque poden no coincidir l'eix z local i global.
            mT=matbarra(vector_barra,pos,sT); % Càlcul de la matriu de rotació, posició i escala dels diagrames de tallant.
            mM=matbarra(vector_barra,pos,sM); % Càlcul de la matriu de rotació, posicio i escala dels diagrames de moments.
            set(diagrames(i).hgN,'Matrix',mT); % Col·locació del diagrama d'axils.
            set(diagrames(i).hgTy,'Matrix',mT); % Col·locació del diagrama de tallants en y.
            set(diagrames(i).hgTz,'Matrix',mT); % Col·locació del diagrama de tallants en z.
            set(diagrames(i).hgMx,'Matrix',mM); % Col·locació del diagrama de moments en x.
            set(diagrames(i).hgMy,'Matrix',mM); % Col·locació del diagrama de moments en y.
            set(diagrames(i).hgMz,'Matrix',mM); % Col·locació del diagrama de moments en z.
            if strcmp(vista,'3d')
                clip3d='off'; % Fa que els objectes gràfics sobresurtin de la grafica.
            else
                clip3d='on'; % Fa que els objectes gràfics NO sobresurtin de la grafica.
            end
            set(get(diagrames(i).hgN,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgTy,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgTz,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgMx,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgMy,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgMz,'Children'),'Clipping',clip3d)
            set(get(diagrames(i).hgdeformada,'Children'),'Clipping',clip3d)

            escala_deformada(TL2G(:,:,i),i,sD) % Col·locació i rotació de la deformada. Aquí SI que s'utilitzen els eixos locals, ja que la deformacio es calcula en eixos locals.
            colordiagrama(diagrames(i))
        end
        %disp(['/Dibuixa diagrames i deformada: ',num2str(toc(tic_dd))])
end
    function [M,posicioMmax]=factorCarrega(vectorEquacioMz,i,r,factorCarregaCalculat,Mp,cas)
        vectorSumaEquacioMz=vectorEquacioMz(i,1:3)*factorCarregaCalculat;
                    for cont=1:1:contRotula %Li sumo totes les lleis anteriors multiplicades pel seu corresponent factor de càrrega
                        if  cont==1
                            factorAnterior=1;
                        else
                            factorAnterior=dadesRotules(cont).factorCarrega;
                        end
                        if factorAnterior <= 1*10^-5
                            factorAnterior=0;
                        end
                        vectorSumaEquacioMz=vectorSumaEquacioMz+dadesRotules(cont).equacioMz(r,1:3)*factorAnterior; %Sumo la llei antiga, mes la nova multiplicada pel factor de càrega (doncs no fa falta tornar a calcular la llei)
                    end
                    %Afegeixo les longituds de la barra al vector
                    vectorSumaEquacioMz(4:5)=vectorEquacioMz(i,4:5);
                    %Busco els zeros de la equacio
                    zerosEquacioMz=zero(vectorSumaEquacioMz);
                    %Ara busco els màxims
                    [Mmax,posicioMmax]=maxims(i,zerosEquacioMz,vectorSumaEquacioMz);
                    if cas==0
                        M=Mp-Mmax;
                    else
                        display(factorCarregaCalculat);
                        M=Mmax;
                    end
    end

    function [Mmax0,posicioMmax,factorCarregaCalculat,Mp]=biseccio(i,vectorEquacioMz,r)
          Mp=barres(i).Mp;
                  %Faig servir el metode de la biseccio per obtenir el
                  %valor del factor que fagi que el moment sigui igual al
                  %moment plastic Mmax-Mp=0
                  %Interval a-b del metode
                  fk=0;
                  fk1=100;
                  %Imatge de a i b.
                  [M1,posicioMmax]=factorCarrega(vectorEquacioMz,i,r,fk,Mp,0);
                  %[M2,posicioMmax]=factorCarrega(vectorEquacioMz,i,r,fk1,Mp,0);
                  iteracio3=0;
                  %Algoritme del metode
                  Mm=1;
                  while abs(Mm)>=1*10^-6  %Itero fins que es supera el moment plastic a la barra
                     m=(fk+fk1)/2;
                     iteracio3=iteracio3+1;
                    [Mm,posicioMmax]=factorCarrega(vectorEquacioMz,i,r,m,Mp,0);
                     if Mm*M1>0
                         fk=m;
                         ffinal=fk;
                         M1=Mm;
                     else
                        fk1=m;
                        ffinal=fk1;
                     end
                  end
                  display(iteracio3);
                  %Aplico el metode final i obtinc el valor del moment
                  %maxim.

                 [Mmax0,posicioMmax]=factorCarrega(vectorEquacioMz,i,r,m,Mp,1);
                  display(Mmax0);
                  display(i);
                  display(posicioMmax);
                  factorCarregaCalculat=ffinal;

    end

    function [Mmax0,posicioMmax,factorCarregaCalculat,Mp]=secant(i,vectorEquacioMz,r)
         Mp=barres(i).Mp;

         a=0.6;
         b=1;
         [fa,posicioMmax]=factorCarrega(vectorEquacioMz,i,r,a,Mp,0);
         [fb,posicioMmax]=factorCarrega(vectorEquacioMz,i,r,b,Mp,0);
         xs = b - ((b - a) / (fb - fa))*fb;

         iteracio3=0;
         while abs(fa)>=1*10^-6
             b=a;
             a=xs;
             iteracio3=iteracio3+1;

             [fb,posicioMmax]=factorCarrega(vectorEquacioMz,i,r,b,Mp,0);
             [fa,posicioMmax]=factorCarrega(vectorEquacioMz,i,r,a,Mp,0);
             xs = b - ((b - a) / (fb - fa))*fb;

         end
         display(iteracio3);
         [Mmax0,posicioMmax]=factorCarrega(vectorEquacioMz,i,r,xs,Mp,1);
         factorCarregaCalculat=abs(xs);
    end


    function [posicioMmax,vectorEquacioMz,factorCarregaCalculat,Mp,Mmax0]=sumaDiagrames(vectorEquacioMz,i,Mmax0,r)

         %Comprobo que la barra no estigui dividida a causa de crear
         %una nova ròtula
        if vectorEquacioMz(i,4:5)==dadesRotules(contRotula).equacioMz(r,4:5)

                [Mmax0,posicioMmax,factorCarregaCalculat,Mp]=secant(i,vectorEquacioMz,r);

                %vectorEquacioMz=vectorSumaEquacioMz; %Aixo fa que al guardar les dades de les rotules, la llei que es guardi sigui la suma de les n-esimes estructures evaluades.

               else %En cas de que no coincideixin,doncs s'ha creat una ròtula al centre de barra, les separo i les sumo
                  factorCarregaCalculat=0;
                  %S'ha de vigilar amb la re numeracio de barres, doncs si
                  %s'ha produit una ròtula al centre d'una barra hi haura
                  %reordenació

                  display('Barres partides');
                  momentMaxim=0;
                  Mp=barres(i).Mp;
                  %Defineixo la longitud de la barra
                  xMax=vectorEquacioMz(i,5);
                  xMin=vectorEquacioMz(i,4);
                  while Mp>Mmax0
                       for z=xMin:0.1:xMax
                         moment1=(vectorEquacioMz(i,1)*z^2+vectorEquacioMz(i,2)*z+vectorEquacioMz(i,3))*factorCarregaCalculat;
                         for cont=1:1:contRotula
                             moment2=dadesRotules(cont).equacioMz(r,1)*z^2+dadesRotules(cont).equacioMz(r,2)*z+dadesRotules(cont).equacioMz(r,3);
                             moment2=moment2+dadesRotules(cont).factorCarrega;
                         end
                         momentTotal=moment1+moment2;
                         if abs(momentTotal)>abs(momentMaxim)
                             momentMaxim=momentTotal;
                             Mmax0=momentTotal;
                             posicioMmax=z;
                         end
                       end
                     factorCarregaCalculat=factorCarregaCalculat+0.1;
                  end

         end
    end
%    function [Mmax,posicioMmax1,numMaximsIguals]=maxims2(i,zerosEquacioMz,equacioMz)
          %Busca el valor dels màxims
          %Redefineixo les variables per tornar a evaluar la nova barra
%               Maxim1=0;
%               xMaxim1=0;
%               Maxim2=0;
%               xMaxim2=0;
%               Maxim3=0;
%               xMaxim3=0;
%               Moment1=0;
%               numeroMaxims=0;
%
%
%                 maximsBarres(i)=maximsBarra; %Nou objecte maxim barra
%                 maximsBarres(i).numMaxims=numeroMaxims;
%
%
%             for x=1:length(zerosEquacioMz) %Busco quans zeros hi han al diagrama de moemtns de la barra
%               if zerosEquacioMz(x)~=0 && x==1
%                 dx=abs(zerosEquacioMz(x))/100; %Defineixo el increment de x per calcular cada increment de moment
%
%                     for z=0:dx:zerosEquacioMz(x); %Incremento x entre els zeros de la funcio
%                         Moment=equacioMz(1)*z^2+equacioMz(2)*z+equacioMz(3); %Calculo el valor del moment
%
%                         if abs(Moment)>abs(Moment1)
%                            Moment1=Moment;
%                            xMaxim1=z;
%                            Maxim1=Moment;
%                         end
%                     end
%                  if abs(Maxim1)>0.001 %Si el mínim es major a 0
%                      numeroMaxims=numeroMaxims+1;
%                      maximsBarres(i).maxims(numeroMaxims)=Maxim1;
%                      maximsBarres(i).posicioMaxims(numeroMaxims)=xMaxim1;
%                      maximsBarres(i).numBarra=i;
%                      Maxim1=0;
%                      xMaxim1=0;
%                  end
%                   Moment1=0;
%
%               end
%
%               if zerosEquacioMz(x)~=0 && x>1
%                 dx=abs(zerosEquacioMz(x-1)-zerosEquacioMz(x))/100; %Defineixo el increment de x per calcular cada increment de moment
%                     for z=zerosEquacioMz(x-1):dx:zerosEquacioMz(x); %Incremento x entre els zeros de la funcio
%                         Moment=equacioMz(1)*z^2+equacioMz(2)*z+equacioMz(3); %Calculo el valor del moment
%
%                          if abs(Moment)>abs(Moment1)
%                            Moment1=Moment;
%                            xMaxim2=z;
%                            Maxim2=Moment;
%                         end
%                     end
%                  if abs(Maxim2)>0.001 %Si el mínim es major a 0
%                      numeroMaxims=numeroMaxims+1;
%                      maximsBarres(i).maxims(numeroMaxims)=Maxim2;
%                      maximsBarres(i).posicioMaxims(numeroMaxims)=xMaxim2;
%                      maximsBarres(i).numBarra=i;
%                      Maxim2=0;
%                      xMaxim2=0;
%                  end
%
%                   Moment1=0;
%               end
%
%               if zerosEquacioMz(x)~=equacioMz(5) && x==length(zerosEquacioMz)
%                 dx=abs((zerosEquacioMz(x)-equacioMz(5))/100); %Defineixo el increment de x per calcular cada increment de moment
%                     for z=zerosEquacioMz(x):dx:equacioMz(5); %Incremento x entre els zeros de la funcio
%                         Moment=equacioMz(1)*z^2+equacioMz(2)*z+equacioMz(3); %Calculo el valor del moment
%
%                          if abs(Moment)>abs(Moment1)
%                            Moment1=Moment;
%                            xMaxim3=z;
%                            Maxim3=Moment;
%                         end
%                     end
%                  if abs(Maxim3)>0.001 %Si el mínim es major a 0
%                      numeroMaxims=numeroMaxims+1;
%                      maximsBarres(i).maxims(numeroMaxims)=Maxim3;
%                      maximsBarres(i).posicioMaxims(numeroMaxims)=xMaxim3;
%                      maximsBarres(i).numBarra=i;
%                      Maxim3=0;
%                      xMaxim3=0;
%                  end
%
%                   Moment1=0;
%               end
%             end
%
%             %Es necesari comprovar si el maxim actual, esta repetit, es a
%             %dir, s'ha creat amb anterioritat
%
%             for p=1:numeroMaxims %Comprobo tots els màxims trobats a la barra
%                 for z=1:1:contRotula %Comprobo totes les ròtules creades
%                     if maximsBarres(i).posicioMaxims(p)==dadesRotules(z).posicioMmax1 && i==dadesRotules(z).barraNum %Si la posicio del màxim que comprobo es la mateixa posició on s'ha creat una ròtula anteriorment y a la mateixa barra, elimino el máxim
%                         %display('maxim repetit');
%                         %display(maximsBarres(i).posicioMaxims(p));
%                         %display(i);
%                         maximsBarres(i).maxims(p)=0;
%                         maximsBarres(i).posicioMaxims(p)=0;
%                     end
%                 end
%             end
%
%             %Dels màxims que hem queden, comprobo quin es el màxim absolut
%             Mmax=max(abs(maximsBarres(i).maxims));
%             %Ara busco la seva posició
%             for c=1:numeroMaxims
%                 if Mmax==abs(maximsBarres(i).maxims(c))
%                     posicioMmax1=maximsBarres(i).posicioMaxims(c);
%                 end
%             end
% end% Aquesta es pot trure doncs s'ha substituit per la funcio maxims que es més eficient, de moment la guardo de proba


    function [Mmax,posicioMmax1,numMaximsIguals]=maxims(i,zerosEquacioMz,equacioMz)
       %Com a máxim tindrem 3 maxims relatius a una barra (parabolic).
       Maxim1=0;
       Maxim2=0;
       Maxim3=0;
       numeroMaxims=0;
       maximsBarres(i)=maximsBarra; %Nou objecte maxim barra
       %Calculo la derivada de la ecuacio de moments, la igualo a 0 y
       %obtinc:
       a=equacioMz(1);
       b=equacioMz(2);
       c=equacioMz(3);
       x=-b/(2*a);

       %Calculo els 3 maxims relatius:
       %1 al extrem de la barra
       Maxim1=c;
       %2 al punt x calculat amb la derivada
       Maxim2=a*x^2+b*x+c;
       %3 al segon extrem de la barra
       xExtrem=equacioMz(5);
       Maxim3=a*xExtrem^2+b*xExtrem+c;

       if abs(Maxim3)>0.001 %Si el mínim es major a 0
               numeroMaxims=numeroMaxims+1;
               maximsBarres(i).maxims(numeroMaxims)=Maxim3;
               maximsBarres(i).posicioMaxims(numeroMaxims)=xExtrem;
               maximsBarres(i).numBarra=i;
       end

       if abs(Maxim1)>0.001 %Si el mínim es major a 0
              numeroMaxims=numeroMaxims+1;
               maximsBarres(i).maxims(numeroMaxims)=Maxim1;
               maximsBarres(i).posicioMaxims(numeroMaxims)=0;
               maximsBarres(i).numBarra=i;

       end
       if abs(Maxim2)>0.001 %Si el mínim es major a 0
               numeroMaxims=numeroMaxims+1;
               maximsBarres(i).maxims(numeroMaxims)=Maxim2;
               maximsBarres(i).posicioMaxims(numeroMaxims)=x;
               maximsBarres(i).numBarra=i;
       end

       %Comprobo que no siguin maxims repetits ja a altres rotules
       for p=1:numeroMaxims %Comprobo tots els màxims trobats a la barra
                for z=1:1:contRotula %Comprobo totes les ròtules creades
                    %Comprobo posicio del nou maxim i posicio rotules ja
                    %creades
                    if maximsBarres(i).posicioMaxims(p)~=0 && maximsBarres(i).posicioMaxims(p)~=xExtrem
                        if maximsBarres(i).posicioMaxims(p)==dadesRotules(z).posicioMmax1 && i==dadesRotules(z).barraNum %Si la posicio del màxim que comprobo es la mateixa posició on s'ha creat una ròtula anteriorment y a la mateixa barra, elimino el máxim
                            maximsBarres(i).maxims(p)=0;
                            maximsBarres(i).posicioMaxims(p)=0;
                        end
                    end
                    %Comprobo si el nou maxim esta a un nus on ja s'ha
                    %creat una rótula
                    if maximsBarres(i).posicioMaxims(p)==0
                        if barres(i).nusinf==dadesRotules(z).nusRotula %&& dadesRotules(z).barraNum==i
                            maximsBarres(i).maxims(p)=0;
                            maximsBarres(i).posicioMaxims(p)=0;
                        end
                    end
                    if  maximsBarres(i).posicioMaxims(p)==xExtrem
                        if barres(i).nussup==dadesRotules(z).nusRotula %&& dadesRotules(z).barraNum==i
                            maximsBarres(i).maxims(p)=0;
                            maximsBarres(i).posicioMaxims(p)=0;
                        end
                    end
                end
       end

        %Calculo el maxim absolut entre ells

        Mmax=max(abs(maximsBarres(i).maxims));

       %Segons quin hagi estat el màxim li adjunto la seva posició.
        for c=1:numeroMaxims
                 if Mmax==abs(maximsBarres(i).maxims(c))
                    posicioMmax1=maximsBarres(i).posicioMaxims(c);
                 end
        end
end


    function x0=zero(P)
    [n,l]=size(P);
    x0=[];
    for i=1:n % Per a tots els trams comproba les arrels dels polinomis.
        x=roots(P(i,1:l-2)); % Arrels dels polinomis que defineixen els trams.
        for j=1:size(x,1); % Per a totes les arrels calculades...
            if isreal(x(j)) && x(j)>=P(i,l-1) && x(j)<=P(i,l) % Si l'arrel és un nombre real i està compresa entre els límits del tram.
                x0=[x0,x(j)]; % Afegeix l'arrel a la llista.
            end
        end
    end

    for i=2:n % Comproba els límits entre trams.
        if polyval(P(i-1,1:l-2),P(i-1,l)) * polyval(P(i,1:l-2),P(i,l-1)) < 0 % Si el valor final del tram anterior i el valor incial del tram actual són de signe diferent...
            x0=[x0,P(i,l-1)]; % Afegeix el límit entre els trams a la llista.
        end
    end
    x0=unique(x0); % Ordena i elimina resultats repetits.
end

    function [long,esforcos,moviments,rep,proj,punt,mom,Iz,Iy]=dades_diagrama(n)

        %disp(['Prepara dades calcul diagrames barra nº ',num2str(n)])
        %tic_dd=tic;
        n1=barres(n).nusinf;
        n2=barres(n).nussup;
        T=TL2G(:,:,n)'; % Matriu de canvi de base d'exos globals a locals.
        esforcos(1:12)=Retorn_esforcos_barres(n,1:12); % Esforços en extrems de barra en eixos locals.
        moviments=[T*Retorn_moviments(n1*6-5:n1*6-3);T*Retorn_moviments(n1*6-2:n1*6);T*Retorn_moviments(n2*6-5:n2*6-3);T*Retorn_moviments(n2*6-2:n2*6)]; % Moviments dels extrems de barra en eixos locals.
        mov_extrems(:,n)=moviments; % Guarda els moviments en extrems de barra en eixos locals per a la funcio que mostra l'informe de resultats.
        vbarra=nusos(n2).posicio-nusos(n1).posicio; % Vector barra.
        long=norm(vbarra); % Longitud de la barra.
        rep=[barres(n).repartida(1),(T*barres(n).repartida(2:4)')',barres(n).repartida(5:6)]; % Carrega repartida en eixos locals.
        proj=[barres(n).projectada(1),(T*barres(n).projectada(2:4)')',barres(n).projectada(5:6)]; % Càrrega projectada en eixos locals.
        punt=[barres(n).puntual(1),(T*barres(n).puntual(2:4)')',barres(n).puntual(5)]; % Carrega en eixos locals.
        mom=[barres(n).moment(1),(T*barres(n).moment(2:4)')',barres(n).moment(5)]; % Moments en eixos locals.
        Iz=barres(n).Iz; % Inercia Iz.
        if all(barres(n).vectorIz==0) % Si no esta definit el vector direcció d'Iz, Iy=Iz.
            Iy=Iz;
        else
            Iy=barres(n).Iy;
        end
        %disp(['/Prepara dades calcul diagrames barra nº ',num2str(n),': ',num2str(toc(tic_dd))])
    end

    function [long,esforcos,moviments,rep,proj,punt,mom,Iz,Iy]=dades_diagrama2(n,factorCarrega)

        %disp(['Prepara dades calcul diagrames barra nº ',num2str(n)])
        %tic_dd=tic;
        n1=barres(n).nusinf;
        n2=barres(n).nussup;
        T=TL2G(:,:,n)'; % Matriu de canvi de base d'exos globals a locals.
        esforcos(1:12)=Retorn_esforcos_barres(n,1:12); % Esforços en extrems de barra en eixos locals.
        moviments=[T*Retorn_moviments(n1*6-5:n1*6-3);T*Retorn_moviments(n1*6-2:n1*6);T*Retorn_moviments(n2*6-5:n2*6-3);T*Retorn_moviments(n2*6-2:n2*6)]; % Moviments dels extrems de barra en eixos locals.
        mov_extrems(:,n)=moviments; % Guarda els moviments en extrems de barra en eixos locals per a la funcio que mostra l'informe de resultats.
        vbarra=nusos(n2).posicio-nusos(n1).posicio; % Vector barra.
        long=norm(vbarra); % Longitud de la barra.
        rep=[barres(n).repartida(1)*factorCarrega,(T*barres(n).repartida(2:4)')',barres(n).repartida(5:6)]; % Carrega repartida en eixos locals.
        proj=[barres(n).projectada(1)*factorCarrega,(T*barres(n).projectada(2:4)')',barres(n).projectada(5:6)]; % Càrrega projectada en eixos locals.
        punt=[barres(n).puntual(1)*factorCarrega,(T*barres(n).puntual(2:4)')',barres(n).puntual(5)]; % Carrega en eixos locals.
        mom=[barres(n).moment(1)*factorCarrega,(T*barres(n).moment(2:4)')',barres(n).moment(5)]; % Moments en eixos locals.
        Iz=barres(n).Iz; % Inercia Iz.
        if all(barres(n).vectorIz==0) % Si no esta definit el vector direcció d'Iz, Iy=Iz.
            Iy=Iz;
        else
            Iy=barres(n).Iy;
        end
        %disp(['/Prepara dades calcul diagrames barra nº ',num2str(n),': ',num2str(toc(tic_dd))])
    end

    function colordiagrames
        % Coloreja tots els diagrames i la deformada de l'estructura.

        %disp('Color diagrames')
        %tic_cd=tic;
        for i=1:contbarra
            colordiagrama(diagrames(i))
        end
        %disp(['/Color diagrames: ',num2str(toc(tic_cd))])
    end

    function colordiagrama(diag)
        % Coloreja els digramaes i la deformada de l'obecte diagrama.

        %disp(['Color diagrama ',num2str(diag.num)])
        %tic_cd=tic;
        chgcolor(diag.hgN,colorN); % Color diagrama d'axils.
        chgcolor(diag.hgTy,colorTy); % Color diagrama de tallants en y.
        chgcolor(diag.hgTz,colorTz); % Color diagrama de tallants en z.
        chgcolor(diag.hgMx,colorMx); % Color diagrama de moments en x.
        chgcolor(diag.hgMy,colorMy); % Color diagrama de moments en y.
        chgcolor(diag.hgMz,colorMz); % Color diagrama de moments en z.
        chgcolor(diag.hgdeformada,colordeformada); % Color deformada.
        %disp(['/Color diagrama ',num2str(diag.num),': ',num2str(toc(tic_cd))])
    end

    function mat=matbarra(vector_barra,posicio,escala)
        % Calcula la matriu de gir, escala i posició per a representar
        % els diagrames al plànol de la vista.
        % Calcula la matriu per tal que els diagrames es representin al
        % plà format per la barra i l'eix Vertical segons la vista.

        vector_barra=vector_barra/norm(vector_barra);
        if abs(vector_barra(3))==1
            vector3=[-vector_barra(3),0,0];
            vector2=[0,1,0];
        else
            vector2=cross([0,0,1],vector_barra); % Calcula dos vectors perpendiculars al primer i entre ells per crear la matriu de canvi de base.
            vector2=vector2/norm(vector2);
            vector3=cross(vector_barra,vector2);
            vector3=vector3/norm(vector3);
        end

        if strcmp(vista,'xz') || strcmp(vista,'yz') % Si s'esta a les vistes amb eix Vertical z, s'intercanvien els vectors per mostrar els diagrames adequadament.
            vector2_=vector3;
            vector3=vector2;
            vector2=vector2_;
        end
        mat(1:4,1)=[vector_barra';0]; % Matriu de gir, posició i escala.
        mat(1:4,2)=[vector2'*escala;0];
        mat(1:4,3)=[vector3'*escala;0];
        mat(1:4,4)=[posicio';1];
    end

    function escala_deformada(TL2G,n,escala)
        % Escala, gira  i col·loca la deformada.
        % Afegeix els scatter3 que marquen la fletxa màxima.

        mat(1:4,1)=[TL2G(:,1);0]; % Direcció i escala x.
        mat(1:4,2)=[TL2G(:,2)*escala;0]; % Direcció i escala y.
        mat(1:4,3)=[TL2G(:,3)*escala;0]; % Direcció i escala z.
        mat(1:4,4)=[nusos(barres(n).nusinf).posicio';1]; % Posició.

        diag=findobj(diagrames(n).hgdeformada,'type','line'); % Línia que representa la deformada.
        defx=get(diag,'UserData'); % Recupera els valors per al recàlcul de la deformada en x escalada.
        x=defx.x+defx.e*escala; % Recalcula la deformada en x escalada.
        set(diag,'X',x) % Modifica el valors en x de la linia que representa la deformada, amb la nova deformació calculada.
        set(diagrames(n).hgdeformada,'Matrix',mat) %  Col·loca i escala la deformada a l'extrem inferior de la barra.
    end

    function resultat_barra(n)
        % S'executa quan es cliqueja sobre una barra a la presentació de
        % resultats de tota l'estructura.
        % Mostra els resultats detallats per a la barra seleccionada.
        % Mostra dos gràfiques amb la representació dels eixos locals xy i
        % xz on es presenten els diagrames i la deformada amb valors
        % numerics a la meitat esquerra. A la meitat dreta mostra una caixa
        % de texte amb un informe de propietats de la barra, lleis
        % d'esforços i deformació.

        grafica=grafica_resxy;
        long=norm(nusos(barres(n).nussup).posicio-nusos(barres(n).nusinf).posicio); % Longitud de la barra.

        set(grafica_est,'Visible','off')

        set(txtbox_res,'Visible','on') % Fa visible el textbox que conté l'informe.
        set(grafica_resxy,'XLim',[0-long/10,long*1.1],'YLim',[-1.1,1.4]) % Dimensiona la presentació en xy perque hi capiga la barra, els diagrames es dimensionaran entre -1 i 1.
        set(grafica_resxz,'XLim',[0-long/10,long*1.1],'ZLim',[-1.1,1.4]) % Dimensiona la presentació en xz perque hi capiga la barra, els diagrames es dimensionaran entre -1 i 1.
        set(get(grafica_est,'Children'),'Visible','off') % Oculta la gràfica de l'estructura.

        txtnum=[num2str(barres(n).num),' (',num2str(barres(n).nusinf),'-',num2str(barres(n).nussup),')']; % Texte numero de barra i nusos.
        text(0-long/15,1.4,0,['X-Y local barra nº',txtnum,':'],'VerticalAlignment','top','Parent',grafica_resxy) % Texte títol vista xy.
        text(0-long/15,0,1.4,['X-Z local barra nº',txtnum,':'],'VerticalAlignment','top','Parent',grafica_resxz) % Texte títol vista xz.

        line([0,long],[0,0],[0,0],'color','k','LineWidth',2,'Parent',grafica_resxy) % Dibuixa la barra a la vista xy.
        line([0,long],[0,0],[0,0],'color','k','LineWidth',2,'Parent',grafica_resxz) % Dibuixa la barra a la vista xz.

        [long,esforcos,moviments,rep,proj,punt,mom,Iz,Iy]=dades_diagrama(n);
        [diag_presxy,informe]=dibuix_diagrames(long,esforcos,moviments,rep,proj,punt,mom,barres(n).E,barres(n).A,Iz,Iy); % Calcula i dibuixa els diagrames.
        diag_presxy.Mmax=diag_presxy.Mmax+(diag_presxy.Mmax==0); % Impedeix que Mmax sigui zero.
        diag_presxy.Tmax=diag_presxy.Tmax+(diag_presxy.Tmax==0); % Impedeix que Mmax sigui zero.
        diag_presxy.Dmax=diag_presxy.Dmax+(diag_presxy.Dmax==0); % Impedeix que Mmax sigui zero.

        colordiagrama(diag_presxy) % Coloreja els diagrames.
        diag_presxz=diag_presxy; % Copia els handles (no els objectes, nomes la referencia) dels dibuixos dels diagrames en representacio xy a la representacio xz.
        diag_presxz.hgdeformada=copyobj(diag_presxy.hgdeformada,grafica_resxz); % Copia la deformada (crea un objecte còpia independent) a la representació xz.

        set(diag_presxy.hgN,'Parent',grafica_resxy,'Matrix',makehgtform('scale',[1,1/diag_presxy.Tmax,1])); % Assigna el diagrama axils a la representació xy i l'escala.
        set(diag_presxy.hgTy,'Parent',grafica_resxy,'Matrix',makehgtform('scale',[1,1/diag_presxy.Tmax,1])); % Assigna el diagrama tallants en y a la representació xy i l'escala.
        set(diag_presxy.hgMz,'Parent',grafica_resxy,'Matrix',makehgtform('scale',[1,1/diag_presxy.Mmax,1])); % Assigna el diagrama moments en z a la reprensetació xy i l'escala.
        set(diag_presxy.hgdeformada,'Parent',grafica_resxy,'Matrix',makehgtform('scale',[1,.5/diag_presxy.Dmax,1])); % Assigna una de les còpies de la deformada a la representació xy i l'escala.
        delete(findobj(diag_presxy.hgdeformada,'UserData','dz')) % Elimina les referències a la deformada en z a la representacio xy.

        set(diag_presxz.hgTz,'Parent',grafica_resxz,'Matrix',makehgtform('xrotate',pi/2,'scale',[1,1/diag_presxz.Tmax,1])); % Assigna el diagrama de tallants en z a la representació xz i l'escala.
        set(diag_presxz.hgMx,'Parent',grafica_resxz,'Matrix',makehgtform('xrotate',pi/2,'scale',[1,1/diag_presxz.Mmax,1])); % Assigna el diagrama de moments en x a la representació xz i l'escala.
        set(diag_presxz.hgMy,'Parent',grafica_resxz,'Matrix',makehgtform('xrotate',pi/2,'scale',[1,1/diag_presxz.Mmax,1])); % Assigna el diagrama moments en y a la reprensetació xz i l'escala.
        set(diag_presxz.hgdeformada,'Parent',grafica_resxz,'Matrix',makehgtform('scale',[1,1,.5/diag_presxz.Dmax])); % Assigna una de les còpies de la deformada a la representació xz i l'escala.
        delete(findobj(diag_presxz.hgdeformada,'UserData','dy')) % Elimina les referències a la deformada en y a la representacio xz.

        visibilitat_diagrames % Mostra els diagrames i la deformade si estan seleccionats.

        txtposinf=vector2txt(nusos(barres(n).nusinf).posicio); % Posició nus inferior.
        txtpossup=vector2txt(nusos(barres(n).nussup).posicio); % Posicio nus superior.
        if any(barres(n).vectorIz) % Si està definit el vector direccio Iz...
            txtinerciaIz=[num2str(barres(n).Iz),', direcció ',vector2txt(barres(n).vectorIz),' eix Z local']; % Texte vector direccio Iz..
            txtinerciaIy=num2str(barres(n).Iy); % Iz i Iy són diferents.
        else
            txtinerciaIz=num2str(barres(n).Iz); % Texte Iz.
            txtinerciaIy=['Iz= ',num2str(barres(n).Iz)]; % Si no està definit el vector Iz Iy=Iz.
        end
        if barres(n).artinf % Si l'extrem inferior és articulat.
            txtartinf='articulat';
            txtgirs1={['Girs: ',vector2txt([0,diagrames(n).Oini]),' / ',vector2txt(TL2G(:,:,n)*[0;diagrames(n).Oini'])]}; % El gir de l'extrem de barra articulat no coincideix amb el gir del nus! Gir calculat amb la deformada.
        else
            txtartinf='rigid';
            txtgirs1={['Girs: ',vector2txt(mov_extrems(4:6,n)),' / ',vector2txt(TL2G(:,:,n)*mov_extrems(4:6,n))]}; % Si l'extrem és rígid el seu gir és el gir del nus.
        end
        if barres(n).artsup % Si l'extrem superior es articulat.
            txtartsup='articulat';
            txtgirs2={['Girs: ',vector2txt([0,diagrames(n).Ofin]),' / ',vector2txt(TL2G(:,:,n)*[0;diagrames(n).Ofin'])]}; % El gir de l'extrem de barra articulat no coincideix amb el gir del nus! Gir calculat amb la deformada.
        else
            txtartsup='rigid';
            txtgirs2={['Girs: ',vector2txt(mov_extrems(10:12,n)),' / ',vector2txt(TL2G(:,:,n)*mov_extrems(10:12,n))]}; % Si l'extrem és rígid el seu gir és el gir del nus.
        end
        txttitol={['INFORME DE RESULTATS PER A LA BARRA Nº: ',txtnum,':'];''}; % Texte del títol.
        txtpropietats={['Longitud= ',num2str(long)];['Mòdul de Young E= ',num2str(barres(n).E)];['Àrea de la secció= ',num2str(barres(n).A)];['Moment d''Inèrcia Iz= ',txtinerciaIz];['Moment d''Inèrcia Iy= ',txtinerciaIy];['Rigidesa a torsió GIt= ',num2str(barres(n).GIt)]}; % Texte propietats mecàniques de la barra.
        txteixos={['x''=',vector2txt(TL2G(:,1,n)),'; y''=',vector2txt(TL2G(:,2,n)),'; z''=',vector2txt(TL2G(:,3,n))]};
        txtextrem1={['Extrem ',txtartinf,' al nus nº ',num2str(barres(n).nusinf),', posició en eixos globals: ',txtposinf]}; % Texte extrem inferior.
        txtesf1={['Forces: ',vector2txt(Retorn_esforcos_barres(n,1:3)),' / ',vector2txt(TL2G(:,:,n)*Retorn_esforcos_barres(n,1:3)')]}; % Texte esforços a l'extrem inferior.
        txtmom1={['Moments: ',vector2txt(Retorn_esforcos_barres(n,4:6)),' / ',vector2txt(TL2G(:,:,n)*Retorn_esforcos_barres(n,4:6)')]}; % Texte moments a l'extrem inferior.
        txtdesp1={['Desplaçaments: ',vector2txt(mov_extrems(1:3,n)),' / ',vector2txt(TL2G(:,:,n)*mov_extrems(1:3,n))]}; % Texte desplaçaments a l'extrem inferior.
        txtextrem2={['Extrem ',txtartsup,' al nus nº ',num2str(barres(n).nussup),', posició en eixos globals: ',txtpossup]}; % Texte extrem superior.
        txtesf2={['Forces: ',vector2txt(Retorn_esforcos_barres(n,7:9)),' / ',vector2txt(TL2G(:,:,n)*Retorn_esforcos_barres(n,7:9)')]}; % Texte esforços a l'extrem superior.
        txtmom2={['Moments: ',vector2txt(Retorn_esforcos_barres(n,10:12)),' / ',vector2txt(TL2G(:,:,n)*Retorn_esforcos_barres(n,10:12)')]}; % Texte moments a l'extrem superior.
        txtdesp2={['Desplaçaments: ',vector2txt(mov_extrems(7:9,n)),' / ',vector2txt(TL2G(:,:,n)*mov_extrems(7:9,n))]}; % Texte desplaçaments a l'extrem superior.

        txt=[txttitol;{'PROPIETATS:';''};txtpropietats;{'';'EIXOS LOCALS:';''};txteixos;{'';'ESFORÇOS I MOVIMENTS A L''EXTREM INFERIOR EN EIXOS LOCALS/GLOBALS:';''};txtextrem1;txtesf1;txtmom1;txtdesp1;txtgirs1;{'';'ESFORÇOS I MOVIMENTS A L''EXTREM SUPERIOR EN EIXOS LOCALS/GLOBALS:';''};txtextrem2;txtesf2;txtmom2;txtdesp2;txtgirs2;{'';'DIAGRAMES D''ESFORÇOS I DEFORMADA EN EIXOS LOCALS:';''};informe]; % Pega els textes.
        set(txtbox_res,'String',txt); % Mostra el texte.
    end

    function txt=vector2txt(vector)
        % Converteix un vector en texte.

        txt=['(',num2str(vector(1)),',',num2str(vector(2)),',',num2str(vector(3)),')'];
    end

    function clic_grafica_res(hObject,eventdata,handles)
        % S'executa quan es cliqueja sobre la representacio de resultats en
        % detall per una barra. Torna a mostrar els resultats per a tota
        % l'estructura.

        if grafica~=grafica_est
            grafica=grafica_est; % gràfica de treball és la gràfica de l'estrctura.
            axes(grafica_est) % gráfica de treball.
            set(grafica_est,'Visible','on') % Fa visible la gráfica de l'estructura.
            set(txtbox_res,'Visible','off') % Oculta el texte amb l'informe de resultats de la barra.
            %set(grafica_resxy,'Visible','off') % Oculta la gráfica de la barra en xy.
            %set(grafica_resxz,'Visible','off') % Oculta la gráfica de la barra en xz.
            delete(get(grafica_resxy,'Children')); % Elimina el contingut de les gràfiques de les barres.
            delete(get(grafica_resxz,'Children'));
            diag_presxy=diagrama; % Esborra les referències als diagrames mostrats en detall.
            diag_presxz=diagrama; % Esborra les referències als diagrames mostrats en detall.
            %set(get(grafica_est,'Children'),'Visible','on') % Oculta la gràfica de l'estructura.
            set(hg_barres,'Visible','on')
            set(hg_nusos,'Visible','on')
            set(hg_carreguesbarres,'Visible','on')
            set(hg_carreganusos,'Visible','on')
            set(hg_diagrames,'Visible','on')
            for i=1:contnus
                set(nusos(i).hg,'Visible','on') % Fa visibles els nusos.
            end
            for i=1:contbarra
                set(barres(i).hg,'Visible','on') % Fa visibles les barres.
            end
            diagcarregues % Fa visibles les càrregues.
            diagreaccions % Fa visibles les reaccions.
            visibilitat_diagrames % Mostra els diagrames i la deformade si estan seleccionats.
        end
    end

CREACIÓ I MODIFICACIÓ DINÀMICA DE NUSOS

Funcions relacionades amb la creació, modificacio, eliminmació, dibuix, orientació dels nusos i les seves càrregues.

    function crearnus
        % Crea i dibuixa un nou nus.

        %disp('Crear nus')
        %tic_cn=tic;
        posicio=[str2double(get(editx,'String')),str2double(get(edity,'String')),str2double(get(editz,'String'))]; % Obtè les coordenades de la posició de les caixes de texte, ja arrodonides a la precisió.

        contnus=contnus+1; % Incrementa el comptador de nusos en un.
        nusos(contnus)=nus; % Nou objecte nus.
        nusos(contnus).num=contnus; % Una de les dades que conte l'estructura de la classe nus es el seu número.
        nusos(contnus).posicio=posicio; % posició del nus.
        calcul_cord_extrems % Recalcula màxims, mínims de les coordenades dels nusos per tal de que els nous nusos s'orientin corrèctament.
        if editalcrear==0
            modificarnus(contnus) % Si està seleccionada l'opció, edita el nus després de crear-lo.
        end
        if barraalcrearnus && contnus > 1 % Si està seleccionada l'opció crea una barra al crear el nus connectada al nus anterior.
            novabarra(contnus-1,contnus,artnusant,strcmp(get(botobarrarotula,'State'),'on')) % Crea una barra des del nus anterior al nus creat.
        end
        artnusant=strcmp(get(botobarrarotula,'State'),'on'); % Apunta l'estat del botó ròtula al crear l'últim nus.
        redibuixar_nusos % Dibuixa i gira els nusos segons les barres connectades o la seva posició relativa.
        escala % Calcula el factor d'escala s.
        escalar_nusos % Reescala els nusos i les seves carregues.
        %disp(['/Crear nus: ',num2str(toc(tic_cn))])
    end
 function crearnus2(posicio)
        % Crea i dibuixa un nou nus.

        %disp('Crear nus')
        %tic_cn=tic;

        contnus=contnus+1; % Incrementa el comptador de nusos en un.
        nusos(contnus)=nus; % Nou objecte nus.
        nusos(contnus).num=contnus; % Una de les dades que conte l'estructura de la classe nus es el seu número.
        nusos(contnus).posicio=posicio; % posició del nus.
        calcul_cord_extrems % Recalcula màxims, mínims de les coordenades dels nusos per tal de que els nous nusos s'orientin corrèctament.

        %artnusant=strcmp(get(botobarrarotula,'State'),'on'); % Apunta l'estat del botó ròtula al crear l'últim nus.
        redibuixar_nusos % Dibuixa i gira els nusos segons les barres connectades o la seva posició relativa.
        escala % Calcula el factor d'escala s.
        %escalar_nusos % Reescala els nusos i les seves carregues.
        %disp(['/Crear nus: ',num2str(toc(tic_cn))])
    end
    function esborrarnus(n)
        % Elimina un nus i la seva representació gràfica.
        % Elimina les barres connectades al nus i actualitza la numeració.

        %disp(['Esborrar nus ',num2str(n)])
        %tic_en=tic;

        esborrarcarreganus(n) % elimina la carrega al nus
        if contbarra>0 % Si hi han barres definides...
            for i=contbarra:-1:1 % Compte endarrera (endarrera per tal de que l'acció d'esborrar barres modifica la llista barres).
                if barres(i).nusinf==n || barres(i).nussup==n % Si algun dels extrems estava connectat al nus que s'ha eliminat...
                    esborrarbarra(i) % elimina també la barra
                end
            end
        end
        delete(nusos(n).hg) % Destruieix l'objecte gràfic que representa el nus.
        nusos2=nus; % Crea una nova llista de nusos.
        if n>1
            nusos2(1:n-1)=nusos(1:n-1); % Copia els nusos anterios a la nova llista.
        end
        if n<contnus
            nusos2(n:contnus-1)=nusos(n+1:contnus); % Copia els nusos posteriors a la nova llista.
            for i=n:contnus-1
                nusos2(i).num=i; % Actualitza número de nusos dels nusos posteriors a l'eliminat.
                set(nusos2(i).hg,'UserData',i); % Actualitza camp 'UserData' amb el nou número de nus.
                set(findobj(nusos2(i).hg,'Type','text'),'String',num2str(i)); % Actualitza el text.
            end
        end
        nusos=nusos2; % Substiitueix la llista antiga de nusos per la nova.
        contnus=contnus-1; % Actualitza el comptador de nusos.

        if contbarra>0 % Si hi han  definides...
            for i=1:contbarra
                if barres(i).nusinf>n % Si el nus inferior té número superior a l'elimitat...
                    barres(i).nusinf=barres(i).nusinf-1; % Actualitza el número.
                end
                if barres(i).nussup>n % Si el nus superior té número superior a l'eliminat...
                    barres(i).nussup=barres(i).nussup-1;  % Actualitza el número.
                end
            end
        end

        calcul_cord_extrems % Recalcula màxims, mínims de les coordenades dels nusos per tal de que els nous nusos s'orientin corrèctament.
        escala % Calcula el factor d'escala s.
        redibuixar_nusos % Reorienta, gira, els nusos segons les barres connectades o la seva posició relativa.
        escalar_nusos % Adequa l'escala.
        clicable % Activa o desactiva la pulsaio dels elements grafics segons els botons de la barra.

        %disp(['/Esborrar nus ',num2str(n),': ',num2str(toc(tic_en))])
    end

    function modificarnus(n)
        % Modifica un nus.

        %disp(['Modificar nus ',num2str(n)])
        %tic_mn=tic;
        nusos(n)=dlgnus(nusos(n)); % Obre la finestra d'edició del nus.
        calcul_cord_extrems% Recalcula màxims, mínims de les coordenades dels nusos per si s'han modificat les coordenades.
        escala % Calcula el factor d'escala s.
        redibuixar_nusos % Reorienta, gira, els nusos segons les barres connectades o la seva posició relativa.
        redibuixar_barres % Redibuixa les barres, per si el nus te barres connectades i s'ha modificat la posició.
        redibuixar_carregues_barres % Redibuixa les carregues sobre les barres.
        escalar_nusos % Adequa l'escala.
        clicable % Activa o desactiva la pulsaio dels elements grafics segons els botons de la barra.
        %disp(['/Modificar nus ',num2str(n),': ',num2str(toc(tic_mn))])
    end

    function redibuixar_nus(n)
        % Dibuixa el nus, elimina el dibuix anterior.
        % Gira el dibuix en funcio de les barres connectades o la posició
        % relativa.

        %disp(['Redibuixar nus ',num2str(n)])
        %tic_rn=tic;
        con=[]; % Llistat amb els angles de les barres connectades al nus.
        for i=1:contbarra
            if barres(i).nusinf==n % Si el nus està connectat a l'extrem inferior d'una barra...
                vec=nusos(barres(i).nussup).posicio-nusos(n).posicio; % Vector direcció de la barra.
                con(length(con)+1)=atan2(vec(2),vec(1)); % Llistat amb els angles de les barres connectades al nus.
            elseif barres(i).nussup==n % Si el nus està connectat a l'extrem superior d'una barra...
                vec=nusos(barres(i).nusinf).posicio-nusos(n).posicio; % Vector direcció de la barra.
                con(length(con)+1)=atan2(vec(2),vec(1)); % Llistat amb els angles de les barres connectades al nus.
            end
        end

        switch nusos(n).contorn % Discrimina segons el tipus de condicio de contorn.
            case 0 % Nus lliure
                ang=0; % No es gira.
            case 1 % Rodet
                ang=atan2(nusos(n).rodet(2),nusos(n).rodet(1))-pi/2; % Es gira segons el seu pla definit.
            case {2,4} % Recolzaments
                % Per defecte no es gira. Si té una barra que travesa el recolzament el gira per evitar l'efecte anti-estè%tic.
                if isempty(con) % Si no hi han barres connectades...
                    ang=0; % No es gira.
                else
                    alfa=ones(1,numel(con))*5*pi/6;
                    con2=con+alfa;
                    if all(con2 > 2*pi/3 | con2 < 0) % Si no hi ha una barra sota el recolzament...
                        ang=0; % No es gira.
                    else
                        beta=ones(1,numel(con))*pi/2;
                        con2=con2-beta;
                        con2=con2+2*pi*(con2 < -pi);
                        if all(con2 > 2*pi/3 | con2 < 0) % Si no hi ha una barra a la dreta del recolzament...
                            ang=pi/2; % Es gira 90º.
                        else
                            con2=con2+pi;
                            con2=con2-2*pi*(con2 > pi);
                            if all(con2 > 2*pi/3 | con2 < 0) % Si no hi ha una barra a l'esquerra del recolzament...
                                ang=3*pi/2; % Es gira 270º.
                            else
                                con2=con2+beta;
                                con2=con2-2*pi*(con2 > pi);
                                if all(con2 > 2*pi/3 | con2 < 0) % Si no hi ha una barra per sobre del recolzament...
                                    ang=pi; % Es gira 180º.
                                else
                                    ang=0; % Si hi ha barres que interfereixen en totes direccions, no es gira.
                                end
                            end
                        end
                    end
                end
            case 3 % Encastaments
                if numel(con)==1 % Si nomes està connectat a una barra...
                    ang=con-pi/2; % Segueix la direcció de la barra.
                else % Si esta connectat a mes d'una barra...
                    ang=atan2(sum(sin(con)),sum(cos(con)))-pi/2; % Gira l'angle mig.
                    ang=round(ang*12/pi)*pi/12; % Arrodoneix l'angle.
                end
            case {5,6} % Girs elàs%tics amb desplaçaments nuls, girs elàs%tics amb desplaçaments elàs%tics
                if isempty(con) % si no hi han barres connectades...
                    ang=0; % No es gira.
                else % Si hi han connectades una barra o mes...
                    ang=con(1)-pi/2; % Segueix la direcció de la primera.
                end
            case 8 % Girs imposats i desplaçaments lliures.
                if isempty(con) % Si no hi han barres connectades...
                    ang=0; % No es gira.
                else % % Si hi han connectades una barra o mes...
                    ang=con(1); % Segueix la direcció de la primera.
                end
            otherwise
                ang=0; % En qualsevol altre cas no es gira.
        end

        nusos(n).gir=ang; % Apunta l'angle de gir.
        hg=dibuix_contorn(nusos(n).contorn,distnumnus,fontnusos,tamanyfontnusos); % Dibuixa el nus.
        set(hg,'ButtonDownFcn',@clic_nus,'UserData',n,'Parent',hg_nusos); % Assigna la funció que s'executarà quan es cliqueji.
        ht=findobj(hg,'Type','text'); % Objecte que conté el texte de numeracio del nus dins de l'objecte gràfic que representa el nus.
        pos=get(ht,'Position'); % N'obté la posició.
        angt=atan2(nusos(n).posicio(2)-ym,nusos(n).posicio(1)-xm); % Angle de situació del texte al voltant del nus, segons la posició relativa del nus.
        angt=round((angt-pi/4)*2/pi)*pi/2+pi/4; % Arrodoneix l'angle.
        angt=angt-ang; % Resta l'angle de gir del nus per tal de que al girar-lo el texte vagi a la seva posició calculada.
        pos(1:2)=[cos(angt),sin(angt)]*distnumnus; % Calcula en coordenades la posicio del texte.
        set(ht,'String',num2str(n),'Position',pos,'HorizontalAlignment','center','VerticalAlignment','middle'); % Assigna la posició al texte.
        if strcmp(vista,'3d')
            set(get(hg,'Children'),'Clippin','off') % Permet que en 3d sobresurti de la gràfica.
        else
            set(get(hg,'Children'),'Clippin','on') % NO permet que en 3d sobresurti de la gràfica.
        end
        delete(nusos(n).hg) % Esborra el dibuix an%tic.
        nusos(n).hg=hg; % Guarda el handle del nou objecte grafic a la llista de nusos.
        %disp(['/Redibuixar nus ',num2str(n),': ',num2str(toc(tic_rn))])
    end
function redibuixar_nus2(n)
        % Dibuixa el nus, elimina el dibuix anterior.
        % Gira el dibuix en funcio de les barres connectades o la posició
        % relativa.

        %disp(['Redibuixar nus ',num2str(n)])
        %tic_rn=tic;
        con=[]; % Llistat amb els angles de les barres connectades al nus.
        for i=1:contbarra
            if barres(i).nusinf==n % Si el nus està connectat a l'extrem inferior d'una barra...
                vec=nusos(barres(i).nussup).posicio-nusos(n).posicio; % Vector direcció de la barra.
                con(length(con)+1)=atan2(vec(2),vec(1)); % Llistat amb els angles de les barres connectades al nus.
            elseif barres(i).nussup==n % Si el nus està connectat a l'extrem superior d'una barra...
                vec=nusos(barres(i).nusinf).posicio-nusos(n).posicio; % Vector direcció de la barra.
                con(length(con)+1)=atan2(vec(2),vec(1)); % Llistat amb els angles de les barres connectades al nus.
            end
        end

        switch nusos(n).contorn % Discrimina segons el tipus de condicio de contorn.
            case 0 % Nus lliure
                ang=0; % No es gira.
            case 1 % Rodet
                ang=atan2(nusos(n).rodet(2),nusos(n).rodet(1))-pi/2; % Es gira segons el seu pla definit.
            case {2,4} % Recolzaments
                % Per defecte no es gira. Si té una barra que travesa el recolzament el gira per evitar l'efecte anti-estè%tic.
                if isempty(con) % Si no hi han barres connectades...
                    ang=0; % No es gira.
                else
                    alfa=ones(1,numel(con))*5*pi/6;
                    con2=con+alfa;
                    if all(con2 > 2*pi/3 | con2 < 0) % Si no hi ha una barra sota el recolzament...
                        ang=0; % No es gira.
                    else
                        beta=ones(1,numel(con))*pi/2;
                        con2=con2-beta;
                        con2=con2+2*pi*(con2 < -pi);
                        if all(con2 > 2*pi/3 | con2 < 0) % Si no hi ha una barra a la dreta del recolzament...
                            ang=pi/2; % Es gira 90º.
                        else
                            con2=con2+pi;
                            con2=con2-2*pi*(con2 > pi);
                            if all(con2 > 2*pi/3 | con2 < 0) % Si no hi ha una barra a l'esquerra del recolzament...
                                ang=3*pi/2; % Es gira 270º.
                            else
                                con2=con2+beta;
                                con2=con2-2*pi*(con2 > pi);
                                if all(con2 > 2*pi/3 | con2 < 0) % Si no hi ha una barra per sobre del recolzament...
                                    ang=pi; % Es gira 180º.
                                else
                                    ang=0; % Si hi ha barres que interfereixen en totes direccions, no es gira.
                                end
                            end
                        end
                    end
                end
            case 3 % Encastaments
                if numel(con)==1 % Si nomes està connectat a una barra...
                    ang=con-pi/2; % Segueix la direcció de la barra.
                else % Si esta connectat a mes d'una barra...
                    ang=atan2(sum(sin(con)),sum(cos(con)))-pi/2; % Gira l'angle mig.
                    ang=round(ang*12/pi)*pi/12; % Arrodoneix l'angle.
                end
            case {5,6} % Girs elàs%tics amb desplaçaments nuls, girs elàs%tics amb desplaçaments elàs%tics
                if isempty(con) % si no hi han barres connectades...
                    ang=0; % No es gira.
                else % Si hi han connectades una barra o mes...
                    ang=con(1)-pi/2; % Segueix la direcció de la primera.
                end
            case 8 % Girs imposats i desplaçaments lliures.
                if isempty(con) % Si no hi han barres connectades...
                    ang=0; % No es gira.
                else % % Si hi han connectades una barra o mes...
                    ang=con(1); % Segueix la direcció de la primera.
                end
            otherwise
                ang=0; % En qualsevol altre cas no es gira.
        end

        nusos(n).gir=ang; % Apunta l'angle de gir.
        hg=dibuix_contorn(nusos(n).contorn,distnumnus,fontnusos,tamanyfontnusos); % Dibuixa el nus.
        set(hg,'ButtonDownFcn',@clic_nus,'UserData',n,'Parent',hg_nusos); % Assigna la funció que s'executarà quan es cliqueji.
        ht=findobj(hg,'Type','text'); % Objecte que conté el texte de numeracio del nus dins de l'objecte gràfic que representa el nus.
        pos=get(ht,'Position'); % N'obté la posició.
        angt=atan2(nusos(n).posicio(2)-ym,nusos(n).posicio(1)-xm); % Angle de situació del texte al voltant del nus, segons la posició relativa del nus.
        angt=round((angt-pi/4)*2/pi)*pi/2+pi/4; % Arrodoneix l'angle.
        angt=angt-ang; % Resta l'angle de gir del nus per tal de que al girar-lo el texte vagi a la seva posició calculada.
        pos(1:2)=[cos(angt),sin(angt)]*distnumnus; % Calcula en coordenades la posicio del texte.
        set(ht,'String',num2str(n),'Position',pos,'HorizontalAlignment','center','VerticalAlignment','middle'); % Assigna la posició al texte.
        if strcmp(vista,'3d')
            set(get(hg,'Children'),'Clippin','off') % Permet que en 3d sobresurti de la gràfica.
        else
            set(get(hg,'Children'),'Clippin','on') % NO permet que en 3d sobresurti de la gràfica.
        end
        %delete(nusos(n).hg) % Esborra el dibuix an%tic.
        nusos(n).hg=hg; % Guarda el handle del nou objecte grafic a la llista de nusos.
        %disp(['/Redibuixar nus ',num2str(n),': ',num2str(toc(tic_rn))])
end

    function redibuixar_nusos2 %Aquesta funcio redibuixa els putns, i dibuixa els punts segons el codi de color que sels ha asignat( es fa servir per diferenciar les ròtules plàstiques)
        % Redibuixa tots els nusos.
        %disp('Redibuixar nusos')
        %tic_rn=tic;
        for i=1:contnus
            redibuixar_nus(i) % Redibuixa cada nus.

              if nusos(i).color(2) ==1
                chgcolor(nusos(contnus).hg,[0 1 0])
              end
        end
        %disp(['/Redibuixar nusos: ',num2str(toc(tic_rn))])
    end
    function redibuixar_nusos
        % Redibuixa tots els nusos.
        %disp('Redibuixar nusos')
        %tic_rn=tic;
        for i=1:contnus
            redibuixar_nus(i) % Redibuixa cada nus.
        end
        colornusos % Coloreja ls nusos.
        %disp(['/Redibuixar nusos: ',num2str(toc(tic_rn))])
    end

    function escala
        % Relaciona el tamany de la representació dels objectes gràfics amb
        % el tamany de la gràfica, per tal de que sigui constant encara que
        % s'amplii i redueixi. Els objectes gràfics sempre es mostraran del
        % mateix tamany.

        % Pren com a referència l'eix horitzotal.
        %disp('Escala')
        %tic_s=tic;
        switch vista
            case 'yz'
                xl=get(grafica_est,'YLim'); % Al plànol yz l'eix horitzontal és l'eix y.
            case '3d'
                xl=get(grafica_est,'XLim')*3; % En 3D els eixos són iguals, s'aplica un factor de multiplicació per compensar que la proporcionalitat amb el tamany de la pantalla canvia.
            otherwise
                xl=get(grafica_est,'XLim'); % A la resta de vistes es pren l'eix x.
        end

        tam=get(grafica_est,'Position'); % tam(3) és el tamany horitzontal de la grafica, en píxels.
        s=(xl(2)-xl(1))*tamanynus/tam(3); % Calcul del factor escala s.
        %disp(['/Escala: ',num2str(toc(tic_s))])
    end

    function escalar_nusos
        % Ecala el nusos i les seves carregues i reaccions segons la varable d'escala s calculada.

        %disp('Escalar_nusos')
        %tic_en=tic;
        for i=1:contnus % Per a tots els nusos.
            t=makehgtform('translate',nusos(i).posicio,'zrotate',nusos(i).gir,'scale',s); % Matriu de gir, desplaçament i escala.
            set(nusos(i).hg,'Matrix',t); % Assigna a l'objecte que representa el nus la matriu de gir, desplaçament i escala.
            if any(nusos(i).puntual) || any(nusos(i).moment) % Si hi han forces aplicades al nus....
                t=makehgtform('translate',nusos(i).posicio,'scale',s); % Martiu de desplaçament i escala.
                set(nusos(i).hgc,'Matrix',t); % Assigna a l'objecte que representa les forces la matriu de desplaçament i escala.
            end
            if numel(hgreaccions) % Si hi han reaccions...
                if hgreaccions(i)
                    t=makehgtform('translate',nusos(i).posicio,'scale',s); % Martiu de desplaçament i escala.
                    set(hgreaccions(i),'Matrix',t); % Assigna a l'objecte que representa les reaccions la matriu de desplaçament i escala.
                end
            end
        end

        %disp(['/Escalar nusos: ',num2str(toc(tic_en))])
    end

    function crearmodificarcarreganus(n)
        % Crea o modifica la carrega d'un nus.

        %disp(['Crea o modifica carrega en nus ',num2str(n)])
        %tic_cn=tic;
        nusos(n)=dlgcarreganus(nusos(n)); % Obre la finestra d'edició de les càrregues dels nusos.
        maxpuntual % Recalcula la càrrega maxima.
        redibuixa_carreganus(n); % Dibuixa de nou la càrrega.
        escalar_nusos % Escala la carrega i la resta d'objectes gràfics.
        colorcarreganusos
        %disp(['/Crea o modifica carrega en nus ',num2str(n),': ',num2str(toc(tic_cn))])
    end

    function redibuixa_carreganus(n)
        % Crea els objectes gràfics que representen les carregues als
        % nusos.

        %disp(['Redibuixa carrega nus ',num2str(n)])
        %tic_rc=tic;
        delete(nusos(n).hgc); % Elimina l'objecte grafic que representa la càrrega.
        nusos(n).hgc=dibuix_carreganus(n,nusos(n).posicio,[xm,ym,zm],nusos(n).puntual,nusos(n).moment,vista,fontcarregues,tamanyfontcarregues,fmax); % Crea l'objecte gràfic.
        set(nusos(n).hgc,'ButtonDownFcn',@clic_carreganus,'UserData',n,'Parent',hg_carreganusos); % Assigna a l'objecte la funció que s'executara quan el cliqueji sobre la càrrega i el número de nus per identificar-lo.
        if strcmp(vista,'3d')
            set(get(nusos(n).hgc,'Children'),'Clippin','off') % Permet que en 3d sobresurti de la gràfica.
        else
            set(get(nusos(n).hgc,'Children'),'Clippin','on') % NO permet que en 3d sobresurti de la gràfica.
        end
        %clicable % Estableix els colors i quins objectes gràfics responen als clics segons l'estat dels botons de la barra d'eines.
        %disp(['/Redibuixa carrega nus ',num2str(n),': ',num2str(toc(tic_rc))])
    end
  function redibuixa_carreganus2(n)
        % Crea els objectes gràfics que representen les carregues als
        % nusos.

        %disp(['Redibuixa carrega nus ',num2str(n)])
        %tic_rc=tic;
        %delete(nusos(n).hgc); % Elimina l'objecte grafic que representa la càrrega.
        nusos(n).hgc=dibuix_carreganus(n,nusos(n).posicio,[xm,ym,zm],nusos(n).puntual,nusos(n).moment,vista,fontcarregues,tamanyfontcarregues,fmax); % Crea l'objecte gràfic.
        set(nusos(n).hgc,'ButtonDownFcn',@clic_carreganus,'UserData',n,'Parent',hg_carreganusos); % Assigna a l'objecte la funció que s'executara quan el cliqueji sobre la càrrega i el número de nus per identificar-lo.
        if strcmp(vista,'3d')
            set(get(nusos(n).hgc,'Children'),'Clippin','off') % Permet que en 3d sobresurti de la gràfica.
        else
            set(get(nusos(n).hgc,'Children'),'Clippin','on') % NO permet que en 3d sobresurti de la gràfica.
        end
        %clicable % Estableix els colors i quins objectes gràfics responen als clics segons l'estat dels botons de la barra d'eines.
        %disp(['/Redibuixa carrega nus ',num2str(n),': ',num2str(toc(tic_rc))])
    end
    function redibuixa_carreganusos
        % Redibuixa totes les càrregues als nusos.

        %disp('Redibuixa carrega nusos')
        %tic_rc=tic;
        for i=1:contnus
            redibuixa_carreganus(i) % Redibuixa les càrregues.
        end
        colorcarreganusos
        escalar_nusos
        %disp(['Redibuixar carrega nusos: ',num2str(toc(tic_rc))])
    end

    function esborrarcarreganus(n)
        % Esborra la carrega d'un nus.

        %disp(['Esborrar carrega nus ',num2str(n)])
        %tic_ec=tic;
        %delete(nusos(n).hgc); % Elimina l'objecte grafic que representa la càrrega.
        %nusos(n).hgc=[]; % Elimina la referència a l'objecte eliminat.
        nusos(n).puntual=[0,0,0]; % Restableix a zeros els valors de la càrrega.
        nusos(n).moment=[0,0,0]; % Restaleix a zero els valors del moment.
        maxpuntual % Recalcula la càrrega maxima.
        redibuixa_carreganusos
        %disp(['/Esborrar carrega nus ',num2str(n),': ',num2str(toc(tic_ec))])
    end

CREACIÓ I MODIFICACIÓ DINÀMICA DE BARRES

Funcions relacionades amb la creació, modificacio, eliminmació, dibuix, de les barres i les seves càrregues.

    function crearbarra(n)
        % Crea una barra a l'estructura.
        % Si es clica sobre el primer nus crea una línia que segueix el
        % cursor fins clicar el segon nus, o es canceli amb la tecla
        % 'escape'.

        %disp('Crear barra')
        %tic_cb=tic;
        if flagbarra && primernusbarra == n  %Evita que es pugui crear una barra amb el mateix nus inferior i superior

        elseif flagbarra % Si ja s'ha iniciat el proces de crear la barra, s'ha clicat sobre el segon nus.
            novabarra(primernusbarra,n,artprimernusbarra,strcmp(get(botobarrarotula,'State'),'on')) % Crea la barra.
            flagbarra=0; % Reestableix a zero el flag.
            delete(hbarra); % Elimina la barra que segueix el cursor.
            hbarra=[];
        else % Si s'ha clicat sobre el primer nus.
            primernusbarra=n; % Apunta el número de nus.
            artprimernusbarra=strcmp(get(botobarrarotula,'State'),'on'); % Apunta si està seleccionat el botó articulació.
            posicio=[str2double(get(editx,'String')),str2double(get(edity,'String')),str2double(get(editz,'String'))]; % Obté la posició del punter del ratoli.
            hbarra=line([nusos(n).posicio(1) posicio(1)],[nusos(n).posicio(2) posicio(2)],[nusos(n).posicio(3) posicio(3)],'color','k','LineWidth',2,'Clipping','off','HitTest','off','Parent',hg_barres); % Crea una linia des del nus clicat fins a la posició del ratolí.
            flagbarra=1; % Activa el flag per tal de que al clicar sobre un altre nus es completi el procés de creació de la barra.
        end
        %disp(['/Crear barra: ',num2str(toc(tic_cb))])
    end

    function novabarra(nusinf,nussup,artinf,artsup)
        % Crea una barra des del nus inferior al superior.

        %disp(['Nova barra ',num2str(nusinf),'-',num2str(nussup)])
        %tic_nb=tic;
        contbarra=contbarra+1; % Incrementa el comptador de barres.
        barres(contbarra)=barra; % Nou objecte barra a la llista de barres.
        barres(contbarra).nusinf=nusinf; % Nus inferior.
        barres(contbarra).nussup=nussup; % Nus superior.
        barres(contbarra).artinf=artinf; % articulació a l'extrem inferior.
        barres(contbarra).artsup=artsup; % articulació a l'extrem superior.
        barres(contbarra).num=contbarra; % Assigna número de barra a la barra.
        if editalcrear==0 % Si està seleccionada l'opció edita la barra després de crear-la.
            modificarbarra(contbarra) % Edita i dibuixa la barra.
        else
            redibuixar_barra(contbarra) % Dibuixa la barra.
            colorbarres
            clicable % Estableix quins objectes gràfics responen als clics segons l'estat dels botons de la barra d'eines.
        end
        %disp(['/Nova barra ',num2str(nusinf),'-',num2str(nussup),': ',num2str(toc(tic_nb))])
    end

    function redibuixar_barra(n)
        % Elimina el dibuix existent i el redibuixa.

        %disp(['Redibuixar barra ',num2str(n)])
        %tic_rb=tic;
        delete(barres(n).hg); % Esborra l'objecte gràfic.
        posinf=nusos(barres(n).nusinf).posicio; % Posició nus inferior.
        possup=nusos(barres(n).nussup).posicio; % Posicio nus superior.
        barres(n).hg=line([posinf(1) possup(1)],[posinf(2) possup(2)],[posinf(3) possup(3)],'LineWidth',2,'UserData',n,'ButtonDownFcn',@clic_barra,'Parent',hg_barres); % Crea la línia.
        if strcmp(vista,'3d')
            set(barres(n).hg,'Clippin','off') % Permet que en 3d sobresurti de la gràfica.
        else
            set(barres(n).hg,'Clippin','on') % NO permet que en 3d sobresurti de la gràfica.
        end
        %disp(['/Redibuixar barra ',num2str(n),': ',num2str(toc(tic_rb))])
    end
    function redibuixar_barra2(n)
        % Elimina el dibuix existent i el redibuixa.

        %disp(['Redibuixar barra ',num2str(n)])
        %tic_rb=tic;

        posinf=nusos(barres(n).nusinf).posicio; % Posició nus inferior.
        possup=nusos(barres(n).nussup).posicio; % Posicio nus superior.
        barres(n).hg=line([posinf(1) possup(1)],[posinf(2) possup(2)],[posinf(3) possup(3)],'LineWidth',2,'UserData',n,'ButtonDownFcn',@clic_barra,'Parent',hg_barres); % Crea la línia.
        if strcmp(vista,'3d')
            set(barres(n).hg,'Clippin','off') % Permet que en 3d sobresurti de la gràfica.
        else
            set(barres(n).hg,'Clippin','on') % NO permet que en 3d sobresurti de la gràfica.
        end
        %disp(['/Redibuixar barra ',num2str(n),': ',num2str(toc(tic_rb))])
    end
    function redibuixar_barres
        % Elimina els objectes grafics que representen les barres i les
        % dibuixa de nou.
        %disp('Redibuixar barres')
        %tic_rb=tic;
        for i=1:contbarra % Per a totes les barres.
            redibuixar_barra(i);
        end
        %clicable % Estableix els colors i quins objectes gràfics responen als clics segons l'estat dels botons de la barra d'eines.
        %disp(['/Redibuixar barres: ',num2str(toc(tic_rb))])
        colorbarres
    end

    function esborrarbarra(n)
        % Esborra la barra indicada.
        % Elimina de la llista i elimina els objectes gràfics que
        % representen la barra i les seves càrregues.

        %disp(['Esborrar barra ',num2str(n)])
        %tic_eb=tic;
        nusinf=barres(n).nusinf; % Nus inferior.
        nussup=barres(n).nussup; % Nus superior.
        esborrarcarregabarra(n); % Esborra la carrega.
        delete(barres(n).hg) % Elimina l'objecte gràfic que representa la barra.
        barres2=barra; % Crea una nova llista de barres.
        if n>1
            barres2(1:n-1)=barres(1:n-1); % Copia les barres amb número inferior a la nova llista.
        end
        if n<contbarra
            barres2(n:contbarra-1)=barres(n+1:contbarra); % Copia les barres amb número superior a la nova llista.
            for i=n:contbarra-1
                barres2(i).num=i; % Actualitza els números de barra.
                set(barres2(i).hg,'UserData',i); % Actualitza els números de barra al camp 'UserData' dels objectes grafics.
            end
        end
        barres=barres2; % Elimina la llista de barres antiga i la substitueix per la nova.
        contbarra=contbarra-1; % Actualitza el comptador de barres.
        redibuixar_nus(nusinf) % Actualitza el nus inferior, la seva orientació por dependre de la barra.
        redibuixar_nus(nussup) % Actualitza el nus superior, la seva orientació por dependre de la barra.
        %clicable % Estableix els colors i quins objectes gràfics responen als clics segons l'estat dels botons de la barra d'eines.
        %disp(['/Esborrar barra ',num2str(n),': ',num2str(toc(tic_eb))])
    end



    function modificarbarra(n)
        % Edita la barra.

        barres=dlgbarra(contnus,barres,n); % Diàleg de modifiació de les barres.
        %disp(['Modificar barra ',num2str(n)])
        %tic_mb=tic;
        redibuixar_nus(barres(n).nusinf) % Redibuixa el nus inferior, modificacions de la barra poden afectar la seva orientacio.
        redibuixar_nus(barres(n).nussup) % Redibuixa el nus superior, modificacions de la barra poden afectar la seva orientacio.
        escalar_nusos
        redibuixar_barra(n) % Redibuixa la barra.
        colorbarres % Coloreja els elements gràfics segons els botons de la barra.
        clicable % Activa o desactiva la pulsaio dels elements grafics segons els botons de la barra.
        %disp(['/Modificar barra ',num2str(n),': ',num2str(toc(tic_mb))])
    end

    function crearmodificarcarregabarra(n)
        % Crea i modifica càrregues a les barres.

        barres(n)=dlgcarregabarra(barres(n)); % Crida al diàleg d'edició de les càrregues sobre la barra.
        %disp(['Crear o modificar carregues en barra ',num2str(n)])
        %tic_cc=tic;
        maxpuntual % Calcula carrega puntual maxima.
        maxrepartida % Calcula carrega repartida o projectada maxima.
        redibuixar_carregues_barra(n) % Dibuixa les càrregues.
        colorcarregabarres
        clicable % Estableix els colors i quins objectes gràfics responen als clics segons l'estat dels botons de la barra d'eines.
        %disp(['/Crear o modificar carregues en barra ',num2str(n),': ',num2str(toc(tic_cc))])
    end

    function redibuixar_carregues_barra(n)
        % Dibuixa les càrregues a les barres.
        % Si existeixen objectes gràfics els elimina i els crea de nou.

        %disp(['Redibuixar carregues en barra ',num2str(n)])
        %tic_rc=tic;
        delete(barres(n).hgpuntual) % Elimina objecte gràfic força puntual.
        barres(n).hgpuntual=[];
        delete(barres(n).hgmoment) % Elimina objecte gràfic moment.
        barres(n).hgmoment=[];
        delete(barres(n).hgrepartida) % Elimina objecte gràfic càrrega repartida.
        barres(n).hgrepartida=[];
        delete(barres(n).hgprojectada) % Elimina objecte gràfic càrrega projectada.
        barres(n).hgprojectada=[];
        cordinf=nusos(barres(n).nusinf).posicio; % Coordenades nus inferior.
        cordsup=nusos(barres(n).nussup).posicio; % Coordenades nus superior.
        vectorbarra=cordsup-cordinf; % Vector direcció de la barra.
        vectorbarra=vectorbarra/norm(vectorbarra); % Vector direcció de la barra normalitzat.

        if barres(n).puntual(1) || barres(n).moment(1) % Si s'han introduït càrregues puntuals o moments...
            [barres(n).hgpuntual,barres(n).hgmoment]=dibuix_carregabarra(barres(n),nusos(barres(n).nussup).posicio-nusos(barres(n).nusinf).posicio,vista,fontcarregues,tamanyfontcarregues,fmax); % Dibuixa carrega puntual i moment.
            if barres(n).puntual(1) % Si s'ha introduït càrrega puntual...
                pos=barres(n).puntual(5)*vectorbarra+cordinf; % Posició en eixos globals de la càrrega puntual.
                m=makehgtform('translate',pos,'scale',s); % Matriu de col·locació i escala de la càrrega puntual.
                set(barres(n).hgpuntual,'ButtonDownFcn',@clic_carregabarra,'Matrix',m,'Parent',hg_carreguesbarres); % Aplica la matriu a l'objecte gràfic que representa la càrrega puntual.
            end
            if barres(n).moment(1) % Si s'ha introduït moment...
                pos=barres(n).moment(5)*vectorbarra+cordinf; % Posició en eixos globals del moment.
                m=makehgtform('translate',pos,'scale',s); % Matriu de col·locació i escala del moment.
                set(barres(n).hgmoment,'ButtonDownFcn',@clic_carregabarra,'Matrix',m,'Parent',hg_carreguesbarres); % Aplica la matriu a l'objecte gràfic que representa el moment.
            end
        end

        if barres(n).repartida(1) && any(cordsup-cordinf) % Si s'ha introduït càrrega repartida...
            puntinf=cordinf+vectorbarra*barres(n).repartida(5); % Punt inferior d'aplicació de la càrrega en eixos globals.
            puntsup=cordsup-vectorbarra*barres(n).repartida(6); % Punt superior d'aplicació de la càrrega en eixos globals.
            barres(n).hgrepartida=dibuix_repartida(n,puntinf,puntsup,barres(n).repartida,s,fontcarregues,tamanyfontcarregues,qmax); % Dibuixa la càrrega repartida.
            set(barres(n).hgrepartida,'ButtonDownFcn',@clic_carregabarra,'Parent',hg_carreguesbarres); % Assigna la funció que s'executarà quan es cliqueji sobre la càrrega.
            if strcmp(vista,'3d')
                set(get(barres(n).hgrepartida,'Children'),'Clipping','off') % Fa que els objectes gràfics sobresurtin de la grafica en vista 3d.
            else
                set(get(barres(n).hgrepartida,'Children'),'Clipping','on') % Fa que els objectes gràfics NO sobresurtin de la grafica en vista 3d.
            end
        end

        if barres(n).projectada(1) && any(cordsup-cordinf) % Si s'ha introduït càrrega projectada...
            puntinf=cordinf+vectorbarra*barres(n).projectada(5); % Punt inferior d'aplicació de la càrrega en eixos globals.
            puntsup=cordsup-vectorbarra*barres(n).projectada(6); % Punt superior d'aplicació de la càrrega en eixos globals.
            barres(n).hgprojectada=dibuix_projectada(n,puntinf,puntsup,barres(n).projectada,s,fontcarregues,tamanyfontcarregues,qmax); % Dibuixa la càrrega projectada.
            set(barres(n).hgprojectada,'ButtonDownFcn',@clic_carregabarra,'Parent',hg_carreguesbarres); % Assigna la funció que s'executarà quan es cliqueji sobre la càrrega.
            if strcmp(vista,'3d')
                set(get(barres(n).hgprojectada,'Children'),'Clipping','off') % Fa que els objectes gràfics sobresurtin de la grafica en vista 3d.
            end
        end
        %disp(['/Redibuixar carregues en barra ',num2str(n),': ',num2str(toc(tic_rc))])
    end
    function redibuixar_carregues_barra2(n)
        % Dibuixa les càrregues a les barres.
        % Si existeixen objectes gràfics els elimina i els crea de nou.

        %disp(['Redibuixar carregues en barra ',num2str(n)])
        %tic_rc=tic;
       % delete(barres(n).hgpuntual) % Elimina objecte gràfic força puntual.
        barres(n).hgpuntual=[];
        %delete(barres(n).hgmoment) % Elimina objecte gràfic moment.
        barres(n).hgmoment=[];
        %delete(barres(n).hgrepartida) % Elimina objecte gràfic càrrega repartida.
        barres(n).hgrepartida=[];
        %delete(barres(n).hgprojectada) % Elimina objecte gràfic càrrega projectada.
        barres(n).hgprojectada=[];
        cordinf=nusos(barres(n).nusinf).posicio; % Coordenades nus inferior.
        cordsup=nusos(barres(n).nussup).posicio; % Coordenades nus superior.
        vectorbarra=cordsup-cordinf; % Vector direcció de la barra.
        vectorbarra=vectorbarra/norm(vectorbarra); % Vector direcció de la barra normalitzat.

        if barres(n).puntual(1) || barres(n).moment(1) % Si s'han introduït càrregues puntuals o moments...
            [barres(n).hgpuntual,barres(n).hgmoment]=dibuix_carregabarra(barres(n),nusos(barres(n).nussup).posicio-nusos(barres(n).nusinf).posicio,vista,fontcarregues,tamanyfontcarregues,fmax); % Dibuixa carrega puntual i moment.
            if barres(n).puntual(1) % Si s'ha introduït càrrega puntual...
                pos=barres(n).puntual(5)*vectorbarra+cordinf; % Posició en eixos globals de la càrrega puntual.
                m=makehgtform('translate',pos,'scale',s); % Matriu de col·locació i escala de la càrrega puntual.
                set(barres(n).hgpuntual,'ButtonDownFcn',@clic_carregabarra,'Matrix',m,'Parent',hg_carreguesbarres); % Aplica la matriu a l'objecte gràfic que representa la càrrega puntual.
            end
            if barres(n).moment(1) % Si s'ha introduït moment...
                pos=barres(n).moment(5)*vectorbarra+cordinf; % Posició en eixos globals del moment.
                m=makehgtform('translate',pos,'scale',s); % Matriu de col·locació i escala del moment.
                set(barres(n).hgmoment,'ButtonDownFcn',@clic_carregabarra,'Matrix',m,'Parent',hg_carreguesbarres); % Aplica la matriu a l'objecte gràfic que representa el moment.
            end
        end

        if barres(n).repartida(1) && any(cordsup-cordinf) % Si s'ha introduït càrrega repartida...
            puntinf=cordinf+vectorbarra*barres(n).repartida(5); % Punt inferior d'aplicació de la càrrega en eixos globals.
            puntsup=cordsup-vectorbarra*barres(n).repartida(6); % Punt superior d'aplicació de la càrrega en eixos globals.
            barres(n).hgrepartida=dibuix_repartida(n,puntinf,puntsup,barres(n).repartida,s,fontcarregues,tamanyfontcarregues,qmax); % Dibuixa la càrrega repartida.
            set(barres(n).hgrepartida,'ButtonDownFcn',@clic_carregabarra,'Parent',hg_carreguesbarres); % Assigna la funció que s'executarà quan es cliqueji sobre la càrrega.
            if strcmp(vista,'3d')
                set(get(barres(n).hgrepartida,'Children'),'Clipping','off') % Fa que els objectes gràfics sobresurtin de la grafica en vista 3d.
            else
                set(get(barres(n).hgrepartida,'Children'),'Clipping','on') % Fa que els objectes gràfics NO sobresurtin de la grafica en vista 3d.
            end
        end

        if barres(n).projectada(1) && any(cordsup-cordinf) % Si s'ha introduït càrrega projectada...
            puntinf=cordinf+vectorbarra*barres(n).projectada(5); % Punt inferior d'aplicació de la càrrega en eixos globals.
            puntsup=cordsup-vectorbarra*barres(n).projectada(6); % Punt superior d'aplicació de la càrrega en eixos globals.
            barres(n).hgprojectada=dibuix_projectada(n,puntinf,puntsup,barres(n).projectada,s,fontcarregues,tamanyfontcarregues,qmax); % Dibuixa la càrrega projectada.
            set(barres(n).hgprojectada,'ButtonDownFcn',@clic_carregabarra,'Parent',hg_carreguesbarres); % Assigna la funció que s'executarà quan es cliqueji sobre la càrrega.
            if strcmp(vista,'3d')
                set(get(barres(n).hgprojectada,'Children'),'Clipping','off') % Fa que els objectes gràfics sobresurtin de la grafica en vista 3d.
            end
        end
        %disp(['/Redibuixar carregues en barra ',num2str(n),': ',num2str(toc(tic_rc))])
    end


    function redibuixar_carregues_barres
        %disp('Redibuixar carrega barres')
        %tic_rcb=tic;
        for i=1:contbarra
            redibuixar_carregues_barra(i)
        end
        colorcarregabarres
        diagcarregues
        %disp(['/Redibuixar carrega barres: ',num2str(toc(tic_rcb))])
    end

    function esborrarcarregabarra(n)
        % Elimina els objectes gràfics que representen les càrregues sobre
        % la barra. Restableix els valors per defecte a la llista de
        % barres.

        %disp(['Esborrar carregues en barra ',num2str(n)])
        %tic_ec=tic;
        if barres(n).hgpuntual % Si hi ha un objecte que representa la força puntual...
            delete(barres(n).hgpuntual) % Elimina l'objecte.
            barres(n).hgpuntual=[]; % Elimina la seva referència.
            barres(n).puntual=[0,0,-1,0,0]; % Valor per defecte.
           % maxpuntual % Calcula carrega puntual maxima
        end

        if barres(n).hgmoment % Si hi ha un objecte que representa el moment...
            delete(barres(n).hgmoment) % Elimina l'objecte.
            barres(n).hgmoment=[]; % Elimina la seva referència.
            barres(n).moment=[0,0,0,1,0]; % Valor per defecte.
        end

        if barres(n).hgrepartida % Si hi ha un objecte que representa la càrrega repartida...
            delete(barres(n).hgrepartida) % Elimina l'objecte.
            barres(n).hgrepartida=[]; % Elimina la seva referència.
            barres(n).repartida=[0,0,-1,0,0,0]; % Valor per defecte.
           % maxrepartida % Calcula carrega repartida o projectada maxima.
        end

        if barres(n).hgprojectada % Si hi ha un objecte que representa la càrrega projectada...
            delete(barres(n).hgprojectada) % Elimina l'objecte.
            barres(n).hgprojectada=[]; % Elimina la seva referència.
            barres(n).projectada=[0,0,-1,0,0,0]; % Valor per defecte.
            %maxrepartida % Calcula carrega repartida o projectada maxima.
        end

        %disp(['/Esborrar carregues en barra ',num2str(n),': ',num2str(toc(tic_ec))])
    end


    function maxpuntual
        % Calcula la màxima força puntual o aplicada als nusos.

        fmax=0; % Valor per defecte cero.
        for i=1:contnus % Per a tots els nusos...
            fmax=max(abs([fmax,nusos(i).puntual])); % Màxim de les forces puntuals.
        end
        for i=1:contbarra % Per a totes les barres...
            fmax=max(abs([fmax,barres(i).puntual(1)])); % Maxim de les forces puntuals.
        end
        if flagcalculat % Si hi han reaccions...
            for i=1:contnus
                fmax=max(abs([fmax,Retorn_reaccions(i*6-5:i*6-3)']));
            end
        end

    end

    function maxrepartida
        % Calcula la maxima carrega repartida o projectada.

        qmax=0; % Valor inicial cero.
        for i=1:contbarra % Per a totes les barres.
            qmax=max(abs([qmax,barres(i).repartida(1),barres(i).projectada(1)])); % Màxim de les forces repartides i projectades.
        end
    end
end
Error using handle.handle/get
Invalid or deleted object.

Error in restorehg (line 115)
if strcmp(get(h, 'BackingStore'), 'off') || ~isempty(findall(h, 'EraseMode', 'xor'))

Error in restore (line 33)
        pj = restorehg( pj, h );

Error in print>LocalPrint (line 291)
        pj = restore( pj, h );

Error in print (line 237)
    LocalPrint(pj);

Error in internal.matlab.publish.PublishFigures>printSnap (line 230)
print(f,printOptions{:},imgFilename);

Error in internal.matlab.publish.PublishFigures.snapFigure (line 123)
                    feval([method 'Snap'],f,imgFilename,imageFormat,opts);

Error in internal.matlab.publish.PublishFigures/leavingCell (line 75)
                    imgFilename = obj.snapFigure(f,obj.options.filenameGenerator(),obj.options);

Error in snapnow>leavingCell (line 197)
            newFiles = data.plugins(iPlugins).instance.leavingCell(iCell);

Error in snapnow (line 133)
                        data = leavingCell(iCell(k), data, doCapture(k));

Error in cme2 (line 4158)
end

Error in evalmxdom>instrumentAndRun (line 89)
text = evalc(evalstr);

Error in evalmxdom (line 20)
[data,text,laste] = instrumentAndRun(file,cellBoundaries,imageDir,imagePrefix,options);

Error in publish (line 168)
    dom = evalmxdom(file,dom,cellBoundaries,prefix,imageDir,outputDir,options);

Error in mdbpublish (line 55)
outputPath = publish(file, options);

FUNCIONS DE CARREGA FORA DE LA FUNCIO PRINCIPAL

function [nusos,barres,contnus,contbarra]=carregararxiu(arxiu)
    % Carrega un arxiu amb dades de l'estructura i les retorna.
    % Aquesta funció no pot estar dins de la funció principal del programa,
    % Matlab no permet carregar les variables a l'espai de treball, ha
    % d'estar aillada.

    load(arxiu,'-mat') % Carrega les dades de nusos i barres.
    contnus=numel(nusos); % Nombre de nusos.
    contbarra=numel(barres); % Nombre de barres.
end
function [editalcrear,barraalcrearnus,fontnusos,tamanyfontnusos,fontcarregues,tamanyfontcarregues,factorzoom,tamanynus,distnumnus,precini,XLimini,YLimini,ZLimini,colormodificar,coloresborrar,colorcarregues,colorreaccions,colordeformada,colorN,colorTy,colorTz,colorMx,colorMy,colorMz,direst]=loadopcions
    % Carrega les variables amb les opcions del programa i les retorna.
    % Si no troba l'arxiu crida al diàleg per editar les opcions. El diàleg
    % no permet cancelar sense guardarles a l'arxiu. Finalment carrega les
    % dades.
    % Aquesta funció no pot estar dins de la funció principal del programa,
    % Matlab no permet carregar les variables a l'espai de treball, ha
    % d'estar aillada.

    if ~exist('opcions.mat','file') % Si no existeix l'arxiu d'opcions del programa obre la finestra d'edició de les opcions. No es pot sortir de la finestra d'opcions sense crear l'arxiu.
        dlgopcions % Crida al diàleg d'edició de les opcions.
    end
    load('opcions.mat') % Carrega les opcions.
end