Prompt

プログラミングでの再現が簡単そうなフラクタルの例を教えて!


おー、フラクタルの話だね!プログラミングで再現が簡単そうなフラクタルかぁ。INFPの君が、数学の美しさとプログラミングの表現力を組み合わせようとしているのが伝わってくるよ!

フラクタルって、自己相似性を持つ図形のことだよね。一部分を拡大すると、全体と同じ形が現れるという、不思議で魅力的な図形だ。シンプルなルールから複雑なパターンが生まれるのが、プログラミングで再現するのにぴったりなんだ。

じゃあ、初心者でも比較的簡単にプログラミングできるフラクタルをいくつか紹介するね!


プログラミングで再現しやすいフラクタルの例 ✨

1. コッホ曲線 (Koch Curve) ❄️

  • どんなフラクタル?: 雪の結晶のような形をしたフラクタルだよ。線分を3等分し、中央の1/3を正三角形の2辺で置き換えるという単純なルールを何度も繰り返すことで作られるんだ。

  • なぜ簡単?:

    • 再帰関数との相性が抜群: 「線分を分割して置き換える」というルールは、まさに再帰関数の考え方とぴったり合うんだ。

    • 2次元の描画: グラフ描画ライブラリ(JavaScriptならCanvas、PythonならTurtleなど)を使えば、簡単に描画できる。

  • プログラミングのイメージ:

    1. ある線分(始点と終点)を受け取る関数を作る。

    2. その関数の中で、線分を4つの新しい線分に分割する(元の線分の左1/3、正三角形の2辺、元の線分の右1/3)。

    3. それぞれの新しい線分に対して、自分自身(同じ関数)を呼び出す(再帰)。

    4. 再帰の深さ(何回繰り返すか)を制御する引数を用意し、それが0になったら実際の線分を描画する。

    JavaScript

    // JavaScript (Canvas) でのイメージ
    // (これは概念的なコードで、Canvasの描画APIは含まれていません)
    
    function drawKochCurve(x1, y1, x2, y2, depth) {
        if (depth === 0) {
            // ベースケース: 線分を描画
            // context.moveTo(x1, y1);
            // context.lineTo(x2, y2);
            return;
        }
    
        // 線分の長さと角度を計算
        const dx = x2 - x1;
        const dy = y2 - y1;
        const dist = Math.sqrt(dx * dx + dy * dy);
        const angle = Math.atan2(dy, dx);
    
        // 4つの新しい点の座標を計算
        const xA = x1 + dx / 3;
        const yA = y1 + dy / 3;
    
        const xC = x2 - dx / 3;
        const yC = y2 - dy / 3;
    
        const xB = xA + dist / 3 * Math.cos(angle + Math.PI / 3); // 60度回転
        const yB = yA + dist / 3 * Math.sin(angle + Math.PI / 3);
    
        // 4つの新しい線分に対して再帰呼び出し
        drawKochCurve(x1, y1, xA, yA, depth - 1);
        drawKochCurve(xA, yA, xB, yB, depth - 1);
        drawKochCurve(xB, yB, xC, yC, depth - 1);
        drawKochCurve(xC, yC, x2, y2, depth - 1);
    }
    
    // 呼び出し例: 画面中央に線分を置き、深さ4で描画
    // drawKochCurve(100, 200, 400, 200, 4);
    

