« Processingであの花ED風-花クラス解説 | Main | 今の僕の自転車感 »

Processingであの花ED風-メインルーチン解説

前々回のソースコードの解説です。

前回の花クラスの解説に続いて、今回は、"メインルーチン"の解説です。ソースコード全体は前々回を参照してください。花クラスの解説はこちら

メインルーチン

変数定義
ArrayList<Flower> flowers = new ArrayList<Flower>();  //「花」を管理する配列

int fRate = 30;  // フレームレート

float zoomRange = 0;  //ズームする割合
float zoomRate = 0;  //1フレームあたりのズーム量
int zoomCount = 0;  //ズームにかけるフレーム数

float eyeX = 0;  //カメラ位置 X座標
float eyeY = 0;  //カメラ位置 Y座標
float eyeZ = 0;  //カメラ位置 Z座標
float centerX = 0;  //カメラ視点 X座標
float centerY = 0;  //カメラ視点 Y座標
float centerZ = 0;  //カメラ視点 Z座標

boolean isColor = false//カラーモードフラグ

…コメントの通りです。それぞれの変数は、順次登場すると思います。

初期設定
//初期設定
void setup() {
  //画面設定
  size(1200, 800, P3D);
  frameRate(fRate);
  colorMode(HSB, 100);

sizeは、画面のサイズを指定しています。3つ目の引数"P3D"は、画面を3次元空間として扱うことを宣言しています。これにより、カメラを3次元的に配置し、そこから見える範囲を表示するということができるようになります。後述のズームの再現でこの設定が発揮されます。

frameRateは、1秒間のフレーム数…つまりコマ数を設定します。大量の描画と動きの滑らかさのバランスを考えて、1秒間に30フレームに設定しました。固定値でもいいのですが、ズームにかける時間の計算などに使いたかったので、変数として用意しました。PCの性能に余裕がある場合は、増やしていいかもしれません。

colorModeは、色の表現方法を指定しています。通常はRGB(赤、緑、青のそれぞれの明るさで色を表現)ですが、この場合は、色相を一定範囲内でランダムに設定しやすいようHSB(色相、彩度、明るさ)で設定することにします。第2引数の100は、色相、彩度、明るさのそれぞれの最大値を100として設定すること意味します。明るさであれば100が最も明るく、0なら真っ暗ということになります。

カメラ設定
  //カメラ設定
  zoomRange = height * 0.2;
  eyeX = width/2.0;
  eyeY = height/2.0;
  eyeZ = (height/2.0) / tan(PI*30.0 / 180.0);
  eyeZ -= zoomRange;
  centerX = width/2.0;
  centerY = height/2.0;
  camera(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, 0, 1, 0);

zoomRangeは、画面がズームする量です。試行錯誤の結果、画面高さの20%としました。

カメラは画面の真ん中からZ軸上に設定し、途中のズームではカメラがZ軸上を移動することによって実現します。

Hana_4

exeZは、視野角(視野の中心から最大限見える範囲までの角度)が30度であることから、見せたい範囲の短辺(この場合、height)を基準に三角関数で算出しています。計算式は、Processingのレファレンスにあるデフォルト値の計算方法を引用しています。カメラは初期状態でスクリーンに寄った状態で始まるので、eyeZからズーム量を引いてあります。

プログラムが動いている間、カメラ位置のXY座標とカメラ視点のXYZ座標は変わらないため、最初の1回だけ計算して変数に保持しておくことで、実行中の負荷を軽減しています。

花生成
  //「花」生成 小さい方(奥)から大きい方(手前)の順に
  for (int i = 0; i < 1000; i++) {
    flowers.add(new Flower("fl24.png", 1, 1));
  }
  for (int i = 0; i < 400; i++) {
    flowers.add(new Flower("fl32.png", 1, 1));
  }
  for (int i = 0; i < 80; i++) {
    flowers.add(new Flower("fl64.png", 1.5, 2));
  }
  for (int i = 0; i < 20; i++) {
    flowers.add(new Flower("fl128.png", 2, 2));
  }
  for (int i = 0; i < 4; i++) {
    flowers.add(new Flower("fl256.png", 3, 3));
  }
}

