Processing lesson(8) 大量生産2(for文,配列)

Learning Objectives

Note
教材を使用される方は、“lesson資料のご利用について”のご一読をお願いします。
  • “For文"を使った反復処理を使ってみる
  • “配列"について理解し使ってみる
  • アルゴリズムの重要性について理解する

前回のあらすじ

  • 反復処理(繰り返し)を使いこなすと、少ない記述でたくさんの作業を行うことができる

For文

  • 繰り返しの書き方は"While文"だけではない
  • While文では別々に書いた以下の処理を、For文では一度に書ける
  • ループ変数の初期化
  • 継続条件
  • ループ変数の更新
  • 教材:ZERO-PDE 整列(For文)

反復処理の使いどころ

  • While文、For文の使い方は様々。Processingでは、データを大量に作る、処理する、等間隔に並べる、一定ずつ色調を変える・・など様々な大量データの処理に使われる

配列(大量のデータの置き場所)

  • 配列とは:たくさんの変数が並んだもの
  • 1つずつ"変数"を宣言するのではなく、複数の箱を用意し、メモリの領域を確保するようなイメージ(→「ロッカー」「下駄箱」みたいなもの)

https://1.bp.blogspot.com/-eS3KcRowDS4/Wp94KMHTJFI/AAAAAAABKrI/80uB9dCfgS4ydSt2F2p_UanZDn5tJmnbQCLcBGAs/s800/locker_set_close.png
ラベルがついた一列のロッカー

https://4.bp.blogspot.com/-pY1hVuJ4tF8/WlW0w07PQcI/AAAAAAABJsQ/U1cNMxWNR0UHTc7nm8pTTuZ69ygF7Jm_QCLcBGAs/s180-c/omairi_noukotsudou_locker_open.png
ラベルがついたロッカー(縦横のロッカー)

ラベルは連番になっている。Processingの場合、0番から始まり、(データの個数-1)番で終わる。ラベルの番号のことを配列の"インデックス(添字)“という。

格納するデータのことを配列の"要素"という

../../images/lesson/2020/10/スクリーンショット-2020-10-07-9.35.58.png 1次元のint型の配列


配列はどういう時に便利?

教材: ZERO-PDE 大量生産(配列)の"ランダムウォーク"を参照。ランダムにボールを動かすためには、今の位置をフレームをまたいで"覚えておく"ための変数が必要。

配列を使うことにより、複数のボールのそれぞれの位置をフレームをまたいで"覚えておく"時に有効。
→ xの値を格納するための配列、yの値を格納するための配列をそれぞれデータの個数の要素で用意する。


例1: ランダムに動き回るボール

// ランダムに歩き回るエージェントが複数体
// (配列・for文を使って効率化)
// エージェントの位置を覚えておくための変数
float[] ballXs; // 配列名"ballXsの宣言
float[] ballYs; // 配列名 ballYsの宣言
void setup() {
  size(600, 600);
  noStroke();
  fill(0, 0, 0);
  // 配列の個数を決めて生成
  ballXs = new float[1000];
  ballYs = new float[1000];
  for (int i = 0; i < 1000; i++) {
    // i 番目のエージェントの変数の初期値(開始時の位置)をキャンバス中央に  設定
  ballXs[i] = width / 2;
  ballYs[i] = height / 2;
  }
}
void draw() {
  background(255, 255, 255);
  for (int i = 0; i < 1000; i++) {
    // i 番目のエージェントの位置をランダムにずらす
    ballXs[i] += random(-10, 10);
    ballYs[i] += random(-10, 10);
  }
  for (int i = 0; i < 1000; i++) {
    // i 番目のエージェントを描く
    ellipse(ballXs[i], ballYs[i], 30, 30);
  }
}

例2. アンパンマンと1%のばいきんまん(変数、配列、条件分岐、繰り返し)

上のプログラムのボールの描画の箇所を画像の読み込み処理に変更し、かつ確率の制御で判定すると・・

../../images/lesson/2020/10/Anpanman_baikinman.gif

PImage anpanman;
PImage baikinman;
float[] ballX;float[] ballY;
int maxAnpanman = 50;
void setup(){
  anpanman = loadImage("Anpanman.png");
  baikinman = loadImage("Baikinman.png");
  size(1000, 1000);
  background(255);
  fill(0);
  ballX = new float[maxAnpanman];
  ballY = new float[maxAnpanman];
  int i = 0;
  while(i<maxAnpanman){
    ballX[i]=width/2;
    ballY[i]=height/2;
    i=i+1;
  }
}

void draw(){
  background(255);
  int i = 0;
  while (i<maxAnpanman){
    ballX[i] += random(-40,40);
    ballY[i] += random(-40,40);
    if(random(maxAnpanman)/maxAnpanman<0.01){
      image(baikinman, ballX[i], ballY[i]);
    } else {
      image(anpanman, ballX[i], ballY[i]);
    }
    i=i+1;
  }
}