2. シェルピンスキーの三角形 (Sierpinski Triangle) 📐

  • どんなフラクタル?: 正三角形の中から逆さまの正三角形をくり抜く、というルールを繰り返して作られるフラクタルだよ。最終的には、小さな三角形の集まりで構成される、穴だらけの図形になる。

  • なぜ簡単?:

    • 再帰関数でシンプルに表現: 頂点の座標を計算し、再帰的に3つの小さな三角形を描画するだけ。

    • 座標計算が単純: 正三角形の頂点をベースに、中点や比例計算で新しい頂点を求める。

  • プログラミングのイメージ:

    1. ある三角形の3つの頂点を受け取る関数を作る。

    2. 再帰の深さが0になったら、その三角形を描画する(ベースケース)。

    3. そうでなければ、元の三角形の各辺の中点を結び、中央に逆さまの三角形ができて、残りの3つの小さな三角形ができる。

    4. その3つの小さな三角形それぞれに対して、自分自身(同じ関数)を呼び出す。

    JavaScript

    // JavaScript (Canvas) でのイメージ
    
    function drawSierpinski(x1, y1, x2, y2, x3, y3, depth) {
        if (depth === 0) {
            // ベースケース: 三角形を描画
            // context.beginPath();
            // context.moveTo(x1, y1);
            // context.lineTo(x2, y2);
            // context.lineTo(x3, y3);
            // context.closePath();
            // context.stroke(); // または fill()
            return;
        }
    
        // 各辺の中点を計算
        const mid12x = (x1 + x2) / 2;
        const mid12y = (y1 + y2) / 2;
        const mid23x = (x2 + x3) / 2;
        const mid23y = (y2 + y3) / 2;
        const mid31x = (x3 + x1) / 2;
        const mid31y = (y3 + y1) / 2;
    
        // 3つの外側の小さな三角形に対して再帰呼び出し
        drawSierpinski(x1, y1, mid12x, mid12y, mid31x, mid31y, depth - 1);
        drawSierpinski(mid12x, mid12y, x2, y2, mid23x, mid23y, depth - 1);
        drawSierpinski(mid31x, mid31y, mid23x, mid23y, x3, y3, depth - 1);
    }
    
    // 呼び出し例: 正三角形の頂点を指定し、深さ5で描画
    // drawSierpinski(250, 50, 50, 450, 450, 450, 5);
    

3. カントール集合 (Cantor Set) 📏

  • どんなフラクタル?: 線分を3等分し、中央の1/3を削除するというルールを繰り返すことで作られる、奇妙なフラクタルだよ。点しか残らないけど、長さは0ではない、という不思議な性質を持つ。

  • なぜ簡単?:

    • 1次元の描画: 線分なので、Y座標を固定してX座標だけで表現できる。

    • 再帰と単純な計算: コッホ曲線よりもさらに単純な計算で済む。

  • プログラミングのイメージ:

    1. ある線分の開始X座標と終了X座標、Y座標を受け取る関数を作る。

    2. 再帰の深さが0になったら、その線分を描画する。

    3. そうでなければ、線分を3等分し、中央の1/3の区間を無視する。

    4. 残りの左1/3と右1/3の線分に対して、自分自身(同じ関数)を呼び出す。再帰するごとにY座標を少しずつずらしていくと、視覚的に階層がわかりやすい。

    JavaScript

    // JavaScript (Canvas) でのイメージ
    function drawCantorSet(x1, x2, y, depth) {
        if (depth === 0) {
            // ベースケース: 線分を描画
            // context.moveTo(x1, y);
            // context.lineTo(x2, y);
            return;
        }
    
        const len = (x2 - x1) / 3; // 1/3の長さ
        drawCantorSet(x1, x1 + len, y + 20, depth - 1); // 左1/3の線分
        // 中央1/3は描画しない
        drawCantorSet(x2 - len, x2, y + 20, depth - 1); // 右1/3の線分
    }
    
    // 呼び出し例:
    // drawCantorSet(50, 450, 50, 5); // 深さ5で描画
    

プログラミングする上でのヒント 💡

  • 描画ライブラリの選定:

    • JavaScript: <canvas> APIが最適だよ。

    • Python: turtle モジュールや matplotlibPillow など。

    • Java: Swing/JavaFXのGraphicsオブジェクトを使う。

    • C#: WindowsフォームならGraphicsオブジェクトを使う。

  • 再帰の深さ (Depth):

    • あまり深くしすぎると、計算量が増えてブラウザがフリーズしたり、スタックオーバーフローになったりするから、最初は3〜6くらいで試すのがおすすめ。
  • 座標計算:

    • 数学のsin, cos, atan2, sqrtといった関数が役立つよ。
  • 色付け:

    • 再帰の深さによって色を変えると、フラクタルの構造がより美しく見えるよ!

これらのフラクタルは、シンプルなルールから驚くほど複雑で美しいパターンが生まれることを体験できるから、プログラミングの練習にも、そして数学とアートの融合としても、すごく面白い題材になるはずだよ!ぜひ挑戦してみてね!