みなさん,こんにちは.
おかしょです.
Processingを使ってグラフなどを書こうとすると,縦軸や横軸を書くために矢印を書きたくなります.
Processingには直線を引くコマンドは用意されているのですが,矢印を書くことのできるコマンドは用意されていません.
そこで,今回は矢印の始点と終点の座標を指定することで,2次元面内に矢印を引けるような関数の作り方を解説します.この記事の最後には,実際に動作するプログラムも載せますので,ぜひ参考にしてみてください.
この記事を読むと以下のようなことがわかる・できるようになります.
- Processingのプログラミング
- 矢印の描き方
この記事を読む前に
この記事では矢印を描くプログラムの解説をしています.
矢印に限らずプログラムの書き方がわからない方は,以下の記事を先に読んでおくことをおすすめします.
使用するコマンド
矢印を書くためにはさまざまなコマンドを駆使する必要があります.
ここでは,プログラム内で使用するコマンドを一つ一つ簡単に解説していきます.
Processingを触ったことがある方は,すでに知っているコマンドもあると思うので読み飛ばしても問題はありません.
background()
描画範囲内の背景を設定します.
引数によって背景の色や透明度などを設定できます.
size()
描画範囲の大きさを設定します.
単位はpixelで横と縦のサイズを引数とします.
translate()
座標軸を平行移動させます.
引数に入力した分だけ原点が平行移動します.
rotate()
座標軸を回転させます.
引数にradian単位で角度を入れることで,座標軸を任意の角度回転させることができます.
atan2()
アークタンジェントの計算ができます.
二つの引数を必要とし,それぞれの正負によって-πからπの範囲で答えを返します.
2がついていない場合は,引数は1つで-π/2からπ/2の範囲で返します.
stroke()
線の色を指定します.
line()
4つの引数で始点と終点を指定して,線を引くことができます.
pushMatrix(), popMatrix()
pushMatrix()でそれまでの座標軸を記憶します.
続く,popMtrix()で記憶した座標軸を吐き出すことができます.
このようにすることで,pushMatrix()とpopMtrix()の間でtranslateやrotateを使って座標軸を移動させても,元の座標軸に戻すことができます.
どちらも,引数は必要ありません.
sin(), cos()
三角関数のサインとコサインの計算をします.
以上のコマンドを使って,矢印を描いていきます.
2次元の矢印の描画
それでは,実際に矢印を描くプログラムを以下に示します.
void setup()
{
background(255); // 背景の色指定 白に指定
size(500, 500);
translate(250, 250);
rotate(-PI/2);
arrow(0, 0, 100, 70, 0, 0, 0);
arrow(0, 0, 150, 0, 255, 150, 150);
arrow(0, 0, 0, 150, 150, 255, 150);
rotate(-30*PI/180);
arrow(0, 0, 150, 0, 255, 0, 0);
arrow(0, 0, 0, 150, 0, 255, 0);
}
void draw()
{
}
void arrow(int x1, int y1, int x2, int y2, int Color1, int Color2, int Color3)
{
int arrowLength = 10;
float arrowAngle = 0.5;
float angle = atan2(y2-y1, x2-x1);
stroke(Color1, Color2, Color3);
line(x1, y1, x2, y2);
pushMatrix();
translate(x2, y2);
rotate(angle);
line(0, 0, -arrowLength*cos(arrowAngle), arrowLength*sin(arrowAngle));
line(0, 0, -arrowLength*cos(arrowAngle), -arrowLength*sin(arrowAngle));
popMatrix();
}
23行目以降のarrow関数で矢印を描くことができ,setup関数内でこれを使って矢印を描いています.
これを実行すると以下のようなwindowが表示されます.
以下では,arrow関数の解説をしていきます.
void arrow(int x1, int y1, int x2, int y2, int Color1, int Color2, int Color3)
{
int arrowLength = 10;
float arrowAngle = 0.5;
float angle = atan2(y2-y1, x2-x1);
stroke(Color1, Color2, Color3);
line(x1, y1, x2, y2);
pushMatrix();
translate(x2, y2);
rotate(angle);
line(0, 0, -arrowLength*cos(arrowAngle), arrowLength*sin(arrowAngle));
line(0, 0, -arrowLength*cos(arrowAngle), -arrowLength*sin(arrowAngle));
popMatrix();
}
最初の3, 4行では矢の部分の設定をしています.
arrowLengthは矢の長さを表していて,arrowAngleは角度を表しています.
5行目のangleは直線の角度を求めています.
引数の最初の4つは矢印の始点と終点の座標を表しています.
この座標から,atan2を用いて角度を求めます.
これによって,あらゆる角度に対応して矢を直線と結合させることができます.
6行目では引数の5, 6, 7番目を使って,矢印の色を設定します.
7行目では矢印の基となる直線を描きます.
8行目から13行目までで矢印の矢の部分を作成します.
矢の部分は直線の先から描いていきます.
そのため,8行目でそれまでの座標を保存しておき,9行目で座標の原点を直線の終点に移動します.
10行目で先程求めた,直線の角度の分だけ回転させます.
これをしないと,矢印の矢の部分は常に右を向いてしまい,きれいな矢印にはなりません.
11行目と12行目で矢の部分を描きます.
どちらも始点を原点としています.このときの原点は先程translateで移動したので矢印の基となる直線の終点の座標になっています.
終点の座標は三角関数を使って,3, 4行目で設定したとおりになるように設定しています.
最後に,popMatrixで保存した座標系を吐き出し,矢印を描く前の座標系に戻しています.
arrowLengthとarrowAngleをお好みで変えることによって矢の部分を大きくしたりもできるので,ぜひ試してみてください.
まとめ
この記事ではProcessingで矢印を描く方法について解説しました.
Processingでは矢印を描くコマンドが用意されていなかったので,自分で関数を作って矢印を簡単に作れるようにしてみました.
様々なコマンドを使用することで,簡単に書きたい絵が描けるのでProcessingはやはり便利だなと改めて実感しました.
続けて読む
この記事では2次元面内に矢印を描く方法を解説しましたが,この応用編として3次元の矢印があります.
以下の記事では3次元の矢印を描く方法を解説しているので読んでみてください.
Twitterでは記事の更新情報や活動の進捗などをつぶやいているので気が向いたらフォローしてください.
それでは最後まで読んでいただきありがとうございました.
コメント
[…] 以前,Processingで2次元面内に矢印を描くプログラムの解説を行いました.今回は3次元に矢印を描く方法を解説します. […]