海龜也懂碎形


在〈自相似的碎形〉中談過,自相似性是一種內在重複的模式,是另一種規律,如果給予海龜自相似性的規律,它也能畫出碎形。

來讓海龜畫出一棵樹吧!在這之前,必須讓海龜能畫出一個 Y,這很簡單,如果海龜一開始是頭朝上,從 Y 有底部開始,必須前進、轉彎、前進,接著沿原路爬回 Y 的分岐點,調整為頭朝上,轉彎、前進…

就目前的 Turtle 實作來說,是也能做到沿原路爬回,不過要多個 forwardturn 步驟來組成,比較麻煩,為了寫程式上的方便,這邊在 Turtle 增加 pushpop 兩個方法:

class Turtle {
    constructor(x = 0, y = 0, angle = 0) {
        this.coordinateVector = createVector(x, y);
        this.headingVector = createVector(1, 0).rotate(angle);
        this.state = [];  // 儲存海龜目前狀態
    }

    …略

    // 將目前狀態置入堆疊
    push() {
        this.state.push(new Turtle(
            this.coordinateVector.x,
            this.coordinateVector.y,
            this.headingVector.heading()
        ));
    }

    // 將堆疊頂的第一個狀態彈出,作為目前海龜狀態
    pop() {
        const t = this.state.pop();
        this.coordinateVector = t.coordinateVector;
        this.headingVector = t.headingVector;
    }
}

如果目前海龜已來到一個狀態,無論後續操作為何,想回到目前狀態的話,就使用 push 先保存狀態,之後若想回復,就 pop 彈出狀態,這就相當於海龜沿原路爬回該狀態了。

先來畫個 Y:

如果每個分支也都是個 Y 呢?

那就長成一棵樹了,只不過因為分支的長度與角度是固定的,使得這棵規律到太不自然了,若故意加入一些隨機:

看來就比較自然一些了,如果要製造點樹搖曳的感覺,可以只令分支角度隨機變化的幅度小一些,結合動畫就會有點像了: