MATLABでお絵描きツールを作ってみた （マウス操作イベントに応じたプログラム例）

# はじめに

MATLABでは、マウス操作に応じたプログラムを行うことができます。ここでは、簡単なお絵描きツールを例に、その方法を説明します。

# どのようにプログラミングするか？

スクリプトや関数を記述するMATLABにおいて、マウス操作に応じたプログラミングをどのようにするのか、ぱっとは分かりにくいですが、実は、グラフなどを描画する figure にコールバック関数を設定することで、マウス操作に応じたプログラムをすることができます。マウス操作に応じた線を描画することでお絵かきツールを作成できます。

# マウス操作に関するfigure のコールバック関数

figure には、マウス操作に応じた以下のコールバック関数があります。

| コールバック関数|概要|
|:-------------------|:-------------------------------------------------|
| **WindowButtonDownFcn**|マウスをクリックしたときに呼びだされるコールバック関数|
| **WindowButtonMotionFcn**| マウスを動かしたときに呼びだされるコールバック関数|
| **WindowButtonUpFcn**|マウスを離したときに呼びだされるコールバック関数|

ちなみに、今回の例では使いませんが、figure には、キーボード入力に対応する **WindowKeyPressFcn** というコールバック関数もあります。

# マウスの位置の取得

マウスがある場所は、figure、または、axes の **CurrentPoint** プロパティで取得することができます。今回のお絵描きツールでは、axes上の座標が欲しいので、axes の **CurrentPoint** を使用します。

# プログラム例

次のアイデアでプログラムを作成します。

- figure 全体にaxes を表示
- マウスボタンを押したときには、ボタン押下状態を共通変数に保存し、その点をlineで表示
- ボタン押下状態でマウスを移動したときには、line のX座標、Y座標に新たな座標を追加して更新
- マウスボタンをリリースした時は、ボタン押下状態をオフ

では、実際のプログラム例です。

```matlab:simple_draw.m
function simple_draw()

%% 共通変数の定義
ButtonState = false;      % マウスボタンの押下状態
curLineH    = gobjects(); % 現在のLineのオブジェクト
curLineX    = [];         % 現在のLineのX座標
curLineY    = [];         % 現在のLineのY座標

%% Figureの表示
figH                       = figure();                     % figH: Figureオブジェクト
figH.MenuBar               = 'none';                       % メニューをオフ
figH.WindowButtonDownFcn   = @WindowButtonDownFcn_figH;    % マウスボタン押下時のコールバック関数を指定
figH.WindowButtonMotionFcn = @WindowButtonMotionFcn_figH;  % マウスボタン移動時のコールバック関数を指定
figH.WindowButtonUpFcn     = @WindowButtonUpFcn_figH;      % マウスボタンリリース時のコールバック関数を指定

%% Axesの表示
axH               = axes(figH);    % axH: 軸オブジェクト
axH.XTick         = [];            % X軸目盛をオフ
axH.YTick         = [];            % Y軸目盛をオフ
axH.Units         = 'normalized';  % Positionの単位指定
axH.Position      = [0,0,1,1];     % Figure全体にAxesを表示
axH.XLim          = [0,1];         % X軸範囲を指定
axH.YLim          = [0,1];         % Y軸範囲を指定

    %% コールバック関数の定義
    function WindowButtonDownFcn_figH(~,~)
        %% マウスボタン押下時のコールバック        
        ButtonState = true; % 押下状態を保存

        % マウスの位置の取得
        curLineX = axH.CurrentPoint(1,1);
        curLineY = axH.CurrentPoint(1,2);

        % 線の描画
        curLineH = line(axH,curLineX, curLineY);
    end

    function WindowButtonMotionFcn_figH(~,~)
        %% マウスボタン移動時のコールバック
        if ButtonState
            % マウスボタンを押下時には、Lineの描画を更新

            % 現在のマウスの位置
            X = axH.CurrentPoint(1,1);
            Y = axH.CurrentPoint(1,2);
            
            % 線の座標値を更新
            curLineX = [curLineX;X];
            curLineY = [curLineY;Y];

            % 描画の更新
            curLineH.XData = curLineX;
            curLineH.YData = curLineY;
        end
    end

    function WindowButtonUpFcn_figH(~,~)
        %% マウスボタンリリース時のコールバック
        ButtonState = false;  % ボタン押下状態を解除
    end
end
```

コールバック関数をネスト関数にすることで、マウスのクリック状況を保持する ButtonState を共通変数としています。

# 実行例

実行すると 何も表示されない figure が表示されますので、マウスをクリックして絵を描くことができます。
こんな感じです。（絵心がなくてスミマセン。。）
一般的なPCを想定して、「マウス」として説明してきましたが、タッチパネル対応のPCですと、指やペンで絵を描くこともできます。

![example1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482917/53900e31-7eee-7adb-07a5-307a13cb65ed.png)
![example2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482917/fff98054-050b-2353-459e-ae2657b9c882.png)

# 終わりに

MATLABでのマウス操作に対応するプログラム例として、figureのコールバック関数を用いたお絵描きツールの例を紹介しました。60行ほどのプログラムでできてしまうので、コールバック関数が分かれば、いろいろな例に適用したくもなりますね。
お絵描きツールの応用としては、line の属性を変更して線の太さや色などを変えたり、描画した絵を画像ファイルとして保存する機能を追加することも可能です。OCR機能を使って、手書き文字の認識もできますね。「いいね」がたくさんついたら、次回紹介したいと思います！

[続きの記事:MATLABでお絵描きツールを作ってみた(2) (ボタンで各種設定)](https://qiita.com/sanmojih/items/116046214fa8deac8569)

### 【補足】uifigure, uiaxesの場合

最新のMATLABでは、AppDesginerでも使われている新しいテクノロジーによる uifigure がありますが、uifigure にも同様のコールバック関数が用意されています。