風呂瀬 信五

p5.jsで探るフラクタルの深淵:再帰と数式が織りなす無限の美

プログラミングという論理の海で、予測不能な美しさを湛えた島を見つけたい。そんな願いを抱いたことはないでしょうか。単純なルールを繰り返し適用するだけで、なぜかくも複雑で、生命の息吹すら感じさせる幾何学模様が生まれるのか。その問いの核心に触れる鍵、それが p5.js フラクタル の世界です。この記事では、あなたの setup()draw() が、自己相似形という無限の深淵を覗き込む窓になるまでを案内します。複雑な数学への恐れは一旦脇に置き、コードが紡ぐ詩に耳を澄ませながら、ジェネラティブアートの本質的な魅力、すなわち秩序からカオスが立ち上る瞬間の神秘を探求していきましょう。

フラクタルとは何か:自己相似形の奥深き世界への誘い

フラクタルとは、その一部分を拡大すると、全体と同じ、あるいは非常によく似た形が繰り返し現れる幾何学的構造を指します。この性質は 自己相似形 と呼ばれ、フラクタルの魂とも言える概念です。私たちの周りを見渡せば、自然界そのものがフラクタルの壮大なギャラリーであることに気づかされます。リアス式海岸の複雑な入り江、冬の窓を飾る雪の結晶、空に浮かぶ雲の輪郭、そして一本のシダの葉。これらはすべて、異なるスケールに同じパターンを内包しています。

シダの葉を想像してみてください。主軸から葉が左右に生え、その一枚一枚の葉もまた、主軸と同じように小さな葉が左右に連なっています。この入れ子構造こそが、自己相似性の本質です。コンピュータの画面という限定された空間の中で、私たちはこの無限の構造を模倣し、探求できます。

クリエイティブコーディング においてフラクタルが魅力的なのは、それが単なる数学的な図形の描画に留まらないからです。それは、有限のルールから無限の複雑さを生成するための、強力な設計思想そのものです。数行のコードが、まるで生命のように成長し、分岐し、我々の予測を遥かに超えるディテールを織りなしていく。このプロセスは、創造という行為の根源的な喜びに満ちています。

p5.jsで描く基本的なフラクタル:再帰関数が紡ぐ幾何学の詩

p5.jsでフラクタル構造を最もエレガントに表現する道具は、再帰関数です。再帰とは、関数が自分自身の処理の中で、再び自分自身を呼び出す仕組みのこと。この「自分を呼び出す」という行為が、フラクタルの「部分が全体を繰り返す」という性質と見事に共鳴します。

最も直感的な例の一つが、フラクタルツリーでしょう。幹を描き、その先端から二本の枝を伸ばす。そして、その枝のそれぞれを新たな「幹」と見なし、同じプロセスを繰り返す。この思考プロセスは、p5.jsのコードに直接翻訳できます。


function setup() {
  createCanvas(800, 600);
}

function draw() {
  background(10, 20, 30);
  stroke(230, 240, 255, 150);
  
  // 画面下部中央を開始点にする
  translate(width / 2, height);
  
  // 最初の枝を描画
  branch(120);
}

function branch(len) {
  // 枝(線)を描く
  line(0, 0, 0, -len);
  // 枝の先端に座標系を移動
  translate(0, -len);

  // 一定の長さより短くなったら再帰を停止する(重要)
  if (len > 4) {
    // 現在の状態(座標系)を保存
    push();
    // 右の枝を描くために少し回転
    rotate(PI / 5);
    // 少し短い枝を再帰的に描く
    branch(len * 0.67);
    // 保存した座標系に戻す
    pop();
    
    // 同様に左の枝を描く
    push();
    rotate(-PI / 5);
    branch(len * 0.67);
    pop();
  }
}

このコードの心臓部は branch 関数です。この関数は線を引き、座標を移動させ、そして自分自身を二度呼び出しています。push()pop() は、座標系の状態(位置、回転)を一時的に保存し、元に戻すための呪文です。これにより、各枝が独立して成長できます。そして最も重要なのが if (len > 4) という終了条件。これがなければ、プログラムは無限に枝を生成しようとし、停止不能に陥ります。再帰は、無限を模倣するための強力な手法ですが、必ず「終わり」を定義しなくてはなりません。

マンデルブロ集合の詩学:複素平面が織りなす色彩の魔術

再帰関数で描くフラクタルが、構造の自己相似性を示すものだとすれば、マンデルブロ集合 は、数式の反復が生み出す風景のフラクタルです。それは、驚くほどシンプルな漸化式 $Z_{n+1} = Z_n^2 + C$ から生成される、複素数平面上の点の集合。ここで $Z$ と $C$ は複素数であり、$Z_0 = 0$ から計算を始めます。

この数式が意味するところを、詩的に解釈してみましょう。キャンバス上のすべてのピクセルを、複素平面上の点 $C$ と見なします。そして、それぞれの点 $C$ について、この漸化式の計算を何度も何度も繰り返します。もし、計算を繰り返しても $Z$ の値が無限に発散せず、ある範囲に留まり続けるならば、その点 $C$ はマンデルブロ集合に属すると判断し、黒く塗りつぶします。逆に、値が発散してしまう場合は、集合の外にあると判断します。

