5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MATLABで時計アプリ (2) (アナログ時計)

Last updated at Posted at 2019-08-30

はじめに

前回、MATLABでのデジタル時計アプリの作成方法を紹介しました。
デジタル時計は、数字を表示するだけなので、次は、針を持つアナログ時計を作成しています。

figureの作成

まず、figureを作成します。こちらはアナログ時計とほぼ変わりません

%% Figureの表示
figH                 = figure();              % figH: Figureオブジェクト
figH.MenuBar         = 'none';                % メニューをオフ
figH.CloseRequestFcn = @CloseRequestFcn_figH; % クローズ時のコールバック関数
figH.NumberTitle     = 'off';                 % 番号表示なし
figH.Name            = 'Analog Clock';        % タイトル

axes の作成

アナログ時計では、針を描画したいので、figure全体に表示するaxes(軸)を準備します。

%% Axesの表示
axH          = axes(figH);    % axH: 軸オブジェクト
axH.Units    = 'normalized';  % Positionの単位指定
axH.Position = [0,0,1,1];     % Figure全体にAxesを表示

時計の枠の表示

時計の枠を作成します。最も一般的な時計ということで、次のように円を表示します。

%% 時計枠(丸) を表示
x = linspace(0,2*pi,100);              % 1周を100分割(単位:ラジアン)
plot(axH,sin(x),cos(x),'LineWidth',5); % 円を描画

axis(axH,'equal'); % 縦横比を合わせる
hold(axH,'on');    % plot追加のためhold

こんな表示になります。
simple_analogclock_00.png

数字を表示

時計の時刻を表す数字を text で表示します。
各時刻に対応する角度を計算して、sin/cos で座標を決定します。

%% 数字を表示
for h1=1:12
    radh = -h1/12*2*pi+pi/2; % 角度の計算
    
    textH = text(axH,0.8*cos(radh),0.8*sin(radh),num2str(h1)); % テキスト作成
    textH.HorizontalAlignment = 'center';  % 中央寄せ
    textH.FontSize            = 30;        % フォントサイズ
    textH.FontWeight          = 'bold';    % 太字指定
end

数字が入って少し時計らしくなってきました。

simple_analogclock_01.png

時計の針の表示

plot で針を表示します。'k' は色を黒に指定することを意味します。太さは、LineWidth で指定します。

%% 長針/短針 のデフォルト表示 (6:00)

hourLineH   = plot(axH,[0,0],[0,-0.6],'k','LineWidth',10);
minuteLineH = plot(axH,[0,0],[0,1],   'k','LineWidth',5);
secondLineH = plot(axH,[0,0],[0,1],   'k','LineWidth',1);

一応、時計と認識できる絵になりました。

simple_analogclock_02.png

針の位置の設定(timerのコールバック関数)

timer のコールバック関数では、その時間での針の位置を計算して表示を更新します。
now は、現在のシリアル時刻(datenum: 0年1月0日0:00を0とした日数の表現)を得ることができます。
単位は、'日'なので、例えば、606024 を乗算すると、単位が秒になります。
これを使って計算すると、現在の時刻に相当する針の角度を求めることができます。
グラフィックスとして、針の位置を変更するためには、それぞれの lineオブジェクトの XData, YData を更新します。

    function updateClock(~,~)
        %% Timerコールバック: 表示の更新                
        % 各針の角度の計算
        sec = now*60*60*24; % 現在時刻の経過秒
        
        rad1 = -fix(sec)/60*2*pi+pi/2;  % 秒針の角度
        rad2 = -sec/60/60*2*pi+pi/2;    % 長針(分)の角度
        rad3 = -sec/60/60/12*2*pi+pi/2; % 短針(時間)の角度
        
        % 各針の描画の更新
        secondLineH.XData = [0,cos(rad1)];        
        secondLineH.YData = [0,sin(rad1)];
        
        minuteLineH.XData = [0,cos(rad2)];
        minuteLineH.YData = [0,sin(rad2)];
        
        hourLineH.XData = [0,0.6*cos(rad3)];
        hourLineH.YData = [0,0.6*sin(rad3)];        
        
    end

完成したプログラム

