4.3 配列

Filed in processing , メディアプログラミング演習II , 制作応用演習(グラフィカルプログラミング演習) 0 comments

さて、次は配列です。配列の英語名は“array”と言い、「整列」という意味があります。プログラミングの世界では、「変数のグループ」のことだと理解しておきましょう。
この配列は非常に便利な機能なのですが、つまずきやすいポイントでもあるようです。ある意味ここは正念場なので、まずは「概念を理解する」ことが大事になります。

4.3.1 1次元配列

まずは、配列が一体どういったものかを見てみましょう。この概念が理解できると使い方も自然に分かると思います。次の式を見てください。

1
2
3
4
5
6
int[] a = new int[3];    //int型の配列a(箱は3つ)を設定
 
a[0] = 1;    //a[0]に1を代入
a[1] = 10;    //a[1]に10を代入
a[2] = 4;    //a[2]に4を代入
println(a);    //aの値を下のメッセージウィンドウに出力

配列の宣言部分は次の式になります。int型の配列a(箱は3つ)を設定しています。

int[] a = new int[3];

また、次のようにも書けます。

int[] a = { 1, 10, 4 };

概念的には【図4.3-a】になります。

array1.gif

図4.3-a

このように、変数の箱が並んでいるイメージです。しかし、この箱はひとつひとつ独立しているのではなく、全部くっついています。この[ ]に囲まれた箱の番号をインデックス番号と呼びます。

ここで気をつけなければいけないのは、a[0]のように、インデックス番号は必ず0から始まります。
ですから、箱が3つあったらインデックス番号は0、1、2となります。

しかし、まだこれだけではなぜ配列という機能の存在が必要なのか分かりづらいと思います。そこで、次の式を見てください。

1
2
3
4
5
6
7
int[] a = new int[4];    //int型の配列a(箱は4つ)を設定
 
for(int i=0; i<4; i++) {
 a[i] = i ;    //a[i]にiを代入
}
 
println(a);    //aの値を下のメッセージウィンドウに出力

この式の配列の中身は【図4.3-b】になります。

array2.gif

図4.3-b

この時点で、勘のいい人は分かるかもしれませんが、配列の利点とは、インデックス番号に変数が使えるということなのです。もし配列を使わなければ次のようになります。

1
2
3
4
5
6
7
8
9
10
11
int a0, a1, a2, a3;    //int型の変数を設定
 
a0 = 0;
a1 = 1;
a2 = 2;
a3 = 3;
 
println(a0);
println(a1);
println(a2);
println(a3);

長くなりますよね。配列の箱が4つだったらまだいいようなもの、これが100個になると非常に効率が悪いですよね。
どうですか?配列の便利さが分かってもらえたでしょうか?また、配列の番号に変数が使えるということは様々な計算式が使えるということです。
次のサンプルを見てください。

1
2
3
4
5
6
7
int[] a = new int[4];    //int型の配列a(箱は4つ)を設定
 
for(int i=0; i<4; i++) {
 a[i] = i*2 ;    //a[i]にi*2の値を代入
}
 
println(a);    //aの値を下のメッセージウィンドウに出力

この式の配列の中身は【図4.3-c】になります。

array3.gif

図4.3-c

4.3.2 各オブジェクトの値をコントロールする

配列を使う利点のひとつは、個々のオブジェクトの属性をコントロールできるという点です。次のサンプルは、円の大きさを変化させるプログラムです。

ステップ1
まずはひとつから始めます。円が拡大縮小するアニメーションを作ってみます。

2016_06_21_0_17

図4.3-d
リスト4.3-a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
float eSize;    //円のサイズ
float speed = 0.5;    //円の拡大縮小のスピード
float minSize = 1.0;     //円のサイズの最小値
float maxSize = 200.0;    //円のサイズの最大値
 
void setup() {
  size(400, 400);
  background(255);
  noStroke();
  fill(0);
 
  eSize = minSize;    //円のサイズを最小値に設定
}
 
void draw() {
  background(255);
 
  eSize += speed;    //円のサイズを変化させる
  //もし円のサイズが最大値を超えたか最小値未満になったら
  //speedの増減を反転させる
  if ((eSize > maxSize) || (eSize < minSize))
    speed = -speed;
 
  //円を描く
  ellipse(width/2, height/2, eSize, eSize);
}

ステップ2
次に、ステップ1のコードをもとにして、配列を使わずに3つ表示させてみます。
円が拡大縮小するスピードは、それぞれの円で変えます。その場合、次のように書けるでしょう。

2016_06_21_0_18

図4.3-e
リスト4.3-b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
float eSize0, eSize1, eSize2;    //円のサイズ
//円の拡大縮小のスピード
float speed0 = 0.4, speed1 = 0.5, speed2 = 0.3;
float minSize= 1.0;     //円のサイズの最小値
float maxSize = 100.0;    //円のサイズの最大値
 
void setup() {
  size(400, 400);
  background(255);
  noStroke();
  fill(0);
 
  eSize0 = minSize;    //円のサイズを最小値に設定
  eSize1 = minSize;
  eSize2 = minSize;
}
 
