ラベル 要素技術 の投稿を表示しています。 すべての投稿を表示
ラベル 要素技術 の投稿を表示しています。 すべての投稿を表示

2015年11月6日金曜日

ランダムウォーク

アートプログラミングと聞いて最初に思い浮かべるものは?
と聞いた時に返ってくる答えランキング1位といえば「ランダム」(俺調べ 調査人数1人)。

ランダムな要素を取り入れると人の意志とは無関係に、予想もつかない変化を見せてくれるので単純におもしろい。数学的にはきっと値に偏りがないだとか、再現性がないようにとか、そういった色々考慮すべき点はあるとは思いますが、今回は単純にProcessingのrandom()が返してくれる数値で遊んでみます。(そういえばrandom()の中のアルゴリズムって何だろ??)

今回作るのはランダムに発生する数値を可視化するランダムウォークです。
ウォークと名がついているから、とりあえず今回は移動だけにランダムな値を適用して見ていこうかと思いますが、移動だけでなく色、形、大きさ、加速度、色々なパラメータに適用する事でもっとおもしろい動きになるらしいです。

二次元平面のランダムウォーク

まずは二次元平面上を上下左右の4方向にそれぞれランダムに移動させてみます。

ソースコード

int gX;
int gY;

void setup() {
  size(200, 200);
  background(255);
  
  gX = width / 2;
  gY = height / 2;
}

void draw() {
  int value = (int)(random(4));
  if(value == 0)      { gX += 1; }
  else if(value == 1) { gX -= 1; }
  else if(value == 2) { gY += 1; }
  else                { gY -= 1; }
  
  stroke(0);
  point(gX, gY);
}

実行結果




これだけでランダムに移動する軌跡を描くことができました。
ちょ、ちょっと地味っすね。

重要なのは、draw()関数の最初の部分。
random()で生成した0.0~3.9までの値を元に、上下左右それぞれの方向へ1ピクセル分移動させるように計算しています。

んーしかし、やっぱりこれだけではちょっと物足りないような・・・?

大量の二次元平面ランダムウォーク


という事で、以下のようにちょっと拡張してみたいと思います。
  1. ランダムウォークする軌跡を大量にする(100個くらい?)
  2. それぞれの軌跡に個別の色を設定する
  3. それぞれの軌跡が混じり過ぎないように過去の線は薄くする

ソースコード

public class Walker {
  int mX;
  int mY;
  color mColor;
  
  public Walker(color col) {
    mX = width / 2;
    mY = height / 2;
    mColor = col;
  }
  
  public void update() {
    int value = (int)(random(4));
    if(value == 0)      { mX += 1; }
    else if(value == 1) { mX -= 1; }
    else if(value == 2) { mY += 1; }
    else                { mY -= 1; }
  }
  
  public void onDraw() {
    stroke(mColor);
    point(mX, mY);
  }
}

ArrayList<Walker> gWalkerList;

void setup() {
  size(200, 200);
  background(0);
  
  gWalkerList = new ArrayList();
  
  for(int i=0; i<100; ++i) {
    gWalkerList.add(new Walker(color((int)random(255), (int)random(255), (int)random(255))));
  }
}

void draw() {
  fill(0, 10);
  rect(0, 0, width, height);
  
  for(Walker walker : gWalkerList) {
    walker.update();
    walker.onDraw();
  }
}

実行結果



複数の軌跡を描くために、軌跡描画処理をクラス化しましたが、基本的な処理は前述のものと変わりありません。

なんだか微生物が動いているみたいでキモかわいい!
でもさすがに100個は多すぎたかな?

2015年11月1日日曜日

1/fゆらぎ (その3)

はい、つづきました。

前回、前々回は以下を参照ください。

1/fゆらぎ その1:http://tryoutartprogramming.blogspot.jp/2015/10/1f-1.html
1/fゆらぎ その2:http://tryoutartprogramming.blogspot.jp/2015/10/1f-2.html


と、いうワケでようやく作っていこうかと思います。
その1の最後にも書きましたが、とりあえずJavaに慣れているから、今回は手っ取り早くProcessing(2.1.1)を使ってみます。

1. 素直に実装してみる

まずは前回の数式を素直に実装してみようかと思います。

ソースコード

float x = 0.1f;

void setup() {
  size(200, 200);
  background(0, 0, 0);
 
  frameRate(20);
}

void draw() {
  fill(0, 0, 0);
  rect(0,0,width, height);
 
  if(x < 0.5f) {
    x = x+2.0f*x*x;
  }
  else if(x >= 0.5f) {
    x = x-2.0f*(1.0f-x)*(1.0f-x);
  }
 
  fill(255, 36, 0, (255*x));
  rect(0,0,width, height);
}

実行結果

1/fゆらぎを素直に実装した実行結果
実行結果


おぉっ。
これだけでも何かそれっぽい。

でもどこかで見たけれど、確かに上端と下端に貼りつきやすい気がする。
この実行結果の例の場合は黒(下端)にちょっとより過ぎているような。。。
と、いう事でどこかのパクりではありますが、解決策を入れてみようかと思います。

