Processing で絵を描こう
ちょっとプログラムを使って図形描画をしたくなったので、簡単にかける仕組みはないかと探して、Processingに行き着いた。
勉強がてら、ポイントとサンプルをまとめました。
なお、最新版の Processing3 を使っているので、適宜インストールはしてください。
Processing とは
Processing は、グラッフィック描画などが柔軟・簡便にできるように設計されたプログラム言語であり、またそれを実行させるための統合開発環境(IDE)でもある。
何ができるの?
- プログラムコードで、絵が描けます1。
- IDE環境でもあるので、プログラムをIDE上のエディタに書いて、実行結果をすぐ見れます。
- 矩形や円、ドットや線など、図形の描画が可能です。
- 描画エリアを3次元として3Dなオブジェクトの描画もできます。
- イベントのキャッチ(マウスやキーボード入力)なども行え、インタラクティブなビジュアルアートの作成も可能。
- 作成した画像のpngなどへの出力が可能です。
- デザイナではないプログラマにとって、時には重宝するでしょう。
- p5.jsといったJavascriptライブラリもあり、発展性もあり。
言語的な特徴
- 関数型のプログラム言語。
- あらかじめ言語で用意されている組み込み関数で描画。
- 関数は動的バインディングなので、文法が引数に決まる。
- 自分で任意の関数も定義可能。
- あらかじめ言語で用意されている組み込み関数で描画。
- JavaをベースにしたDSLなので、文法はほぼJavaです。
- 1つの命令に
;
が必要。 -
,
を使った、複数命令の記述も可能。
- 1つの命令に
-
変数の型あり。Javaのプリミティブな型に加えて、color型が定義されています。
- int - 32ビット整数 -2147483648~2147483647
- long - 64ビット整数(-9223372036854775808~9223372036854775807)
- float - 32ビット単精度浮動小数点数
- double - 64ビット倍精度浮動小数点数
- boolean - 真偽型(
true
/false
) - byte - 8ビット整数(-128~127)
- char - 16ビットUnicode文字(\u0000~\uFFFF)
-
color
-
color()
で定義するか、#RRGGBB
で定義可能。
-
- 型変換には、
int()
などの型変換関数を用いる。
-
制御構文はシンプル
- ループ処理として、
for
,while
- 判断処理として、
if
,switch~case
- ループ処理として、
-
日本語処理も可能
- テキストエディタのフォントは日本語が表示できるものに設定を(Osakaなど)
基本
まずはサンプルコードを。
int x = 0; // x座標初期値
/*
* 初期化
*/
void setup() {
size(200, 200);
background(0);
noStroke();
fill(102);
}
/*
* 描画
*/
void draw() {
rect(x, 10, 2, 80);
x = x + 1;
println("x = ", x); // デバッグ
}
コメント
Javaと同じです。
/*
複数行コメント
*/
// 行末までコメント
コンソールへの出力
Javascriptでいうところのconsole.log()
に当たるのがprint
とprintln
。println
だと自動的に改行が入る。結果はコンソール・エリアに出力される。デバッグにどうぞ。
println("Hello, World!!");
コード
プログラムコードは、頭から順番に処理される。
下記で説明する setup()
や draw()
などを使って基本動作を定義することも可能だが、これらの関数を使わなくても実行可能である。
setup() と draw()
setup()
と draw()
は、言語で定義された初期化関数と描画実行関数である。
setup()
では、実行時に1回呼ばれる。size()
やfullScreen()
、background()
など、ディスプレイ・ウィンドウの属性や初期背景色などの初期化処理を行うと良い。
draw()
は1フレームごとに呼ばれる。実際に描画関数を読んで何かを描かせる。Processingは、draw()
関数の処理が終わった時点で描画を行う。
どちらも void
型の関数とする。
上記サンプルを実行すると、停止()が押され続けるまで、println
が実行されるのがわかるだろう。(描画内容は途中から同じ結果になってしまうので変化なしに見えてしまうが)
リファレンス: setup()
リファレンス: draw()
size() と fullScreen()
ディスプレイ・ウィンドウの属性(幅と高さ)を設定する。
setup()
を用いる場合は、この関数内の一番最初に書かなければならない。
また、Processing3からは全画面表示用の fullScreen()
が用意されている。これらはいずれかのみ指定可能。
リファレンス: size()
リファレンス: fullScreen()
loop() と noLoop()
void setup() {
size(200, 200);
noLoop(); // draw() をループさせない
}
float x = 0;
void draw() {
background(204);
x = x + .1;
if (x > width) {
x = 0;
}
line(x, 0, x, height);
}
void mousePressed() {
loop(); // マウス押し込みで draw() をループ
}
void mouseReleased() {
noLoop(); // マウスをリリースで draw() を非ループ
}
draw()
のループは、loop()
と noLoop()
を使って初期化時、また(イベントハンドラなどを使って)実行時に制御できる。
色の設定
色モデル
RGB色モデルとHSB色モデルが用意されている2。これを colorModel()
で初期化する。
color型とcolor()
color型が定義されていて、色情報を変数として持てる。定義する場合には、CSS方式の#RRGGBB
で代入するか、組み込み関数 color()
を用いる。
color col1 = #FF8800; // オレンジ
color col2 = color(255,0,0); // 赤
color col3 = color(255,0,0,128); // 半透明の赤
background(col1);
リファレンス: color型
リファレンス: color()
背景色の設定
background()
によって設定する。setup()
の中で初期配色として設定ができ、また、draw()
の中でフレーム毎に呼ぶことも可能。
int r=0, g=0, b=0;
void setup() {
size(200, 200);
background(color(r,g,b));
}
void draw() {
r = (r+1) & 255;
g = (g+2) & 255;
b = (b-3) & 255;
background(color(r,g,b));
}
色と線の太さの設定
stroke(color(0,0,255)); // 線の色
strokeWeight(4); // 線の太さ(pixel)
fill(color(128,128,255)); // 塗りつぶし色
rect(20, 20, 60, 60);
線や矩形、円などの外郭の線の色を stroke()
で設定する。 noStroke()
で線なし指定も可能。
線の太さは、 strokeWeight()
で設定する。デフォルトは 1
である。
塗りつぶし色は、 fill()
で設定する。 noFill()
で塗りつぶしなし指定も可能。
リファレンス: stroke()
リファレンス: strokeWeight()
リファレンス: fill()
画像の描画
display windowへ図形を描画する。便利なことに、2D座標系と3D座標系の2つの座標系に対応している。
点を打つ: point()
2D、3Dのどちらの座標系でも利用可能。
void setup() {
size(200, 200);
background(255);
}
void draw() {
float x = random(0, width); // width はシステム変数でdisplay windowの幅
float y = random(0, height); // height もシステム変数でdisplay windowの高さ
int col = int(random(0,255));
stroke(col);
strokeWeight(2);
point(x,y);
}
線を引く: line()
2D、3Dのどちらの座標系でも利用可能。
int r1=0, g1=0, b1=255;
int r2=0, g2=255, b2=0;
size(200, 200);
background(0);
for ( int i=0; i<width; i= i+10 ){
stroke(color(r1,g1,b1));
line(0, i, i, height);
g1 += 20;
stroke(color(r2,g2,b2));
line(i,0,width,i);
b2 += 20;
}
四角形を描く: rect()
2D座標系で使う。line()
と違って、第3、第4引数は、座標ではなく幅と高さなので注意。
第5引数を与えることで、角を丸めることもできる。
boolean is_opening = true;
int win_height = 0;
int WIN_HEIGHT_MAX = 10;
void setup() {
size(320,240);
stroke(color(255,255,255));
strokeWeight(3);
fill(0,0,255);
}
void draw() {
if ( is_opening ){
if ( win_height < WIN_HEIGHT_MAX ){
clear();
rect(20,20,280,20*win_height++,8);
} else {
is_opening = false;
noLoop();
}
} else {
if ( win_height >= 0 ){
background(0);
rect(20,20,280,20*win_height--,8);
} else {
is_opening = true;
clear();
noLoop();
}
}
}
void mousePressed() {
loop();
}
円・楕円を描く: ellipse()
2D座標系で利用可能。
int t=0;
void setup() {
frameRate(30);
size(200,200);
background(0);
}
void draw() {
clear();
float y = 50+pow(t-10,2);
float w = 100+pow(t-10,2);
t = (t < 20)? (t+1): 0;
put_circle(y,w);
}
/*
* 自前な関数(サブルーチン)
*/
void put_circle(float y, float w){
color col = color((255-t*10)&255,0,0);
ellipse(100,y,w,100);
}
文字を描く: text()
2D、3Dのどちらの座標系でも利用可能。
size(300,200);
textSize(32); // pixcel
fill(0, 128, 128);
text("Hello, World!", 20, 30);