人工言語入門 A 2010
Processingで時計を作る
今日の内容
- 最終課題のテーマ発表
- 最終課題に関連した演習
- 基礎:普通のアナログ時計を作る
- 時刻の取得
- 時刻の情報から針の角度を計算する
- より正確な時計にしていくには?
- 応用:単純な図形で「時間」を表現する
- 位置による時間の表現
- 数による時間の表現
- 色による時間の表現
- 形態による時間の表現 …etc
- 基礎:普通のアナログ時計を作る
- 最終課題に関連した演習
最終課題について
テーマ:Processingを用いて「時間」を表現する
- Processingを用いて、「時間」を表現するプログラムを作成してください。
- 時間を表現するといっても、普段身近に接している時計を作成するという意味ではなく、いままで見たことのないような表現手段で「時間」を感じさせる方法を考えてください。
- 作品の完成度よりは、斬新なアイデアを重視します。
- 完成したプログラムは下記のWebサーバのアドレスにアップロードすることで提出したこととします。
- http://www.cuc.ac.jp/~[ログイン名]/proga/final/index.html
時計を作る 1 – アナログ時計を作る
- 課題の内容と関連して、まずは普通のアナログ時計を作成する
- 時刻の取得
- 取得した時刻から、秒針、分針、時針の角度を計算する
- 時刻を取得するための関数
- 取得される時刻は、コンピュータのOSに設定された時刻
//秒の取得 second(); //分の取得 minute(); //時の取得 hour();
- 試しに現在の秒数を取得して、出力してみる
- println() を利用して、Processingのコンソールのテキストエリアに現在の秒数を表示してみる
void setup() { frameRate(30); } void draw() { int h = hour(); int m = minute(); int s = second(); println("現在の時刻は "+h+":"+m+":"+s); }
- 取得した「時」「分」「秒」の値から針の角度を計算する
- それぞれの1単位あたり、何度針が動くのか計算する (角速度)
- 時間
- 12時間で時計を1周する
- 1時間あたりの移動角度 → 360/12 = 30°
- 分
- 60分で時計を1周する
- 1分あたりの移動角度 → 360/60 = 6°
- 秒
- 60秒で時計を1周する
- 1秒あたりの移動角度 → 360/60 = 6°
- 時間
- 現在の時刻の値にそれぞれの角速度をかけ算すると、現在の角度が算出されるはず
- 時刻から、針の角度を計算する
- 例:8時30分20秒
- 時針:8 x 30 = 240°
- 分針:30 x 6 = 180°
- 秒新:20 x 6 = 120°
- 例:8時30分20秒

- Processingのプロラムで表現してみる
- 座標系全体を画面の中央に移動 translate(width/2, height/2);
- 時刻を取得
- 時間の針
- pushMatrix();
- rotate(時間 x 15°);
- popMatrix();
- 分の針
- pushMatrix();
- rotate(時間 x 6°);
- popMatrix();
- 秒の針
- pushMatrix();
- rotate(時間 x 6°);
- popMatrix();
- Processingの rotate() 関数で用いられる角度の単位に注意する必要あり
- 角度の単位は「度 (degree)」ではなく「ラジアン (radian)」で指定しなくてはならない
- Processingでの、degreeからradianへの変換
- radians( 度 );
- radianからdegreeへの変換
- degrees( ラジアン角 );
- Processingでの、degreeからradianへの変換

