黃金螺線


Golden spiral generator 是用來作為日後設計基礎的一個作品,它會產生一或數條黃金螺線,配合 linear_extrude 模組,在拉高的過程中調整 scaletwist 等參數,就能產生以下的圖案:

Golden spiral generator

Fibonacci 數列

想要建立黃金螺線,必須先知道如何產生 Fibonacci 數列,這是在學習程式設計的初學階段,很常用來練習的一個小題目,使用 OpenSCAD 來實作的話,想要求得第 n 個 Fibonacci 數字的話,可以這麼撰寫:

function fibonacci(nth) = 
    nth == 0 || nth == 1 ? nth : (
        fibonacci(nth - 1) + fibonacci(nth - 2)
    );

自然界有許多現象,都符合 Fibonacci 數列的規則,在 Google 的圖片搜尋中,鍵入 fibonacci nature,就可以找到許多這類的圖片,而我設計的 Lotus-like flower,也是使用 Fibonacci 數列來建立。

Lotus-like flower

黃金矩形

在維基百科的 費 氏數列 條目中,有個黃金矩形圖片,其由數個正方形組成,而正方形的邊長關係,就符合 Fibonacci 數列:

黃金矩形

我們來試著使用 OpenSCAD 建立這樣的圖案:

function fibonacci(nth) = 
    nth == 0 || nth == 1 ? nth : (
        fibonacci(nth - 1) + fibonacci(nth - 2)
    );

module line(point1, point2, width = 1, cap_round = true) {
    angle = 90 - atan((point2[1] - point1[1]) / (point2[0] - point1[0]));
    offset_x = 0.5 * width * cos(angle);
    offset_y = 0.5 * width * sin(angle);

    offset1 = [-offset_x, offset_y];
    offset2 = [offset_x, -offset_y];

    if(cap_round) {
        translate(point1) circle(d = width, $fn = 24);
        translate(point2) circle(d = width, $fn = 24);
    }

    polygon(points=[
        point1 + offset1, point2 + offset1,  
        point2 + offset2, point1 + offset2
    ]);
}

module polyline(points, width = 1) {
    module polyline_inner(points, index) {
        if(index < len(points)) {
            line(points[index - 1], points[index], width);
            polyline_inner(points, index + 1);
        }
    }

    polyline_inner(points, 1);
}


module golden_rectangle(from, to, thickness) {
    if(from <= to) {
        f1 = fibonacci(from);
        f2 = fibonacci(from + 1);

        polyline([[0, 0], [f1, 0], [f1, f1], [0, f1], [0, 0]], thickness);

        offset = f2 - f1;

        translate([0, -offset, 0]) rotate(90)
            golden_rectangle(from + 1, to, thickness);
    }
}

golden_rectangle(1, 6, 0.1);

以 Fibonacci 數為邊長,畫出正方形基本上應該沒有問題,重點在於觀察出,每個正方形與下一個正方形,會有 90 度的角度差,為了對齊邊長,必須再位移兩個正方形的邊長差,產生的黃金矩形如下:

黃金矩形

黃金螺線

黃金螺線實際上就是將黃金矩形中每個正方形的兩個對角,使用一個弧連接起來,弧的半徑就是 Fibonacci 數:

function fibonacci(nth) = 
    nth == 0 || nth == 1 ? nth : (
        fibonacci(nth - 1) + fibonacci(nth - 2)
    );

module sector(radius, angles, fn = 24) {
    r = radius / cos(180 / fn);
    step = -360 / fn;

    points = concat([[0, 0]],
        [for(a = [angles[0] : step : angles[1] - 360]) 
            [r * cos(a), r * sin(a)]
        ],
        [[r * cos(angles[1]), r * sin(angles[1])]]
    );

    difference() {
        circle(radius, $fn = fn);
        polygon(points);
    }
}

module arc(radius, angles, width = 1, fn = 24) {
    difference() {
        sector(radius + width, angles, fn);
        sector(radius, angles, fn);
    }
} 

module golden_spiral(from, to, thickness) {
    if(from <= to) {
        f1 = fibonacci(from);
        f2 = fibonacci(from + 1);

        arc(f1, [0, 90], thickness, 48);

        offset = f2 - f1;

        translate([0, -offset, 0]) rotate(90)
            golden_spiral(from + 1, to, thickness);
    }
}

golden_spiral(1, 6, 1); 

產生的黃金螺線如下:

黃金螺線

接下來就是你的功課了,上面的黃金螺線是逆時針方向,要如何能讓它順時針方向呢?以及,要如何能做出如 Golden spiral generator ,可以有數條黃金螺線等各種效果呢?