Chapter2. Processingウォーミングアップ

Processingウォーミングアップ

以前の実験(グラフィックス基礎)でProcessingの使い方は一通り学んでいると思うが, ここでは必要なAPIを振り返っておこう.

本実験で使用する基本的なAPI

完全なAPIのリストは以下を参照せよ.
Language Reference (API) \ Processing 2+

ここでは本実験で主に使用するAPIを紹介する.

setupメソッド

シグネチャ:
void setup()

このメソッドはProcessingの描画処理のエントリーポイント(処理の開始点)となるメソッドである. 上記のシグネチャで自分で定義する必要がある.

このメソッドは実行を開始したときに一度だけ呼ばれるため,さまざまなリソースの初期化処理の ために使うのが一般的である.

drawメソッド

シグネチャ:
void draw()

このメソッドはProcessingの描画処理メソッドである. 上記のシグネチャで自分で定義する必要がある.

初期設定ではdrawは,プログラムが終了するまで繰り返し呼び出されるため, このメソッドをうまく使用してアニメーションを実装することも可能である.

本実験では描画処理は一度しか行う必要がないため,setupメソッド内で 後述するnoLoopメソッドを呼び出して連続的な描画を抑止する.

loopnoLoopメソッド

シグネチャ:
void loop();
void noLoop();

Processingはデフォルトでは、drawメソッドの処理を繰り返し呼び出す. loopnoLoopメソッドはこの繰り返し動作の設定を変更するメソッドである.

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メソッドは,値を一定範囲に制限するメソッドである.vvmin未満の場合は vminを返し,vvmaxより大きい場合はvmaxを返す.それ以外の場合は,vそのものを返す. つまり以下のような動作をする.

\( {\rm constrain}(v,v_{min},v_{max})=\left\{\begin{array} \\ v_{min} & ({\rm when}\ v \lt v_{min}) \\ v & ({\rm when}\ v_{min} \leq v \leq v_{max}) \\ v_{max} & ({\rm when}\ v_{max} \lt v) \\ \end{array}\right. \\ \)

たとえばconstrain(-1, 0, 10)0を返す.

mapメソッドは値の範囲を変換するメソッドである.vの値が$$[v_{min},v_{max}]$$の 範囲であるとして,その値を$$[t_{min},t_{max}]$$の範囲の値に変換する. つまり以下のような動作をする.

\( {\rm map}(v,v_{min},v_{max},t_{min},t_{max})=t_{min}+(t_{max} – t_{min})\times\frac{{\rm constrain}(v,v_{min},v_{max})}{v_{max}-v_{min}} \\ \)

たとえば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という名前で保存すること.

以下のプログラムを穴埋めせよ.

リスト1. スケッチ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のようになる.

fill.cの生成画像
図1. スケッチFillの生成画像

課題1-2 単純なグラデーション

(作業時間目安:5分)

幅512,高さ512の画像を生成するスケッチを作成せよ.
この画像はX方向に従って黒から白へのグラデーションをもつ.

スケッチはGradation1という名前で保存すること.

生成画像は図2のようになる.

gradation1.cの生成画像
図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のようになる.

gradation2.cの生成画像
図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);
    }
  }
}
-クリックで非表示

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>