void setup() { size(300,300); stroke(255); smooth(); frameRate(30); } void draw() { background(0); float s = second(); float m = minute(); float h = hour() % 12; translate(width/2, height/2); ellipse(0,0,width,height); noFill(); stroke(255); //秒針 pushMatrix(); rotate(radians(s*(360/60))); strokeWeight(1); line(0,0,0,-height/2); popMatrix(); //分針 pushMatrix(); rotate(radians(m*(360/60))); strokeWeight(2); line(0,0,0,-height/2); popMatrix(); //時針 pushMatrix(); rotate(radians(h*(360/12))); strokeWeight(4); line(0,0,0,-height/3); popMatrix(); }

実際の時計との違い
- 作成したプログラムの表示と実際のアナログ時計と比べてみる
- なにか違いはないだろうか?
- 分が切り替わった瞬間の動き
- 時間が切り替わった瞬間の動き
- なにか違いはないだろうか?
- 実際の時計
- 時針、分針も常にゆっくりと動いている
- 時刻が変化した瞬間に動くのではなく、ゆっくりと移動して、気がつくと角度が変化している
- 実際の分針
- 秒の影響を受けている
- 毎秒あたり、1/60の影響 (1分 = 60秒なので)
- m = m + (s/60);
- 実際の時針
- 分の影響を受けている
- 毎分あたり、1/60の影響 (1時間 = 60分なので)
- h = h + (m/60);
- 実際にアナログ時計の動きと同じになるよう、プログラムを改良する
void setup() { size(300,300); stroke(255); smooth(); frameRate(30); } void draw() { background(0); float s = second(); float m = minute() + (s/60.0); float h = hour()%12 + (m/60.0); translate(width/2, height/2); ellipse(0,0,width,height); noFill(); stroke(255); //秒針 pushMatrix(); rotate(radians(s*(360/60))); strokeWeight(1); line(0,0,0,-height/2); popMatrix(); //分針 pushMatrix(); rotate(radians(m*(360/60))); strokeWeight(2); line(0,0,0,-height/2); popMatrix(); //時針 pushMatrix(); rotate(radians(h*(360/12))); strokeWeight(4); line(0,0,0,-height/3); popMatrix(); }

- 文字盤を追加
- 角度を変更しながら、一定間隔に目盛を刻んでいく
- 小さな目盛:6度づつ
- 大きな目盛:30度づつ
int MARGIN = 20; void setup() { size(300,300); stroke(255); smooth(); frameRate(30); } void draw() { background(0); float s = second(); float m = minute() + (s/60.0); float h = hour()%12 + (m/60.0); translate(width/2, height/2); rotate(radians(180)); // 文字盤の表示 pushMatrix(); fill(128); noStroke(); for(int i=0; i<60; i++){ rotate(radians(6)); ellipse(width/2-MARGIN,0,3,3); } for(int i=0; i<12; i++){ rotate(radians(30)); ellipse(width/2-MARGIN,0,10,10); } popMatrix(); noFill(); stroke(255); // 秒針 pushMatrix(); rotate(radians(s*(360/60))); strokeWeight(1); line(0,0,0,width/2-MARGIN); popMatrix(); // 分針 pushMatrix(); rotate(radians(m*(360/60))); strokeWeight(2); line(0,0,0,width/2-MARGIN); popMatrix(); // 時針 pushMatrix(); rotate(radians(h*(360/12))); strokeWeight(4); line(0,0,0,width/3-MARGIN); popMatrix(); }

アナログ時計 OOP版
int MARGIN = 20; Clock myClock = new Clock(); void setup() { size(300,300); stroke(255); smooth(); frameRate(30); } void draw() { background(0); myClock.getTime(); myClock.draw(); } class Clock { float s, m, h; Clock(){ } void getTime(){ s = second(); m = minute() + (s/60.0); h = hour()%12 + (m/60.0); } void draw(){ translate(width/2, height/2); rotate(radians(180)); pushMatrix(); fill(128); noStroke(); for(int i=0; i<60; i++){ rotate(radians(6)); ellipse(width/2-MARGIN,0,3,3); } for(int i=0; i<12; i++){ rotate(radians(30)); ellipse(width/2-MARGIN,0,10,10); } popMatrix(); noFill(); stroke(255); pushMatrix(); rotate(radians(s*(360/60))); strokeWeight(1); line(0,0,0,width/2-MARGIN); popMatrix(); pushMatrix(); rotate(radians(m*(360/60))); strokeWeight(2); line(0,0,0,width/2-MARGIN); popMatrix(); pushMatrix(); rotate(radians(h*(360/12))); strokeWeight(4); line(0,0,0,width/3-MARGIN); popMatrix(); } }
