SSAW08 後期第2回

Programming
with proce55ing
2008年9月16日
本日授業の内容

• Processingを題材に、プログラムの基本、約束事を確認


 •   コード構造
 •   変数
 •   データ型
 •   演算
 •   判定
 •   条件分岐
 •   論理式
 •   反復
 •   関数
 •   クラス
 •   オブジェクト
Processingの文法の基本

• Processingの文法は、とてもシンプル!


 // 320x240のウィンドウを生成


 size(320, 240);
 background(0);
Processingの文法の基本

• Processingの文法は、とてもシンプル!


 // 320x240のウィンドウを生成 →コメント


 size(320, 240);
 background(0);
Processingの文法の基本

• Processingの文法は、とてもシンプル!


 // 320x240のウィンドウを生成 →コメント
↓関数(Function)
 size(320, 240);
 background(0);
Processingの文法の基本

• Processingの文法は、とてもシンプル!


 // 320x240のウィンドウを生成 →コメント
↓関数(Function)
 size(320, 240); →命令の終端
 background(0);
Processingの文法の基本

• Processingの文法は、とてもシンプル!


 // 320x240のウィンドウを生成 →コメント
↓関数(Function)
 size(320, 240); →命令の終端
 background(0);
↑命令(Statement)
Processingの文法の基本

• Processingの文法は、とてもシンプル!


 // 320x240のウィンドウを生成 →コメント
↓関数(Function)
 size(320, 240); →命令の終端
 background(0);
             →引数(パラメータ)
↑命令(Statement)
Processingの文法の基本


  /*
 ちなみに、複数行にわたる
 長いコメントを記入したい場合には、
 このように記述します。
 */
Processingの文法の基本


  // size関数は2つのパラメータをもつ
// 最初の値は表示されるウィンドウの幅を
// 2つめの値は高さをあらわしている
size(200, 200);

// (この場合の)background関数は、1つのパラメータをもつ
// その値はグレースケールでの背景色の濃さ(0 ∼ 255)
// を意味している
background(102);
Processingの文法の基本


  //プログラムは(基本的には)上から下に向かって実行される


size(200, 200); // size()関数を実行
int x; // 新規に変数xを宣言
x = 102; // 変数xに、値102を代入
background(x); // xの値を引数にbackground()関数を実行
Processingの文法の基本


   //大文字と小文字は区別されるので注意!
size(200, 200); // OK
Size(200, 200); // NG → Sが大文字


//processingの関数名は全て小文字から始まります
size(400, 200);
background(64);

//2つ以上の単語からなる関数名は、
//最初の文字が小文字、2つめ以降の単語の先頭が大文字になります
noFill();
ellipseMode();
Processingの文法の基本


   //単語の合間に半角スペースを入れてもかまわない


size(200,200); // OK
size(200, 200); // OK
    size(200, 200); // OK
size(       200,            200); // OK

//単語の中にスペースを入れるのは駄目
s ize(200, 200); // NG
簡単な図形を描いてみる

• 簡単な図形を描きながら、Processingのコツをつかむ
• 単純なサンプルから徐々に構造化されたものへと進化します


• キーワード:
  • 座標系
  • 基本図形
    • point(), line(), triangle(), rect(), quad(), ellipse(), bezier()
  • 描画属性
    • stroke(), fill(), noFill(), noStroke(),
    • strokeWeight(), strokeCap(), strokeJoin()
  • 描画モード
    • smooth(), noSmooth(), ellipseMode(), rectMode()
  • 描画順序
Processingの座標系


  //size()のパラメータをいろいろ変えてみる
//その法則は?
size(200, 200);
size(640, 480);
size(10, 600);
size(800, 20);
Processingの座標系

• 左上が原点 (0, 0)            x
• 横にx軸
                 y    0       50   100   150   200
• 縦にy軸



                      50


                     100


                     150


                     200
基本図形の描画
点 - point()

   //point() - 点を描く
point(20,   20);
point(30,   30);
point(40,   40);
point(50,   50);
point(60,   60);
基本図形の描画
線 - line()

   // 線を描く
line(40, 10, 40, 90);
line(50, 10, 50, 90);
line(60, 10, 60, 90);
基本図形の描画
三角形 - triangle()

   //三角形
triangle(60, 10, 25, 60, 75, 65);
triangle(65, 60, 10, 25, 60, 75);
基本図形の描画
四角形1 - quad

   //四角形
quad(20, 20, 20, 70, 60, 90, 60, 40);
quad(20, 20, 70, -20, 110, 0, 60, 40);
基本図形の描画
四角形2 - rect()

   //四角形
