人工言語入門 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();
}
}