お絵かきプログラミングProcessingサンプルコード解説の第10弾です!
ProcessingをまだPCに導入されていない方は、こちらの記事を参考に導入してみてください!
今回は Arctangent というサンプルコードを見てみましょう。
難易度は ★★☆☆☆ くらい。高校まででは習わない数学を扱うので少し難しいかもしれません。
わからない箇所があればコメントをください。
Table of Contents
もくじ
とりあえず動かしてみよう
Processnigを起動し、サンプルコードを開きましょう。
ファイル → サンプル と選択し現れたウィンドウで Basics → Math → Arctangent と選択してください。
このようなスケッチが現れます。ウィンドウの左上にある再生ボタンをクリックして実行してみましょう。
目がマウスカーソルをギョロギョロ見てきます。
今回のコードは 三角関数を応用した図形の描画を扱います。
コードを読む
とりあえずコードの全貌を確認しましょう。
そこそこの長さですね。しかも今回はsetup()、draw()以外にもう一つ大きなブロックがありますね。クラスです。
クラス自体の説明をしようとすると本筋から外れてしまいそうなので、何とか流れがわかる程度の説明にしようと思います。
まず初めのコメントを読みましょう。
「アークタンジェント。マウスを動かすと目の向きが変わります。atan2()はそれぞれの目からマウスカーソルへの角度を計算します。」
とのことです。
アークタンジェントを聞いたことがない人のために簡単に説明します。タンジェントは聞いたことがある前提で話を進めます(高校数学で出てくるtanと書かれる関数です)。sin、cosと一緒に出てくるやつですね。
アークタンジェント(arctan)はこのtangentの逆関数です。
逆関数は聞いたことがない方がいると思いますが、具体例で説明すると、tan(π/4) = 1 ですが、arctan(1) = π/4となります。tanと入出力の関係が逆です。細かい説明は省くので興味のある人は調べてみてください。
まずは1行しかありませんがグローバル変数を確認します。
Eyeという型の変数が宣言されていますね。EyeはProcessingが用意している型ではなく自分で定義しています。中身は後で確認しましょう。
まずは描画の様子が最もわかりやすいdraw()の中身を見てみましょう。
draw
background()は毎度お馴染みですね。全体を塗りつぶす関数です。今回の引数は102なので黒寄りの灰色で塗り潰すことになります。
次ですが、e1~e3がそれぞれupdate()をしてからdisplay()をしています。
現時点ではEye型の中身がわかっていないので処理の詳細はわかりませんが、「目」の何かを更新し、表示することが繰り返される、と想像できますが細かいことは後にまわしましょう。
今回は自分でクラスを定義して使っているおかげもあり、draw()の中は短く収まっていますね。
では一旦setup()を確認しましょう。
setup
size()は毎度おなじみのウィンドウサイズを指定する関数ですね。
noStroke()もよくみる関数ですね。図形の枠線が描かれなくなります。
この後e1~e3に値を設定していますね。とりあえずsetup()を通じて宣言済みの各変数に値が入ったことだけ覚えておきましょう。
では問題のEyeを見てみましょう。クラスの概念には極力触れずに進めます。
Eye
変数と関数が定義されていますね。順に見ていきましょう。
まずローカル変数とコンストラクタ(この言葉がわからなかったら無視して大丈夫)を定義しています。
この時点ではまだよくわからないので、いったん流しましょう。
display()をみてみましょう。先に言ってしまうとここがこのサンプルの肝です。頑張っていきましょう!
pushMatrix()、popMatrix()の説明は 【Follow1】の記事で詳しく説明してあるので今回は軽い説明で進めます。興味がある方はそちらを参照してください。
- pushMatrix()で現在の座標軸を保存します。
- translate()により座標軸を平行移動させます。
- fill()、ellipse()で中心が(0, 0)、直径がsizeの円を描画します。
この時点では以下のようなイメージになります。座標軸を移動させた先で円を描画しています。
次です。
- rotate()で座標軸を回転させます。
- fill()、ellipse()で中心が(0, size/4)、直径がsize/2の円を描画します。
イメージはこのようになります。
最後にpushMatrix()で初めに保存した座標軸を復元します。
これで目の形を描く方法はわかりましたね。
ところで途中で出てきたsizeとangleはどこで決めていたのでしょう。飛ばした部分をみていきましょう。
Eyeで定義してあるもう一つの関数update()をみましょう。
一行しかないですね。
ところでatan2()とありますが、これがarctangent(以下arctan)です。
先ほどarctanの定義を軽く説明しましたが、Processingのatan2()はx、yを入力にとり、θの値を出力します。
atan2()はupdate()の中で使われていますね。update()の中でx、yが出てきますが、これは何の値だったでしょうか?
上の円の描かれ方の図を見返して欲しいのですが、実はx、yは目の中心のx座標、y座標に相当しています。
ではmxとmyはなんでしょう。使われているところを確認しましょう。
マウスカーソルの位置ですね。
さっきの目の図に合わせると位置関係はこんな感じになります。
目の方向を変化させる処理がdraw()内部で無限ループされているので、マウスの移動に応じて目の方向がリアルタイムに変化します。
あとは、実は後回しにしていた部分としてsetup()内部のEyeのコンストラクタがありますね。
コンストラクタの定義はこうなっています。
そして実際に呼ばれているところはこうなっています。
例えばe1は(x, y) = (250, 16) の位置にsize(直径)=120の「目」として生成されています。
これで全ての処理が確認できたと思います。お疲れ様でした!!
今見るとこの動きの仕組みがよくわかると思います。
さいごに
今回は、arctanを用いた図形の描画を学びました。
クラスの使い方は慣れないとわかりにくいと思いますが、今回はarctanのくだりがわかれば十分です。
ではまた次回!