お絵かきプログラミングProcessingサンプルコード解説の第4弾です!
ProcessingをまだPCに導入されていない方は、こちらの記事を参考に導入してみてください!
今回は Follow1 というサンプルコードをみてみましょう。
この記事では、図形変形の基本を学べます。
難易度は ★★☆☆☆ くらい。
わからない箇所があればコメントをください。
Table of Contents
もくじ
とりあえず動かしてみよう
Processnigを起動し、サンプルコードを開きましょう。
ファイル → サンプル と選択し現れたウィンドウで Topics → Interaction → Follow1 と選択してください。
このようなスケッチが現れます。ウィンドウの左上にある再生ボタンをクリックして実行してみましょう。
カーソルを動かすと…なんか付いてきますね?
というわけでこのコードは、「モノをカーソルに付いてくるように動かすコード」です。
インタラクティブな描画を行う際に、マウスカーソルを利用することは多いと思います。
また今回は、座標軸の移動や三角関数など、自分のイメージをより直感的にコードにするために便利な操作を扱います。
ぜひ身につけましょう。
コードを読む
とりあえずコードの全貌を確認しましょう。
コンパクトですね。では読み進めていきましょう。
今回も構造に少し特徴があります。
今まではsetup, drawの2つのブロックで処理が行われていました。が、今回はsegmentがありますね。
これは関数です。ブロックの外部に定義するのは、他のブロックから呼び出すためです。
したがってsegmentは他のブロックで呼ばれることがほぼ確定しているので、この関数の処理は先に理解しておく必要がありそうです。
が、その前にこのsegmentでも使いうるグローバル変数のところまで先に読んでおきましょう。
まずコメントから始まっていますね。
「Keith PetersのコードにのっとったFollow1。線分がカーソルによって押されたり引かれたりする。」
言葉の説明ではわかりにくいですが、実行してみたのでわかりますね。ちなみにline segment=線分です。
ではグローバル変数を見ましょう。
関数内での使われ方は未確認なので、この時点では変数の意味はわかりません。名前からある程度類推しておきましょう。
変数 | 意味 |
---|---|
x | x座標? |
y | y座標? |
angle1 | 角度? |
segLength | segmentの長さ? |
segLengthはさっき確認したコメントでの表現から考えます。このsegmentというのは「線分」のことを指していると思われます。segmentのlengthを縮めながら繋げてsegLengthという言葉になっていると考えられます。
Processingでは変数名として通例キャメルケースを採用します。変数名の表記には様々な流派があり、これはコーディング規約により異なります。興味がある人は調べてみてください。
ではsegmentの中を見ましょう。
実はsegment内部には図形の変形に便利な様々な関数が詰まっています。
というわけで今回は描画に当たって便利な道具としての座標軸の技を詳しく説明します。
座標軸の操作
座標軸の扱い方はこれまで扱ってきませんでした。
簡単にいうと、表に出てこない変数という形で存在していて、いつでも値を変更することができます。
まずはその変数の「形」について説明します。
スタック
座標軸の情報はスタックというデータ構造で保存されます。
スタックはデータを保存しておく枠と思ってもらえればよいです。
スタックのデータ処理は図のようになります。初めは空の箱になっています。データが渡されたら下から積み木のように積み上げていき、データを取り出すときは一番上から取り出します。
ちなみにスタックが空の時は何も取り出せません。
初めに入れたデータは、その上に積まれている全てのデータが取り出されるまで、取り出すことができません。ちなみに初めに入れたものが最後に取り出される性質は、First In First Out (FIFO) と呼ばれます。詳しく知りたい方は調べてみてください。
今回は「座標軸の情報」が積み木としてスタックに渡されます。
座標についてはこれまでも時々説明しましたね。Processingではウィンドウの左上の角の点が(0, 0)で、横軸がx軸、縦軸がy軸とされています。
この原点をずらしたり、回転させたりします。
今回出てきた4つの関数をそれぞれ詳しくみていきましょう。
- pushMatrix()
現在の座標軸を保存する。 - translate(x, y)
座標軸をx軸方向にx、y軸方向にyだけ平行移動する。
これにより原点は(0, 0)から(x, y)に移動します。 - rotate(a)
座標軸を回転させます。
引数aの単位はラジアンです。ラジアンは角度を表す単位の一つであり、180°=πラジアンとして比例計算で求まります。aラジアン = (a/π * 180)° となります。
rotate(a)は座標軸をaラジアン回転させます。回転の向きは時計回りになります。 - popMatrix()
pushMatrix()で保存した座標軸情報を取り出し、設定します。一度取り出すとスタックからは削除されます。
segmentの中にはlineという関数も含まれていますが、これは2点を結ぶ線分を描く関数です。
2点の座標を(x1, y1)、(x2, y2)とすると引数の取り方は
line(x1, y1, x2, y2)
となります。
というわけで、segment(x, y, a)が行うことは、
まず、座標軸をx方向にx、y軸方向にy移動したのち角度をaラジアン回転します。
さらにこの座標軸で(0, 0)と(segLength, 0)を結ぶ線分を描き、座標軸を元に戻します。
segmentだけでかなり重かったですね。残りは上から順にみていきましょう。
setup
次にsetupの部分をみます。
sizeはお馴染みですが、他は初めてかもしれませんね。
関数の意味は次の通りです
関数 | 意味 |
---|---|
size | ウィンドウサイズの指定 |
strokeWeight | 線の太さの指定 |
stroke | 線の色の指定 |
次に進みます。
draw
次にdrawの部分をみます。
backgroundはウィンドウ全体を塗りつぶす関数です。お馴染みです。引数は色を表しますが、今回は「黒」を表します。他の色指定の方法を知りたい方は公式ドキュメントを参照してください。
次に進みましょう。
新たな変数dx, dyが定義されました。マウスカーソル位置座標を表すmouseX, mouseYを使って決定されていることから、カーソル移動により変化する値だとわかりますね。
見慣れない関数が出てきました。atan2, cos, sin…三角関数と呼ばれるものですね。
簡単に関数の意味をまとめます。
関数 | 意味 |
---|---|
atan2 | tanの逆関数 |
cos | コサイン |
sin | サイン |
三角関数について知らないかたは各自で調べてみてください。
この時点ではx, yが何を表す変数なのかわかりません。まだ描画に使われていませんからね。
まず次の行までの処理の結果を考えましょう。x, yは、とりあえず適当な点とします。
図のようになります。
次にx, yの更新が行われます。
図で表すと、x, yはこのような値になります。
次に描画です。
segment(x、y、angle1)は(x, y)を始点とし、長さsegLengthの線分を描きます。線分の角度は垂直から反時計回りにangle1だけ回した状態になります。
ellipseは楕円を描く関数で、ellipse(x, y, 20, 20)は(x, y)を中心にx方向の半径20, y方向の半径20の楕円を描きます。今回は正円になっていますね。
drawが無限ループで処理されることにより、マウスカーソルの移動に伴って、線分の端点と円の中心が更新され、描画し直されることがわかりました!
これで終わりです!お疲れ様でした!
さいごに
今回扱ったトピックは、座標軸の操作、三角関数でした。いずれも効率的な描画には欠かせない技なので、使いこなしてください!
ではまた次回!
[…] pushMatrix()、popMatrix()の説明は 【Follow1】の記事で詳しく説明してあるので今回は軽い説明で進めます。興味がある方はそちらを参照してください。 […]