rect(15, 15, 40, 40);
rect(55, 55, 25, 25);
基本図形の描画
円 - ellipse()

   //円
ellipse(35, 0, 120, 120);
ellipse(38, 62, 6, 6);
ellipse(40, 100, 70, 70);
基本図形の描画
ベジェ曲線 - bezier

   //ベジェ曲線
bezier(85, 20, 40, 10, 60, 90, 15, 80);

//補助線
line(85, 20, 40, 10);
ellipse(40, 10, 4, 4);
line(60, 90, 15, 80);
ellipse(60, 90, 4, 4);
描画の順序

• プログラムの原則:上から下に実行される
• Processingの描画も上から下に
• 後から実行された図形は上にくる
描画の順序


   rect(15, 15, 50, 50); // 下
ellipse(60, 60, 55, 55); // 上
描画属性
背景色 - background()

   //背景色
//グレースケールの値:黒 = 0 ∼ 白 = 255
background(124);
描画属性
塗りの色:fill()

   background(127);

fill(255);
rect(10, 10,   50, 50);
fill(204);
rect(20, 20,   50, 50);
fill(153);
rect(30, 30,   50, 50);
fill(102);
rect(40, 40,   50, 50);
描画属性
塗り潰しなし - noFill()

   rect(10, 10, 50, 50);

noFill(); // ここから先、塗りなし
rect(20, 20, 50, 50);
rect(30, 30, 50, 50);
描画属性
線なし - noStroke

   rect(20, 15, 20, 70);