この「発散するまでの速さ(反復回数)」こそが、あの幻惑的な色彩を生み出す源泉です。発散が速い点には寒色を、遅い点には暖色を、といったルールを設けることで、集合の境界に複雑なグラデーションが浮かび上がります。p5.jsでは、loadPixels() を使ってキャンバスの全ピクセルにアクセスし、各ピクセルに対応する複素数を計算し、その結果に基づいて pixels 配列に色を書き込み、最後に updatePixels() で画面に反映させる、という手順で実装するのが一般的です。

マンデルブロ集合を描画するコードは、再帰的なフラクタルツリーとは全く異なるアプローチを取ります。入れ子状の関数呼び出しではなく、二重の for ループで画面の全ピクセルを走査し、各ピクセルで反復計算を行うのです。これは、異なる種類の「繰り返し」が、異なる種類の美を生み出すことを示唆しています。

アルゴリズムが生み出す無限のディテール:拡大と探索の悦び

フラクタルの真の魔力は、そのディテールに宿っています。特にマンデルブロ集合の境界線を拡大していくと、そこには息を呑むような光景が広がっています。渦巻く螺旋、稲妻のようなフィラメント、そして驚くべきことに、そこには元のマンデルブロ集合とそっくりな「ミニブロ」が無数に点在しているのです。

この拡大と探索のプロセスは、クリエイティブコーダーにとって至上の喜びです。p5.jsでインタラクティブな拡大機能を実装するのは難しくありません。マウスでクリックされた座標を中心として、描画範囲を狭めて再計算するだけです。クリックするたびに、私たちはミクロの宇宙へと深く潜っていきます。そこでは、全体を構成していたはずのルールが、再び全く新しい風景を、同じルールで生成し続けているのです。

しかし、この無限の旅には限界も存在します。コンピュータが扱う数値は、どこまでいっても有限の精度しか持ちえません。ある深度まで拡大を続けると、やがて浮動小数点数の誤差によってディテールが崩れ、ピクセルのブロックが見え始めます。これは失敗ではなく、むしろ重要な示唆です。私たちは、有限の機械語を用いて、無限という概念に触れようとしている。その境界線で生じる揺らぎやノイズすらも、ジェネラティブアートの一部として捉えることができるでしょう。

フラクタルを創造する哲学:秩序とカオスの間の生命の兆し

フラクタルアートの制作は、単に美しい図形を描く行為を超えた、哲学的な探求です。なぜなら、フラクタルは秩序とカオスの間に存在するからです。その生成ルールは、数学的な漸化式や再帰アルゴリズムといった、完全に決定的で秩序だったものです。入力が同じであれば、結果は常に同じになります。

しかし、その結果としてスクリーンに現れるイメージは、まるで予測不可能なカオス、あるいは有機的な生命体のような複雑さを持ちます。マンデルブロ集合の境界線の、どこまでも続く複雑な形状を、誰があのシンプルな $Z^2+C$ という式から完全に予測できたでしょうか。フラクタルツリーのパラメータをほんの少し変えるだけで、まるで異なる種の樹木のような、全く新しい形が生まれます。

この「決定論的なルールから生まれる、予測不能な複雑さ」こそが、多くのアーティストやプログラマーを惹きつけてやまないジェネラティブアートの核心です。私たちはコードを書くことで、宇宙の法則をシミュレートする小さな箱庭を作ります。その中で何が起こるかを完全には制御できません。私たちは創造主であると同時に、アルゴリズムという名の自然現象を観察する、謙虚な発見者でもあるのです。フラクタルに感じる生命の兆しは、この秩序とカオスの間の絶妙な緊張関係から生まれているのかもしれません。

あなたのキャンバスでフラクタルを咲かせるためのヒントと実践

理論の探求は、実践という土壌があってこそ花開きます。さあ、あなたのp5.jsエディタを開き、自分だけのフラクタルを育ててみましょう。以下に、そのためのヒントをいくつか記します。

  1. パラメータを探求する: フラクタルツリーのコードで、枝が分岐する角度 (PI / 5) や、枝が短くなる比率 (0.67) を変えてみてください。random() 関数を少しだけ加えて、左右非対称な、より自然な木を生成してみるのも面白いでしょう。
  2. 色彩をマッピングする: マンデルブロ集合では、反復回数を色相 (HSB カラーモードの H) に、map() 関数を使って割り当ててみましょう。色のサイクルを変えるだけで、同じ形状が全く異なる表情を見せます。
  3. ノイズとの融合: p5.jsの noise() 関数は、フラクタルに有機的な揺らぎを与えるための最高のスパイスです。再帰の各ステップで、回転角度や枝の長さに微細なノイズを加えることで、規則性の中に予測不能な美しさが生まれます。
  4. 基本図形を変える: なぜ枝は常に「線」でなければならないのでしょう? 再帰の各ステップで、線分の代わりに円や四角形、あるいは beginShape() で定義したカスタムシェイプを描画してみると、全く新しいフラクタルアートが生まれます。

フラクタルは、完成された答えではありません。それは、無限のバリエーションを生み出すための、力強い「問い」そのものです。コードを書き、パラメータを調整し、結果を観察し、またコードを書き直す。その繰り返しの先に、あなただけの自己相似形が、静かに芽吹くのを待っています。

関連記事