void draw() {
  background(255);
 
  //左の円
  eSize0 += speed0;    //円のサイズを変化させる
  //もし円のサイズが最大値を超えたか最小値未満になったら
  //speedの増減を反転させる
  if ((eSize0 > maxSize) || (eSize0 < minSize))
    speed0 = -speed0;
 
  ellipse(0, height/2, eSize0, eSize0);    
 
  //中央の円
  eSize1 += speed1;
  if ((eSize1 > maxSize) || (eSize1 < minSize))
    speed1 = -speed1;
 
  ellipse(200, height/2, eSize1, eSize1);
 
  //右の円
  eSize2 += speed2;
  if ((eSize2 > maxSize) || (eSize2 < minSize))
    speed2 = -speed2;
 
  ellipse(400, height/2, eSize2, eSize2);
}

ステップ3
それでは、ステップ2のコードに配列を使ったらどうなるのでしょう。かなり短くなります。

リスト4.3-c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
float[] eSize = new float[3];    //円のサイズ
float[] speed = {0.4, 0.5, 0.3};    //円の拡大縮小のスピード
float minSize = 1.0;     //円のサイズの最小値
float maxSize = 100.0;    //円のサイズの最大値
 
void setup() {
  size(400, 400);
  background(255);
  noStroke();
  fill(0);
 
  for (int i = 0; i < 3; i++) {    
    eSize[i] = minSize;    //円のサイズを最小値に設定
  }
}
 
void draw() {
  background(255);
 
  for (int i = 0; i < 3; i ++) {
    eSize[i] += speed[i];    //円のサイズを変化させる
    //もし円のサイズが最大値を超えたか最小値未満になったら
    //speedの増減を反転させる
    if ((eSize[i] > maxSize) || (eSize[i] < minSize))
      speed[i] = -speed[i];
 
    ellipse(200*i, height/2, eSize[i], eSize[i]);    //円を描く
  }
}

どうですか?for文と組み合わせると短くなります。配列3つではあまり差がありませんが、図形が100個などのケースでも、このコードだとそれほど長くなりません。

4.3.3 複数のオブジェトを作る

また、円の大きさの初期値を変えると、連続した形がうねっているような動きを与えることができます。

2016_06_21_0_18

図4.3-f
リスト4.3-d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int num = 10;    //円の数
float[] eSize = new float[10];    //円のサイズ
float[] speed = new float[10];    //円の拡大縮小のスピード
float minSize = 50.0;     //円のサイズの最小値
float maxSize = 150.0;    //円のサイズの最大値
 
void setup() {
  size(550, 200);
  background(255);
  noStroke();
  fill(0, 200);
 
  for (int i = 0; i < num; i++) {    
    eSize[i] = i*5.0 + 50;    //円のサイズの初期値をそれぞれ設定
    speed[i] = 1.0;    //円のスピードの初期値
  }
}
 
void draw() {
  background(255);
 
  for (int i = 0; i < num; i ++) {
    eSize[i] += speed[i];    //円のサイズを変化させる
    //もし円のサイズが最大値を超えたか最小値未満になったら
    //speedの増減を反転させる
    if ((eSize[i] > maxSize) || (eSize[i] < minSize))
      speed[i] = -speed[i];
 
    ellipse(50*i + 50, height/2, eSize[i], eSize[i]);
  }
}

4.3.4 マウスの動きを記録する

配列は、マウスの動きを記録するときにもよく使われます。次のサンプルは、ドラッグをしている間にマウスのx, y座標を配列に保存し、ドラッグが終わったらその配列に格納された座標とサイズに基づいて再生しています。

2016_06_21_0_36

図4.3-g
リスト4.3-e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
float[] x = new float[100];  //円のx座標
float[] y = new float[100];  //円のy座標
float[] eSize = new float[100];  //円のサイズ
int counter = 0;  //配列に値を順番に入れるためのカウンター
boolean mouseFlag = false;  //マウスが押されているかを判定するフラッグ
 
void setup() {
  size(400, 400);
  background(255);
  noStroke();
  fill(0);
 
  //x[]、y[]、eSize[]を初期化
  for (int i = 0; i<x.length; i++) {
    x[i] = y[i] = eSize[i] = 0;
  }
}
 
void draw() {
  background(255);
 
  //軌跡を残す場合は、下の3行をON、backgroundをOFFにする
  /*
  fill(255, 10);  //透明度のあるrectを描画
  rect(0, 0, width, height);
  fill(0);      //オブジェクトは黒
  */
 
  //マウスが押されていなければ描画
  if (!mouseFlag) {
 
    ellipse(x[counter], y[counter], eSize[counter], eSize[counter]);
 
    counter ++;
    if (counter > x.length-1) counter = 0;
  }
}
 
void mousePressed() {
  background(255);
 
  counter = 0;  //マウスが押されたらカウンターを初期化
  mouseFlag = true;  //フラッグをON
}
 
void mouseDragged() {
  x[counter] = mouseX;  //マウスの座標を記録
  y[counter] = mouseY;
 
  //スピードを記録してeSizeにする
  eSize[counter] = dist(mouseX, mouseY, pmouseX, pmouseY)*2;
  counter ++;  //カウンターを加算
 
  //カウンターは配列のインデックス番号の最大値で止まる
  if (counter >= x.length-1) counter = x.length-1;
}
 
void mouseReleased() {
  //カウンター分までは保存して、それ以外は初期化
  for (int i = counter; i < x.length; i ++) {
    x[i] = 0;
    y[i] = 0;
    eSize[i] = 0;
  }  
  mouseFlag = false;  //マウスフラッグはOFF
}
Posted by noguchi   @   17 4月 2007 0 comments

0 Comments

Sorry, comments are closed.

Previous Post
«
Next Post
»
Stroom designed by Credit Cards In conjunction with Web Hosting Reseller , Dream Interpretation Guide , Best Website Hosting.