noStroke(); // ここから先、線なし
rect(50, 15, 20, 70);
rect(80, 15, 20, 70
描画属性
描画のなめらかさ - smooth(), noSmooth()

   //なめらかに
smooth();
ellipse(30, 48, 36, 36);

//ギザギザに
noSmooth();
ellipse(70, 48, 36, 36);
描画属性
線の太さ - strokeWeight()

   smooth();

line(20, 20, 80, 20);

strokeWeight(6);
line(20, 40, 80, 40);

strokeWeight(18);
line(20, 70, 80, 70);
描画モード
円の描画モード:ellipseMode()

   smooth();
noStroke();

ellipseMode(RADIUS);
fill(126);
ellipse(33, 33, 60, 60);

ellipseMode(CORNER);
fill(255);
ellipse(33, 33, 60, 60);

ellipseMode(CORNERS);
fill(0);
ellipse(33, 33, 60, 60);
描画モード
四角形の描画モード:rectMode()

   noStroke();

rectMode(CORNER);
fill(126);
rect(40, 40, 60, 60);

rectMode(CENTER);
fill(255);
rect(40, 40, 60, 60);

rectMode(CORNERS);
fill(0);
rect(40, 40, 60, 60);
変数 (Variables)

 • 変数とは?
   • データを一時的に記憶しておく領域
   • 箱のイメージ
   • 記憶可能なデータの内容:整数、実数、真偽、色 ...etc.
変数 (Variables)

 • データ形式


名前         サイズ     値の範囲

boolean    1bit    true (真) または false (偽)

byte       8bit    -128 ∼ 127

char       16bit   0 ∼ 65535

int        32bit   -2,147,483,468 ∼ 2,147,483,467

float       32bit   3.40282347E+38 ∼ -3.40282347E+38

color      32bit   16,177,216色
変数の宣言


   int x;
float y;
boolean b;
x = 50;
y = 12.6;
b = true;

int x = 50;
float y = 12.6;
boolean b = true;

float x, y, z;
x = -3.9;
y = 10.1;
z = 124.23;
くりかえし - for文

• プログラムの利点
  • 同じ処理を何度でも飽きずにくりかえし実行してくれる


• for()
   • くりかえしの処理の構造を定義する
   • 長いコードをコンパクトに圧縮してくれる
くりかえし - for文

• for文の書式


      for(初期化;   ループの継続条件;   カウンタ変数の更新) {
            文
      }

• 実行の手順
 1. 初期化を実行する。
 2. 条件を評価する。条件が偽ならば、ループを終了する。
 3. 真文を実行する。
 4. カウンタ変数の更新を実行する。
 5. 条件の評価に戻る。
くりかえし - for文


   //手作業による繰り返し - 面倒!
size(400, 400);

line(20, 20, 80, 380);
line(40, 20, 100, 380);
line(60, 20, 120, 380);
line(80, 20, 140, 380);
line(100, 20, 160, 380);
line(120, 20, 180, 380);
line(140, 20, 200, 380);
line(160, 20, 220, 380);
line(180, 20, 240, 380);
line(200, 20, 260, 380);
line(220, 20, 280, 380);
line(240, 20, 300, 380);
line(260, 20, 320, 380);
line(280, 20, 340, 380);
line(300, 20, 360, 380);
くりかえし - for文
くりかえし - for文


   //for() で書き換えてみる - シンプル!
size(400, 400);

for(int i = 20; i < 320; i = i + 20){
	 line(i, 20, 60 + i, 380);
}
くりかえし - for文
くりかえし - for文


   //for文の入れ子構造


size(400, 400);
smooth();

for (int y = 40; y < 380; y += 40) {
	 for (int x = 40; x < 380; x += 40) {
	 	    ellipse(x, y, 20, 20);
	 }
}
くりかえし - for文
くりかえし - for文


   //for文 - カウンタ更新の工夫
size(400, 400);
noStroke();
fill(64);
smooth();

for (int y = 360; y > 40; y /= 1.1) {
	 for (int x = 360; x > 40; x /= 1.1) {
	 	    ellipse(x, y, 5, 5);
	 }
}
くりかえし - for文
くりかえし - for文


   //for文によるグラデーション
noStroke();
size(400, 400);
for (int y=0; y<400; y+=20) {
	 for (int x=0; x<400; x+=20) {
	 	    fill((x+y) * 0.3);
	 	    rect(x, y, 20, 20);
	 }
}
くりかえし - for文
プログラムに構造を付加する

• プログラムに構造を付加する


 • setup()
    • プログラムを起動した際に1回だけ実行される


 • draw()
    • プログラムが作動している間、継続して繰り返し実行される
プログラムに構造を付加する



                  グローバル変数

void setup(){


                最初に1回だけ実行されるパート

}

void draw(){


                 繰り返し実行されるパート
}
構造化されたプログラムの例


   //初期設定
void setup() {
	 size(400, 400);
	 smooth();
	 fill(128);
	 noStroke();
}

//円を描く
void draw() {
	 background(204);
	 ellipse(200, 200, 100, 100);
}
構造化されたプログラムの例
繰り返し、乱数

• draw()はプログラムを実行している間はくりかえし実行される
• たくさんの図形を描くこともできるはす
   • 図形を描く
   • 位置を移動
   • また図形を描く
   • 位置を移動
   • …


• 乱数 (random) の利用
  • 乱数:全く規則性のない値
  • 乱数の生成 (processigの場合)
    • random(min, max);
        • min∼maxまでの範囲で乱数を生成
繰り返し、乱数
増殖する円

   //初期設定
void setup() {
	 size(400, 400);
	 smooth();
	 fill(128);
	 stroke(32);
}

//繰り返しランダムな場所に円を描く
void draw() {
	 float posX = random(0, 400);
	 float posY = random(0, 400);
	 float ellipseSize = random(4, 40);
	 ellipse(posX, posY, ellipseSize, ellipseSize);
}
繰り返し、乱数
増殖する円
条件分岐:if文

• if文 - 条件分岐
• 「もし∼だったら」という条件を示す文


    if(条件式) {
        真文
    }



    if(条件式) {
        真文
    } else {
        偽文
    }
条件分岐:if文


    //初期設定
void setup() {
	 size(400, 400);
	 smooth();
	 fill(128);
	 stroke(32);
}

//繰り返しランダムな場所に円を描く
void draw() {
	 float posX = random(0, 400);
	 float posY = random(0, 400);
	 float ellipseSize = random(4, 40);
	
	 //もし画面の右半分に中心位置があれば円を描く
	   if(posX > 200){
	   	    ellipse(posX, posY, ellipseSize, ellipseSize);
	   }	
}
条件分岐:if文
条件分岐:if else 文


        //初期設定
void setup() {
	   size(400, 400);
	   background(128);
	   smooth();
	   fill(64);
	   noStroke();
}

//繰り返しランダムな場所に円を描く
void draw() {
	   float posX = random(0, 400);
	   float posY = random(0, 400);
	   float ellipseSize = random(4, 10);
	   if(posX > 200){   //もし画面の右半分だったら
	   	      fill(32);    //濃い灰色でぬりつぶす
	   } else {            //そうでなければ
	   	      fill(204);   //濃い灰色でぬりつぶす
	   }
	   ellipse(posX, posY, ellipseSize, ellipseSize);	
}
条件分岐:if else 文
条件分岐:論理積(AND)と論理和(OR)

• 論理積 (AND)
  • A かつ B (A B)
  • processingでは:A && B




• 論理和 (OR)ベン図による論理積 (AND)
  • A かつ B (A B)
  • processingでは:A ¦¦ B
条件分岐:論理積(AND)と論理和(OR)


     void setup() {
	   size(400, 400);
	   background(128);
	   smooth();
	   fill(64);
	   noStroke();
}

void draw() {
	 float posX = random(0, 400);
	 float posY = random(0, 400);
	 float ellipseSize = random(4, 10);
	 if(posX > 200 && posY > 200){ //論理積
	   	    fill(32);
	   } else if(posX < 200 || posY < 200) { //論理和
	   	    fill(204);
	   }
	   ellipse(posX, posY, ellipseSize, ellipseSize);
}
条件分岐:論理積(AND)と論理和(OR)
条件分岐:モンテカルロ法で円を描く


     void setup() {
	   size(400, 400);
	   background(128);
	   smooth();
	   fill(64);
	   noStroke();
}
void draw() {
	 float posX = random(0, 400);
	 float posY = random(0, 400);
	 float ellipseSize = random(4, 10);
	 //中心からの距離を算出する
	   float distance = dist(200, 200, posX, posY);
	   if(distance < 150){
	   	    fill(32);
	   } else {
	   	    fill(204);
	   }
	   ellipse(posX, posY, ellipseSize, ellipseSize);
}
条件分岐:モンテカルロ法で円を描く
関数を定義する

• 関数とは?
  • 引数と呼ばれるデータを受け取り、定められた通りの処理を実行して結
    果を返す一連の命令群


• いままでやってきたprocessingの命令群も実は全て関数
  • size(), rect(), background()....


• オリジナルの関数を定義することも可能
  • モンテカルロ法で円を描くプログラムをmonteEllipse()として定義する
  • 引数(argument)は、()の中に入れて受け渡しする
関数を定義する


     void setup() {
	   size(400, 400);
	   smooth();
	   noStroke();
}

void draw() {
	 monteEllipse();
}

void monteEllipse() {
	 float posX = random(0, 400);
	 float posY = random(0, 400);
	 float ellipseSize = random(4, 10);
	 float distance = dist(200, 200, posX, posY);
	 if(distance < 100){
	 	      fill(64);
	 	      ellipse(posX, posY, ellipseSize, ellipseSize);
	 }
}
関数を定義する - 引数の定義

• 引数をわたせるようにしてみる
  • 引数の数、順番、型、値は自由に定義できる
  • 下記のように定義してみる
  • monteEllipse(x中心点, y中心点, 半径, グレースケール);
関数を定義する - 引数の定義


     void setup() {
	   size(400, 400);
	   smooth();
	   noStroke();
}

void draw() {
	   monteEllipse(50, 50, 180, 32);
	   monteEllipse(250, 250, 100, 128);
	   monteEllipse(200, 50, 50, 255);
}

void monteEllipse(float cx, float cy, float radius, float grayscale) {
	   float posX = random(0, 400);
	   float posY = random(0, 400);
	   float ellipseSize = random(4, 10);
	   float distance = dist(cx, cy, posX, posY);
	   if(distance < radius){
	   	     fill(grayscale);
	   	     ellipse(posX, posY, ellipseSize, ellipseSize);
	   }
}
関数を定義する - 引数の定義
クラスを定義する

• クラスとは?
  • オブジェクトの設計図
  • オブジェクト指向プログラミングにおいて、データとその操作手順であ
    るメソッドをまとめたオブジェクトの雛型を定義したもの
  • 関数によるよりもさらに発展した概念
     • カプセル化
     • 継承
     • ポリモーフィズム (多態性)


 • monteEllipse関数と同様な機能を、classで書いてみる
 • MonteEllipseクラスとして設計
クラスを定義する


   MonteEllipse m1, m2, m3;

void setup() {
	 size(400, 400);
	 noStroke();
	 smooth();
	 m1 = new MonteEllipse(50, 50, 180, 32);
	 m2 = new MonteEllipse(250, 250, 100, 128);
	 m3 = new MonteEllipse(300, 100, 50, 255);
}

void draw() {
	 m1.update();
	 m2.update();
	 m3.update();
}
クラスを定義する


     class MonteEllipse {
	   float cx, cy, radius, grayscale;
	
	   MonteEllipse(float _cx, float _cy, float _radius, float _grayscale){
	   	    cx = _cx;
	   	    cy = _cy;
	   	    radius = _radius;
	   	    grayscale = _grayscale;
	   }
	
	   void   update(){
	   	      float posX = random(0, 400);
	   	      float posY = random(0, 400);
	   	      float ellipseSize = random(4, 10);
	   	      float distance = dist(cx, cy, posX, posY);
	   	      if(distance < radius){
	   	      	    fill(grayscale, 128);
	   	      	    ellipse(posX, posY, ellipseSize, ellipseSize);
	   	      }
	   }
}
クラスを定義する

Ssaw08 0916