前回と同じところは省略して、プログラム全体を示します。

function simple_analogclock()

%% Figureの表示
figH                 = figure();              % figH: Figureオブジェクト
figH.MenuBar         = 'none';                % メニューをオフ
figH.CloseRequestFcn = @CloseRequestFcn_figH; % クローズ時のコールバック関数
figH.NumberTitle     = 'off';                 % 番号表示なし
figH.Name            = 'Analog Clock';        % タイトル

%% Axesの表示
axH          = axes(figH);    % axH: 軸オブジェクト
axH.Units    = 'normalized';  % Positionの単位指定
axH.Position = [0,0,1,1];     % Figure全体にAxesを表示

%% 時計枠(丸) を表示
x = linspace(0,2*pi,100);              % 1周を100分割(単位:ラジアン)
plot(axH,sin(x),cos(x),'LineWidth',5); % 円を描画

axis(axH,'equal'); % 縦横比を合わせる
hold(axH,'on');    % plot追加のためhold

%% 数字を表示
for h1=1:12
    radh = -h1/12*2*pi+pi/2; % 角度の計算
    
    textH = text(axH,0.8*cos(radh),0.8*sin(radh),num2str(h1)); % テキスト作成
    textH.HorizontalAlignment = 'center';  % 中央寄せ
    textH.FontSize            = 30;        % フォントサイズ
    textH.FontWeight          = 'bold';    % 太字指定
end

%% 長針/短針 のデフォルト表示 (6:00)

hourLineH   = plot(axH,[0,0],[0,-0.6],'k','LineWidth',10);
minuteLineH = plot(axH,[0,0],[0,1],   'k','LineWidth',5);
secondLineH = plot(axH,[0,0],[0,1],   'k','LineWidth',1);

% 現在時刻に合わせる
updateClock();

%% 軸表示の調整
axH.XTick = []; % X軸目盛をオフ
axH.YTick = []; % Y軸目盛をオフ

%% Timerの設定
timerH               = timer();      % timeH: タイマーオブジェクト
timerH.ExecutionMode = 'FixedRate';  % 定期的に実行するよう指定
timerH.Period        = 1;            % 1秒間隔
timerH.TimerFcn      = @updateClock; % コールバック関数指定

% 開始時刻の調整(秒が変わる瞬間にできるだけ合わせる。※処理時間の若干の遅延は許容する)
curTime   = datetime(now,'ConvertFrom','datenum');  % 現在時刻
delayTime = ceil(curTime.Second)-curTime.Second;    % 次に秒が変わる時間との差分(ミリ秒)を計算

timerH.StartDelay = delayTime; % Timerの開始時刻までの遅延を指定

%% timerの開始
start(timerH);

    %% コールバック関数
    function CloseRequestFcn_figH(~,~)
        %% Figureを閉じたときのコールバック:timerをStopしてからクローズ
        stop(timerH);
        delete(timerH);
        delete(figH);
    end

    function updateClock(~,~)
        %% Timerコールバック: 表示の更新                
        % 各針の角度の計算
        sec = now*60*60*24; % 現在時刻の経過秒
        
        rad1 = -fix(sec)/60*2*pi+pi/2;  % 秒針の角度
        rad2 = -sec/60/60*2*pi+pi/2;    % 長針(分)の角度
        rad3 = -sec/60/60/12*2*pi+pi/2; % 短針(時間)の角度
        
        % 各針の描画の更新
        secondLineH.XData = [0,cos(rad1)];        
        secondLineH.YData = [0,sin(rad1)];
        
        minuteLineH.XData = [0,cos(rad2)];
        minuteLineH.YData = [0,sin(rad2)];
        
        hourLineH.XData = [0,0.6*cos(rad3)];
        hourLineH.YData = [0,0.6*sin(rad3)];        
        
    end

end

実行例

実行してみます。

simple_analogclock.png

終わりに

シンプルな時計アプリの例を紹介しました。
GUIやアニメーションのプログラムの勉強にはいい題材で、好みでいろんな時計アプリを作成できると思いますので、チャレンジしてみてください。
ちなみに、MATLAB Central にもいろいろな例がありますよ。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?