Search code examples
matlabmatlab-figure

Closing the figure window causes a new figure window to open


This is a analog clock. It runs perfectly. But once I close the clock, another figure opens up, and only the clock hands show. This makes it difficult to stop the program. How can I stop the program?

x=0;y=0;r=10;
hold on;
theta = 0:pi/60:2*pi;
xc = r * cos(theta);
yc = r * sin(theta);
h = plot(xc,yc,'r','linewidth',4);
axis off
r=9; i=1;
set(gca,'FontWeight','bold');

for theta = pi/6: pi/6: 2*pi
    y1 = r * cos(theta);
    x1 = r * sin(theta);
    plot([x1/9*8 x1/9*7],[y1/9*8 y1/9*7],'color',[0 0 1])
    text(x1/9*9.5,y1/9*9.5,num2str(i),'color',[0 0 1]);
    i=i+1;
end

for theta=pi/30 : pi/30 : 2*pi
    y1 = 10 * cos(theta);
    x1 = 10 * sin(theta);
    plot([x1/9*8 x1/9*7],[y1/9*8 y1/9*7],'color',[0 0 0])
end

while(1)
    tic
    c = clock;
    c = c(1,4:6);
    minute =c(1,2); sec=c(1,3);
    if (c(1,1)>12)
       hr = c(1,1)-12;
    else
       hr = c(1,1);
    end
    min1 = ceil(minute/12);
    theta = (hr*pi)/6 + (min1*pi)/30;
    f=figure(1); hold on;
    y1 = 3 * cos(theta); Yhr = [0 y1];
    x1 = 3 * sin(theta); Xhr = [0 x1];
    hrhnd=plot(Xhr,Yhr);hold on;
    theta1 = (minute*pi)/30;
    y2 = 4.5 * cos(theta1); Ymin = [0 y2];
    x2 = 4.5 * sin(theta1); Xmin = [0 x2];
    minhnd=plot(Xmin,Ymin);
    theta2 = (sec*pi)/30;
    y3 = 5 * cos(theta2); Ysec = [0 y3];
    x3 = 5 * sin(theta2); Xsec = [0 x3];
    sechnd=plot(Xsec,Ysec);
    z=toc;
    pause(1-z);
     delete(sechnd);
     delete(minhnd);
     delete(hrhnd);
end

Solution

  • The simplest way to stop the script when you close the window is to have the script test inside its loop if the window still exists.

    We start the script by creating a figure window and recording its handle:

    fig = figure;
    

    Next, in the loop, we check to see if the window still exists using ishandle:

    while(ishandle(fig))
       ...
    end
    

    The full program:

    x=0;y=0;r=10;
    fig = figure;       %!!! NEW LINE
    hold on;
    theta = 0:pi/60:2*pi;
    xc = r * cos(theta);
    yc = r * sin(theta);
    h = plot(xc,yc,'r','linewidth',4);
    axis off
    r=9; i=1;
    set(gca,'FontWeight','bold');
    
    for theta = pi/6: pi/6: 2*pi
        y1 = r * cos(theta);
        x1 = r * sin(theta);
        plot([x1/9*8 x1/9*7],[y1/9*8 y1/9*7],'color',[0 0 1])
        text(x1/9*9.5,y1/9*9.5,num2str(i),'color',[0 0 1]);
        i=i+1;
    end
    
    for theta=pi/30 : pi/30 : 2*pi
        y1 = 10 * cos(theta);
        x1 = 10 * sin(theta);
        plot([x1/9*8 x1/9*7],[y1/9*8 y1/9*7],'color',[0 0 0])
    end
    
    while(ishandle(fig))    %!!! UPDATED LINE
        tic
        c = clock;
        c = c(1,4:6);
        minute =c(1,2); sec=c(1,3);
        if (c(1,1)>12)
           hr = c(1,1)-12;
        else
           hr = c(1,1);
        end
        min1 = ceil(minute/12);
        theta = (hr*pi)/6 + (min1*pi)/30;
        f=figure(1); hold on;
        y1 = 3 * cos(theta); Yhr = [0 y1];
        x1 = 3 * sin(theta); Xhr = [0 x1];
        hrhnd=plot(Xhr,Yhr);hold on;
        theta1 = (minute*pi)/30;
        y2 = 4.5 * cos(theta1); Ymin = [0 y2];
        x2 = 4.5 * sin(theta1); Xmin = [0 x2];
        minhnd=plot(Xmin,Ymin);
        theta2 = (sec*pi)/30;
        y3 = 5 * cos(theta2); Ysec = [0 y3];
        x3 = 5 * sin(theta2); Xsec = [0 x3];
        sechnd=plot(Xsec,Ysec);
        z=toc;
        pause(1-z);
         delete(sechnd);
         delete(minhnd);
         delete(hrhnd);
    end
    

    You could improve your program by not deleting and re-drawing the hands, but updating their position. You'd do hrhnd=plot(Xhr,Yhr); before the loop, to draw the hand in its initial position, and then set(hrhnd,'XData',Xhr,'YData', Yhr) to update its position.

    You could also do axis equal after drawing the clock face, to ensure it is round.

    Note that you only need to give hold on once at the top, it is not needed after every plot command.