2. 改良版

対策としては単純に上端および下端に近い値になった時、乱数で適当な値に変更してしまいます。
あと、炎を再現するとなると、真っ暗になるのもあれなので、ちょっとゲタ履かせます。

ソースコード

float x = 0.1f;

void setup() {
  size(200, 200);
  background(0, 0, 0, 255);
  frameRate(20);
}

void draw() {
  fill(20, 10, 0);
  rect(0, 0, width, height);
 
  if(x < 0.5f) {
    x = x+2.0f*x*x;
  }
  else if(x >= 0.5f) {
    x = x-2.0f*(1.0f-x)*(1.0f-x);
  }
  
  if((x < 0.005) || (x > 0.995)) {
    x = random(1.0);
  }
  
  x = x * 0.7 + 0.3f;
 
  fill(255, 36, 0, (255*x));
  rect(0, 0, width, height);
}

実行結果

1/fゆらぎ(改良版)の実行結果
実行結果

おぉっいいね。いい感じ。
形はまったく炎っぽくないけど、色の変化のゆらゆら感はなかなかではないだろうか。


と、いうわけで、3回に渡って1/fゆらぎの実装をしてみましたが、丸や四角なんかよりも、もっと地味な結果になりました。3回にも渡ってやるほどのものか?と言われちゃいそうですが、なんとなくそれっぽい感じのモノがとりあえず出来たので、個人的には満足です。最初だし。

これをスマホで表示して、かぼちゃの中に放り込めばジャックオーランタンが出来上がるかも?

2015年10月30日金曜日

1/fゆらぎ (その2)

と、言うわけで"つづき"ました。

前回の記事は「1/fゆらぎ (その1)」をどうぞ。


では、このロウソクの火の揺らぎっぽいものを1/fゆらぎを使って再現してみたいと思います。

まず1/fゆらぎって何ぞや?
1/fゆらぎ (エフぶんのいちゆらぎ) とは、パワー(スペクトル密度)が周波数fに反比例するゆらぎのこと。 
ピンクノイズとも呼ばれ、自然現象においてしばしば見ることができる[1]。具体例として人の心拍の間隔や、ろうそくの炎の揺れ方、電車の揺れ、小川のせせらぐ音、目の動き方、木漏れ日、物性的には金属の抵抗、ネットワーク情報流、蛍の光り方などが例として挙げられる。 (wikipedia 「1/fゆらぎ」より)
ふむ。
さっぱり意味がわからないけど、なんだか色々なものをそれっぽく再現するのに役立ちそうだ。

具体的にこの1/fゆらぎを実装するための方法としては

  • セルラーオートマトン法
  • 1/2階積分法
  • 間欠カオス法

などなどがあるらしい。
この中で「間欠カオス法」ってやつが一番簡単なようなので、お馬鹿な私でも出来そうだと思うのでこれで作ってみます。

間欠カオス法

0~1の範囲のある値xについて、

x < 0.5の場合
 x = x + 2 * x * x

x >= 0.5の場合
 x = x - 2 * (1 - x) * (1 - x)

を計算して、このxをまた次の計算の入力にしていく感じらしいです。


ふむ。
確かに計算式的には難しくない。
何故このような式になるのかはさっぱりわからないけれど。

と、いうわけで、この式を使って今度こそ実際に作ろうと思います!
「えっ?まだ作らないの?さっさと作れよ!!!」という声が聞こえてきそうですが、つづく!!!(多分)

1/fゆらぎ (その1)

そんなわけで、とりあえず何かを作ってみようかと思います。

とは言っても何もかもが素人なので、急にすごいものは作れない。
いや、すごいものどころかまともに動くものすら作れるのか・・・。

やっぱり最初は丸とか四角を描画して動かしたりするものなのかなー?
でもそういうのはそこらじゅうに転がっているし、今更感強いかなー?

なんて事を考えていたら、今はちょうどハロウィン。
何かこれにひっかけて出来ないものかと考えてみました。

ハロウィンと言えば「ジャックオーランタン」だよなぁ。
とは言え、例えば3Dのジャックオーランタンを作成してグリグリ動かすなんて事は今の俺には出来そうに無い。例によってBlenderはインストールしているものの、まともに触っていないので。

そうなると・・・光源。
そうだ!ランタンの光源なんてどうだ!?
ろうそくの火みたいにゆらゆら揺れるものを何とかしてみたり。

って事で、早速ググってみる。

明日から本気出す(´・ω・`):LEDで炎のゆらめき(1/fゆらぎ)をPWMで表現してみる
http://d.hatena.ne.jp/rinie/20120917/1347821818

ほほう。
「1/fゆらぎ」ってやつがポイントかな?

むむむっ!?でも「1/fゆらぎ」って単語は聞いたことがあるぞ。
意味はよくわからないけど、癒し系の曲とかに含まれているとかなんとか。
ロウソクの火の揺らぎもこれで再現可能なのか。
知らなかった。

よし、とりあえずこの1/fゆらぎってやつを作ってみよう。
今のところJavaを使い慣れているってのもあってProcessingを使おうかと考えています。

つづく(多分)