再帰を使ってフラクタル図形を作る by Processing
今回はProcessingで再帰を使ってフラクタル図形を作ります。
再帰ッカーはフラクタルる。
こんなのを作りますよ。
ある程度フラクタル図形を作ったことがある方は「なるほどこういう構造ね」と理解できると思いますが、「なにこれ!かっこいい!どうやって作るの!」って思う方に向けて解説します。
アルゴリズムの説明
まずはどんなアルゴリズムで生成されているのかを説明します。
アニメーションで見たらわかりやすいでしょう。
四角形に1本線を引いて分割すると2つの四角形ができますよね。
その2つの四角形に対しても同様に1本線を引いてできた四角形を……
とそんな処理を繰り返していくのです。
アルゴリズムを実装
まずは全体のコードを貼ります。
void setup() {
size(700, 700);
noLoop();
stroke(0);
noFill();
}
void draw() {
background(250);
divideRect(10, 10, width-20, height-20, 8);
}
//(x座標, y座標, 幅, 高さ, 再帰回数)
void divideRect(float x, float y, float w, float h, int n) {
rect(x, y, w, h);
n--;
if (n>=0) {
//幅が高さよりも大きい、または幅と高さが等しい場合
if (w>=h) {
//ランダムな値を得る
float randomW = random(w*0.1, w*0.9);
//ランダムな値から2つのdivideRectを呼び出す
divideRect(x, y, randomW, h, n); //左側の四角形
divideRect(x+randomW, y, w-randomW, h, n); //右側の四角形
}
//幅が高さよりも小さい場合
if (w<h) {
float randomH = random(h*0.1, h*0.9);
divideRect(x, y, w, randomH, n); //上側の四角形
divideRect(x, y+randomH, w, h-randomH, n); //下側の四角形
}
}
}
//クリックで再描画する
void mousePressed() {
redraw();
}
//sキーで保存
void keyPressed() {
if (key == 's')saveFrame("####.png");
}
どういう処理をされているのか解説していきます。
まず最初の処理はw(幅)とh(高さ)が等しいので、ランダムな値randomWをとります。
端に寄りすぎないようにw*0.1からw*0.9の間でランダムにします。
float randomW = random(w*0.1, w*0.9);
四角形が2つできたのでそれぞれにdivideRect()を呼び出します。
ここで2つのrect()が描画されます。
divideRect(x, y, randomW, h, n); //左側の四角形
divideRect(x+randomW, y, w-randomW, h, n); //右側の四角形
左の四角形だけみてみると、h(高さ)がw(幅)よりも大きいので横に線を引いた分割になります。
右の四角形にも同じ処理がされて、これが2回再帰した形です。
n(再帰回数)が0になるまでこの処理の繰り返しです。四角形の数は倍々と増えていきます。
うん…説明が難しい!理解できましたか?
とりあえず色々いじってると理解できると思います!僕はそうでした。
御託はいい、遊ばせろ!
ということで以下は色々遊んでみた作例です。
rect()で描画しているのでfill()で簡単に色を変えられます。
int[] colors = {#F6F7EB, #E94F37, #393E41, #3F88C5, #44BBA4};
int getCol(){
return colors[(int)random(colors.length)];
}
こんな感じで好きな色からランダムに色を取得しています。
再帰回数によって線の太さを変えてみる。
狂ったように再帰させる。
再帰回数23回。
これだけでいろんな表情を見せてくれますね。
おしまい!
解説記事第2弾なのでこれからも続いていくという希望を込めてマガジンにProcessingのTipsとしてまとめておこうと思います。
ありがとうございました。
Happy coding!
ここから先は
¥ 100
応援してくださる方!いつでもサポート受け付けてます!