画面に描画する画像は、色を付ける部分を白に設定した透過画像(下図の黒い部分は実際には透明に設定しています)を、試行錯誤の結果、サイズ違いで5種類(24px、32px、64px、128px、256px)用意しました。この画像をを小さいほうから順に、生成する数を変えながら設定しています。

Photo_2

ファイルは透過指定が可能で軽量なpng形式です。表現上一番奥(24px)用は強めに、手前(128px、256px)は軽くぼかしがついています。ぼかしを付けたのは、明るい背景に表示したときに、画像の境界が目立ってしまったためです。色を付ける方法は、花クラスで説明します。

描画
//描画
void draw() { 
  //背景塗りつぶし
  background(98);

drawメソッドは、フレームを描画するごとに呼び出されます。まずは前回の描画内容を削除するために、背景をグレースケールで"ほとんど白"に塗りつぶしています。

「花」描画(通常の描画)
  //「花」描画
  if (zoomCount == 0) {
    //ズーム指定がない場合は、「花」をアニメーション描画
    for (Flower f : flowers) {
      f.run();
    }
  }

後述しますが、ズーム中はzoomCountが0以上になります。ズーム中以外では、すべての花に対し、新しい位置を計算して描画するrunメソッドを実行します。

「花」描画つづき(ズームして描画)
  else {
    //ズーム指定がある場合は、カメラを操作
    eyeZ += zoomRate;
    camera(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, 0, 1, 0);
    //「花」は現在の位置で再描画
    for (Flower f : flowers) {
      f.draw();
    }

ズーム中はカメラ位置のZ座標(eyeZ)に1フレームあたりのズーム量を加算します。カメラの位置が決まったら、すべての花に対し、現在の位置で描画するdrawメソッドを実行します。

「花」描画つづき(ズームが終わった時の描画)
    zoomCount -= 1;
    if (zoomCount == 0) {
      //ズームが終わったら、カラーモードを変更
      for (Flower f : flowers) {
        f.changeColor();
      }
      isColor = !isColor;
    }
  }

前項の処理の後、1フレーム分の処理が終わったので、ズームにかけるフレーム数(zoomCount)を1つ減らします。減らした後にもし、ズームにかけるフレーム数が0になったら、すべての花に対し、色を変えるchangeColorメソッドを実行します。

色が変わったことを覚えておくために、カラーモードフラグ(isColor)を反転します。カラーモードフラグはboolean型なので、カラーモードフラグ自信を否定"!"することでtrueはfalseに、falseはtrueになります。

「花」描画つづき(フレーム出力)
  //↓アニメーション用のフレーム画像を出力する場合はコメント解除 
  //saveFrame("frames/####.tif");
}

コメントの通りです。前々回の動画はここで出力したフレームごとの画像をもとに作成しています。1200x800の画面だと、TIFF画像1枚が約2.7MBでした。保存スピードが遅いドライブだとかなりカクカクしてしまいます。なお、フレームは必ず描画し、保存してから次のフレームを描画するので、コマとびの心配はありません。

マウスクリックイベントハンドラ
//マウスクリックイベントハンドラ
void mouseClicked() {
  //ズームにかけるフレーム数を設定する
  zoomCount = (int)(fRate * 1.2);
  if (isColor) {
    //カラー表示の場合はズームイン
    zoomRate = -zoomRange / zoomCount;
  }
  else {
    //モノクロ表示の場合はズームアウト
    zoomRate = zoomRange / zoomCount;
  }
}

ここではズームにかけるフレーム数…つまり、ズーム操作を何フレームにするかを計算して、さらに1フレームあたりのズーム量(zoomRange)をズームする量(zoomRange)とズームにかけるフレーム数(zoomCount)から割り出しています。

ズームする量は、初期設定で画面高さ(height)の20%と設定しました。ズームにかけるフレーム数はフレームレート(1秒当たりのフレーム数)×秒数です。ここでは1.2秒にしましたが大体です。

ここでカラーモードフラグが大事になってきます。カラーモードの場合はズームイン、モノクロモードの場合はズームアウトするように計算しています。

以上、メインルーチンの解説でした。

|

« Processingであの花ED風-花クラス解説 | Main | 今の僕の自転車感 »

Processing」カテゴリの記事

プログラミング」カテゴリの記事

Comments

Post a comment



(Not displayed with comment.)




« Processingであの花ED風-花クラス解説 | Main | 今の僕の自転車感 »