1/fゆらぎ その1 実装編(Processingで)

1/fゆらぎについて大学の方で課題が出たのですが、これは電子工作にも使えるかな〜
と思ったので、こちらの方に載せようと思います。


課題としては人工的にいかに蝋燭の火や、焚火の火を模倣するかです。
実際にLEDを使ってこれを実現しようとすると以下のようになります。


そもそも1/fゆらぎってなんじゃ?ということなんですが、
ザックリ説明すると、人にとって安らぐような音や、ゆらぎというのは
1/fゆらぎに従っていると言われています。


ということは、みなさんがちょっとしたLEDをつかうような電子工作をした際、
1/fゆらぎを実装すれば、より自然に見えるということになりますね。


詳しい説明はgoogleに"1/fゆらぎ"、"1/fノイズ"というキーワードで検索するとたくさん出てくるので、
そちらに譲ります。


私はProcessingを使って、この1/fゆらぎを実現しました。
Processingはフリーのソフトウェアで、簡単にプログラミングが出来るというものです。

とりあえず見てみましょう。


1/fゆらぎを実現する方法はいくつかあるらしいのですが、
今回は間欠カオスという方法を試しました。


Processingのソースコードはこんな感じです。
凄く短いです。

ちょっとこのソースコード問題があります。
輝度の倍率を10秒ぶんテキストに落とそうとしているのですが、
なぜか10秒で終わってくれません。
なので、プログラムを終了するまでテキストに書き込みます。



// 1/fノイズでゆらぎを作ってみよう

PrintWriter writer; //ファイル出力用

void setup(){
 size(400,400);
 colorMode(RGB); //RGB色空間にセット
 background(0); //背景は黒にセット
 frameRate(20); //1秒間に20フレーム
 writer = createWriter("lumin.txt"); // 出力先ファイルをlumin.txtに設定
}
 float x=0.4,y=0; //初期値
 
void draw(){
 float scale; //倍率(0~1の間で)
 int time = 0; //時間カウント変数

 // 揺らぎ関数
 if(x<0.5){
  y=x+2*x*x;
 }else {
  y=x-2*(1-x)*(1-x);
 }
 
 // 1.0と0.0に張付きやすいのでランダム要素を入れる
 if (x<0.01) {
  y = (float)(random(1000)/1000); //1000は適当な数字
 }
 if (x>0.99) {
  y = (float)(random(1000)/1000);
 }
 x=y;
 
 //描画
 fill(0,0,0);
 rect(150,150,100,100);//描画くずを除去(気持ち程度の効果)
 ellipseMode(CENTER);
 fill(int(abs(255 * y)), 0, 0); //赤色の変化
 ellipse(200, 200, 50, 100);
 
 //ファイル出力
 if(time <= (20*10)){//10秒間のファイル出力(なぜか上手くいっていないみたい)
  writer.println(y);
 }
 
 if(time == (20*10)){
  writer.flush(); // バッファに溜まった文字列を出力先に移す
  writer.close(); // 繋がりを閉じる
 }
 time++;
}


以上です。
実際に電子工作を行う際、重要なのは


 float x=0.4,y=0; //初期値
 // 揺らぎ関数
 if(x<0.5){
  y=x+2*x*x;
 }else {
  y=x-2*(1-x)*(1-x);
 }
 x=y;


この部分です。これをmainのループでも、一定周期の割り込みで呼ばれる関数にでも
入れていただければ、輝度yが0〜1の間で変動するので、LEDのPWM出力に対応すれば
上手く行くのではないでしょうか。


ここで出力された輝度ファイルを解析したのですが、
今回は非常に長くなってしまったので次回にします。