본문 바로가기

Software/MATLAB

MATLAB으로 시계를 만들어 보자.

얼마전에.. 아니 예전에 어떤 방문자께서 MATLAB으로 시계를 만드는 방법을 물어보셨었습니다. 당시엔 너무 바빠 대답을 드리지 못했는데요. 문득 잠시 짬이 생기니 그때 질문에 답하고 싶어졌네요^^ 이제 MATLAB으로 시계를 한번 만들어 보겠습니다.


이렇게 생긴 아주 간단한 시계를 만들어 볼려고 하는거죠^^

제일 먼저 생각해야할 것은 바로, 뭐 당연한 이야기지만, 현재의 시간을 알아야하는데요.^^ 게중에 간단히 쓸수있는 것이 'now'라는 명령입니다. 근데 요게 좀 문제가 있어요


치사하게 이렇게 결과가 나오거든요...ㅠㅠ. 이걸 다시 현재 시간처럼 표현하는 명령중에서 좀 간단한 것이


'datestr'이라는 놈입니다. 음.. 단점은... 요게.. 명령어 이름에서도 나타나듯이 문자열로 나타난다는....ㅠㅠ


그러나 뭐 문자열이라고 해서 문제될게 있겠습니까.. 위 코드처럼 짤라서 문자를 숫자로(str2double)로 만들어주면 되죠.. ㅋㅋ... 그런데 이 str2double명령을 사용하기전에 str2num을 사용했거든요. 그런데 MATLAB Editor가 str2num보다 str2double이 더 빠르다더군요. 음.. 이유는 모르겠지만, 빠르다니까 그냥 써야죠^^

이것 말고는 나머지는 예전에 설명했던 것을 이용했습니다. 일단 전체 코드를 좀 보고 약간의 부연설명을 하겠습니다.

% Initialize Figure
t = 0:0.1:2*pi;
h=figure;
plot(10*cos(t), 10*sin(t), 'g'); grid on; axis square
hold(gca, 'on');
t_m = 0:2*pi/60:2*pi;
plot(10*cos(t_m), 10*sin(t_m), 'go', 'MarkerFaceColor','g', 'MarkerSize',5)
t_h = 0:2*pi/12:2*pi;
plot(10*cos(t_h), 10*sin(t_h), 'ro', 'MarkerFaceColor','r', 'MarkerSize',8)
plot(0, 0, 'go', 'MarkerFaceColor','g', 'MarkerSize',10)
set(gca, 'Xlim', [-11 11], 'Ylim', [-11 11], 'box', 'off', 'XColor', [0.801 0.801 0.801], 'YColor', [0.801 0.801 0.801], 'Color', [0.801 0.801 0.801])

% Initialize Each hand
time = datestr(now);
hour = str2double(time(13:14));
min = str2double(time(16:17));
second_r = str2double(time(19:20));

hour_t = pi/2-2*pi/12*hour-2*pi/12*min/60;
hour_hand = line([0.5*cos(hour_t), 4.5*cos(hour_t)], [0.5*sin(hour_t), 4.5*sin(hour_t)], 'color', 'k','LineWidth',12);
min_t = pi/2-2*pi/60*min;
min_hand = line([0.5*cos(min_t), 8*cos(min_t)], [0.5*sin(min_t), 8*sin(min_t)], 'color', 'k','LineWidth',6);
second_t = pi/2-2*pi/60*second_r;
second_hand = line([0.5*cos(second_t), 9*cos(second_t)], [0.5*sin(second_t), 9*sin(second_t)], 'color', 'b','LineWidth',3);

% Main code
while(1)
    time = datestr(now);
    hour = str2double(time(13:14));
    min = str2double(time(16:17));
    second = str2double(time(19:20));
    
    if second ~= second_r
        % Update time
        updateHour = pi/2-2*pi/12*hour-2*pi/12*min/60;
        updateMin = pi/2-2*pi/60*min;
        updateSec = pi/2-2*pi/60*second;
        
        % Calculate position of each hand
        updateHour_x = [0.5*cos(updateHour), 4.5*cos(updateHour)];
        updateHour_y = [0.5*sin(updateHour), 4.5*sin(updateHour)];
        updateMin_x = [0.5*cos(updateMin), 8*cos(updateMin)];
        updateMin_y = [0.5*sin(updateMin), 8*sin(updateMin)];
        updateSec_x = [0.5*cos(updateSec), 9*cos(updateSec)];
        updateSec_y = [0.5*sin(updateSec), 9*sin(updateSec)];
        
        % Update position of each hand
        set(hour_hand, 'Xdata', updateHour_x, 'Ydata', updateHour_y);
        set(min_hand, 'Xdata', updateMin_x, 'Ydata', updateMin_y);
        set(second_hand, 'Xdata', updateSec_x, 'Ydata', updateSec_y);
        
        drawnow;
        second_r = updateSec;
    end
end

이게 그 코드인데요...
좀 긴가요???^^

일단 2행부터 11행까지는 그냥 기본 시계판을 만드는것입니다. 그런데 그중 11행에서 사각형 표시를 없애버리고('Box', 'off'), 기본판과 X, Y출의 색을 동일하게 처리해서 눈금이 없어지도록 했구요. (음... 그 눈금자를 없애는 속성을 모르겠더군요...ㅠㅠ). 그리고, 정사각형으로(axis square) 그리도록 했습니다.

그리고 14행부터 17행까지는 위에서 설명한 현재의 시간을 받아오는 것이구요.

그것에 맞춰서 19번행부터 24번행까지 현재의 시간을 일단 그린것입니다. 여기서, 분침은 60등분이나 되니 신경쓰지 않았지만, 시침의 경우는 현재의 분 만큼 또 진행되어야해서 그걸 19번행에서 고려했습니다. 그리고, 시, 분, 초침을 그릴때, MATLAB은 x축의 양의 방향에서 시작해서 시계반대방향으로 '+'라고 생각하기 때문에 y축의 양의방향 그러니까, 90도 지점에서 시계방향으로 시작하게끔하기 위해 19번행, 21번행, 23번행과 같이 표현한 것입니다.

그리고, 이후 26번행부터는 MATLAB의 애니메이션을 설명했던 글 [관련글]에서 다룬 것을 사용했습니다. 당시엔 'for'문을 사용했고, 지금은 'while'문을 무조건 돌리도록(^^) 한것 뿐인데요. 덕분에 시계프로그램을 강제종료하면 살짝 에러 메세지가 하나 뜹니다. 뭐 종료버튼하나 만들면 되는 일인데.. 좀.. 귀찮네요...ㅠㅠ 죄송...^^


반응형