Processingウォーミングアップ
以前の実験(グラフィックス基礎)でProcessingの使い方は一通り学んでいると思うが, ここでは必要なAPIを振り返っておこう.
本実験で使用する基本的なAPI
完全なAPIのリストは以下を参照せよ.
Language Reference (API) \ Processing 2+
ここでは本実験で主に使用するAPIを紹介する.
setupメソッド
void setup()
このメソッドはProcessingの描画処理のエントリーポイント(処理の開始点)となるメソッドである. 上記のシグネチャで自分で定義する必要がある.
このメソッドは実行を開始したときに一度だけ呼ばれるため,さまざまなリソースの初期化処理の ために使うのが一般的である.
drawメソッド
void draw()
このメソッドはProcessingの描画処理メソッドである. 上記のシグネチャで自分で定義する必要がある.
初期設定ではdraw
は,プログラムが終了するまで繰り返し呼び出されるため,
このメソッドをうまく使用してアニメーションを実装することも可能である.
本実験では描画処理は一度しか行う必要がないため,setup
メソッド内で
後述するnoLoop
メソッドを呼び出して連続的な描画を抑止する.
loop
,noLoop
メソッド
void loop(); void noLoop();
Processingはデフォルトでは、draw
メソッドの処理を繰り返し呼び出す.
loop
,noLoop
メソッドはこの繰り返し動作の設定を変更するメソッドである.
noLoop
メソッドを呼び出すと,Processingの繰り返し描画を抑止する.前述のように,
本実験では繰り返し描画は不要であるためsetup
メソッド内でnoLoop
メソッドを一度だけ
呼び出す必要がある.
loop
メソッドは,noLoop
メソッドで抑止された繰り返し描画を再開するメソッドであるが,
本実験では使用しない.
sizeメソッド
void size(int w, int h)
このメソッドは描画を行う画面のサイズを指定するメソッドである.
通常はsetup
メソッドの最初に一度だけ使用する.
- 引数:
w
: 画面の幅h
: 画面の高さ
このメソッドで指定した画面の幅と高さは後述するグローバル変数width
, height
で
参照することができる.
backgroundメソッド
void background(color c)
background
メソッドは画像の背景色を指定する.描画処理を行っていない部分は
このメソッドに指定した色で塗りつぶされる.色の指定の仕方は後述する.
width,height変数
int width; // 画面の幅 int height; // 画面の高さ
size
メソッドで設定された画面の幅と高さを取得することができるグローバル変数である.
fill,noFill, stroke, noStrokeメソッド
void fill(color c); void noFill(); void stroke(color c); void noStroke();
これらのメソッドは直接何かを描画するメソッドではなく,後述する基本的な 図形を描画するメソッドの描画設定を恒久的に変更するメソッドである.
fill
メソッドは図形の内側を塗りつぶす色を設定する.noFill
メソッドを呼び出すと図形内の塗りつぶさないように設定される.
stroke
メソッドは図形のふちの線の色を設定する.noStroke
メソッドはを呼び出すと縁の線を描画しないように設定される.
color型,colorメソッド
color color(int r, int g, int b);
color
型は色を表すデータ型であるがint
の別名でもある.色の指定方法は二種類ある.
color c1 = #FF0000; // 赤 color c2 = color(255, 0, 0); // これも赤
上記のように#
に続いて6桁の16進数を指定する方法とcolor
メソッドで指定する二種類の方法がある.
pointメソッド
point(int x, int y)
x
,y
で指定した座標の画素をstroke
メソッドで指定した色に設定する.
print, printlnメソッド
void print(String msg); void println(String msg);
print
メソッド,println
メソッドはコンソールへメッセージを出力するメソッドである.
コンソールとはProcessing IDEの画面下部の領域のことである.
print
メソッドとprintln
メソッドの違いは,println
はメッセージを出力後に改行をすることである.
Processingは基本的にグラフィック出力を行うための環境であるが,テキストベースの メッセージを出力すると便利な場合がある(デバッグなど).
数学関数
一般的な数学関数が使用可能である.
float sqrt(float v); // 平方根 √v float sq(float v); // 平方 v^2 float pow(float v, float n); // 累乗 v^n float abs(float v); // 絶対値 |v|
以下のようなメソッドも使用できる.
float constrain(float v, float vmin, float vmax); // 値の制限 float map(float v, float vmin, float vmax, float tmin, float tmax); // 値のマッピング
constrain
メソッドは,値を一定範囲に制限するメソッドである.v
がvmin
未満の場合は
vmin
を返し,v
がvmax
より大きい場合はvmax
を返す.それ以外の場合は,v
そのものを返す.
つまり以下のような動作をする.
たとえばconstrain(-1, 0, 10)
は0
を返す.
map
メソッドは値の範囲を変換するメソッドである.v
の値が$$[v_{min},v_{max}]$$の
範囲であるとして,その値を$$[t_{min},t_{max}]$$の範囲の値に変換する.
つまり以下のような動作をする.
たとえばmap(5, 0, 10, 0, 1)
は0.5
を返す.
saveメソッド
void save(string filename);
save
メソッドは現在の画面を,画像ファイルとして保存するメソッドである.
さあ,はじめよう
本節では,Processingでスケッチ(≒プログラム)を作成する基本的なウォークスルーを示す.
スケッチの作成
A.1) デスクトップの画面左下のスタートメニューをクリックする.
A.2) スタートメニューが開いている状態でキーボードでprocessing
と入力する.
アプリケーションが検索される.演習室のPCには複数のバージョンのProcessingがインストールされているが,ここではProcessing-3.0.*を起動する.
A.3) 下図のようなスプラッシュスクリーンが表示され(バージョンによって多少見た目が違うかも知れない),すぐに表示が消える.
A.4) 下図のような空のスケッチが作成される.
A.5) 空のスケッチを作成したら最初に保存しよう.ファイル
メニューの保存
をクリックする.
A.6) 以下のようなダイアログが表示されるので,適当に名前を変えて保存する(デフォルトのままでもよい).
A.7) 空の画面を作成してみよう.スケッチに以下のように描き込む.
void setup() { size(512, 512); background(color(0,0,0)); }
Processing-3ではプログラムを記述しているときにリアルタイムで文法チェックが 行われるため,入力中は以下のようにエラーメッセージ(コンソールの上の赤色部分)が 表示されることがあるが,特に気にする必要はない.
ただし,完全に入力し終わった後にもこのようなエラーメッセージが表示されている場合は 入力したものに本当に誤りが含まれている可能性がある.ソースコード中の赤い波線がひかれた部分 およびその周辺をよく見なおしてみよう.
A.8) 入力が終わったらを押してみよう.
ちなみに,Ctrl+Rキー(コントロールキーを押しながらRキー)を押しても実行することができる.
初回起動時は以下のようなダイアログが表示されるかも知れない.このダイアログが表示された場合はキャンセルボタンを押すこと.
以上が基本的なスケッチの作成方法である.
フォントの設定
Processingはデフォルトでは日本語を表示できない. たとえばスケッチに以下のように書き込んだ場合,
void setup() { // ここは日本語である }
以下のように表示されてしまい,読むことができない.
コメントだけでも日本語を使いたい場合があるかもしれない.その場合は,Processingの 表示に使うフォントの設定を変更する.この作業は一度だけでよい.
M.1) ファイル
メニューの設定
をクリックする.
M.2) 以下のような画面が表示される.
M.3) エディターとコンソールのフォント
を日本語表示可能なものに変更し,複雑なテキスト入力を有効にする
にチェックを入れる.
ソースコードの表示などには等幅フォントを使用するといいだろう.下記の例ではMS ゴシックを指定して
フォントサイズを14
に設定している.
M.4) この状態で一度Processingを再起動すると,日本語が表示できるようになる.
ただしコメント以外では日本語を使うことができないということを覚えておこう.
全ての画素を処理する
画面の全ての画素を一つずつ処理してみよう.このような処理をラスタースキャンという. 以下の手順に沿って進めよ.
B.1) スケッチを以下のように書き換える(まだ実行はしない).
void setup() { size(512, 512); background(color(0,0,0)); noSmooth(); // 描画のスムージングを行わない noLoop(); // 連続的な描画を行わない }
Processingでは,2Dプリミティブ(線や丸など)の描画の際に発生するジャギー(ギザギザ)を
低減するモードがデフォルトで有効になっている.noSmooth
はこのモードを解除するメソッドである.
本実験ではProcessingの2Dプリミティブ描画の機能を使用せず画素を直接制御するため,
このモードを解除しておく必要がある(そうしないと処理速度に影響してしまう).
また,デフォルトではdraw
メソッドは,スケッチが実行中に繰り返し呼び出され続ける.
本実験ではアニメーションを作るような部分はないため,noLoop
メソッドでそれを抑止している.
B.2) B.1で追記したコードにdraw
メソッドを追加する(まだ実行はしない).
void setup() { size(512, 512); background(color(0,0,0)); noSmooth(); noLoop(); } void draw() // 追加 { }
B.3) B.2で追記したdraw
メソッドのあとに,以下のように二重ループを追加する(まだ実行はしない).
void setup() { size(512, 512); background(color(0,0,0)); noSmooth(); noLoop(); } void draw() { // 二重ループ for(int y = 0; y < height; ++y) { for(int x = 0; x < width; ++x) { } } }
まだループの中には何も書いていないが,このループによって画像の左上から右下に向かって
すべての座標を反復することができる.
コンピュータグラフィックスの分野では,習慣的にこのような順序で処理する場合が多い.
(画像データのメモリ上の格納方法などに由来するがここでは割愛する.)
B.4) B.3の二重ループの中に以下のように処理を追加する(まだ実行はしない).
void setup() { size(512, 512); background(color(0,0,0)); noSmooth(); noLoop(); } void draw() { // 二重ループ for(int y = 0; y < height; ++y) { for(int x = 0; x < width; ++x) { stroke(color(255, 0, 0)); // 色を設定 point(x, y); // 座標(x,y)の画素をストロークの色で塗る } } }
point
メソッドは指定した座標の画素をstroke
で塗りつぶすメソッドである.
この例では画像全域を塗りつぶすのでstroke
は一度呼び出せば事足りるが,後の拡張のため
ループ内で描画色の設定を逐一行うようになっている.
B.5) を押してみよう.
このスケッチが本実験の全てのスケッチの基本形となる.各行の処理をきちんと理解しておこう.
以上で基本的なウォークスルーは終了である.
課題
課題1-1 塗りつぶし(復習)
(作業時間目安:5分)
幅512,高さ512の画像を生成するスケッチを作成せよ.
画素値は全て$$(r,g,b)=(255,127,64)$$で塗りつぶすこと.
スケッチはFillという名前で保存すること.
以下のプログラムを穴埋めせよ.
void setup() { size(512, 512); background(color(0,0,0)); noSmooth(); noLoop(); } void draw() { for(int y = 0; y < height; ++y) { for(int x = 0; x < width; ++x) { /* 穴埋め1 */; /* 穴埋め2 */; } } }
生成画像は図1のようになる.
図1. スケッチFillの生成画像
課題1-2 単純なグラデーション
(作業時間目安:5分)
幅512,高さ512の画像を生成するスケッチを作成せよ.
この画像はX方向に従って黒から白へのグラデーションをもつ.
スケッチはGradation1という名前で保存すること.
生成画像は図2のようになる.
図2. Gradation1の生成画像
ヒント1
ヒント:座標値の範囲[0,512)を,一端[0.0,1.0]にマップする.
ヒント2
void setup() { size(512, 512); background(color(0,0,0)); noSmooth(); noLoop(); } void draw() { for(int y = 0; y < height; ++y) { for(int x = 0; x < width; ++x) { float fx = /* 穴埋め */; int gray = (int)(255 * fx); stroke(gray); point(x, y); } } }
課題1-3 RGBチャネルごとのグラデーション
(作業時間目安:10分)
幅512,高さ512のPPM形式の画像を生成するスケッチを作成せよ.
スケッチはGradation2という名前で保存すること.
この画像はRGBの各チャネルごとに以下のようなグラデーションを持つ.
- Rチャネル:X方向に従って255から0に変化する
- Gチャネル:Y方向に従って0から255に変化する
- Bチャネル:座標(0,0)のとき0,座標(511,511)のとき255となる.
生成画像は図3のようになる.
図3. Gradation2の生成画像
ヒント1
ヒント:BチャネルはX座標とY座標の積
ヒント2
void setup() { size(512, 512); background(color(0,0,0)); noSmooth(); noLoop(); } void draw() { for(int y = 0; y < height; ++y) { float fy = (float)y / (height-1); for(int x = 0; x < width; ++x) { float fx = (float)x / (width-1); int red = /* 穴埋め1 */; int green = /* 穴埋め3 */; int blue = /* 穴埋め2 */; stroke(color(red, green, blue)); point(x, y); } } }
0 Comments.