似蓮花


我的作品中有個 Lotus-like flower,說是蓮花也並不是蓮花,只是長得像而已!

Lotus-like flower

因為是程式產生的,你可以決定它的花瓣數,這就不像是蓮花了,例如:

似蓮花

會覺得這像花朵,是因為自然界有些花的花瓣,確實是有著相同的規則排列,這個規則就是先前在 黃 金螺線 中談過的費式數列。

多條黃金螺線

黃金螺線 中,只談過如何建立一個黃金螺線,如果能建立數條黃金螺線,每條各轉動特定角度,會是如何呢?

spirals = 5;

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);
    }
}

linear_extrude(1) for(a = [0 : 360 / spirals : 360 - 360 / spirals]) {
    rotate(a) golden_spiral(1, 6, 0.5); 
}

/*
mirror([0, 1, 0]) linear_extrude(1) for(a = [0 : 360 / spirals : 360 - 360 / spirals]) {
    rotate(a) golden_spiral(1, 6, 0.5); 
}
*/

在 5 條黃金螺線、每條轉動 72 度的情況下,會產生以下的圖案:

似蓮花

如果你拿掉程式中的註解符號,那會產生順時針的 5 條黃金螺線,與原本逆時針的黃金螺線交錯,就會得到以下的圖案:

似蓮花

在 Google 圖片搜尋中尋找「fibonacci nature」,你一定看過類似的圖片,例如向日葵花的螺旋花序。

擺上花瓣

現在,我們只關注一條螺線,如果現在於該條螺線的位置中,擺上一個個的花瓣會如何呢?花瓣姑且先用個菱形替代吧!也就是使用 scale([2, 1, 1]) circle(r, $fn = 4) 來權充花瓣,也就是 golden_spiral 模組先改成以下:

// ...程式碼與之前相同...故略 

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

        offset = f2 - f1;

        linear_extrude(thickness, center = true) 
            scale([2, 1, 1]) circle(offset / 5, $fn = 4);

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

golden_spiral(5, 10, 1); 

circle 模組需要的半徑,是兩個費式數差的五分之一,這樣的話,就會有由小到大的花瓣,完成的圖案如下:

似蓮花

嗯?一點都不像花呢!?如果現在來個四條螺線好了:

spirals = 4;

// ...程式碼與之前相同...故略 

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

        offset = f2 - f1;

        linear_extrude(thickness, center = true) 
            scale([2, 1, 1]) circle(offset / 5, $fn = 4);

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

for(a = [0 : 360 / spirals : 360 - 360 / spirals]) {
    rotate(a) golden_spiral(5, 10, 1); 
}

就會產生以下的圖案:

似蓮花

感覺有那麼一點點接近了吧!只不過,每個花瓣現在都躺得平平的,現在,試著把每個花瓣立起來,這會使用到 rotate

// ...程式碼與之前相同...故略 

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

        offset = f2 - f1;

        rotate([0, 30, 0]) linear_extrude(thickness, center = true) 
            scale([2, 1, 1]) circle(offset / 5, $fn = 4);

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

// ...程式碼與之前相同...故略 

感覺如何呢?

似蓮花

有點像了,只不過太稀疏了一點,用 translate 調整一下每個花瓣的位置好了:

// ...程式碼與之前相同...故略 

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

        offset = f2 - f1;

        translate([5, 0, 0]) rotate([10, 30, 0]) 
linear_extrude(thickness, center = true) scale([2, 1, 1]) circle(offset / 5, $fn = 4); translate([0, -offset, 0]) rotate(90) golden_spiral(from + 1, to, thickness); } } // ...程式碼與之前相同...故略

喔喔!感覺更像了:

似蓮花

現在把 spirals 設成 8,並且將 golden_spiral 改名為 golden_petals,就會覺得神似蓮花了:

spirals = 8;

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_petals(from, to, thickness) {
    if(from <= to) {
        f1 = fibonacci(from);
        f2 = fibonacci(from + 1);

        offset = f2 - f1;

        translate([5, 0, 0]) rotate([10, 30, 0]) 
linear_extrude(thickness, center = true) scale([2, 1, 1]) circle(offset / 5, $fn = 4); translate([0, -offset, 0]) rotate(90) golden_petals(from + 1, to, thickness); } } for(a = [0 : 360 / spirals : 360 - 360 / spirals]) { rotate(a) golden_petals(5, 10, 1); }

出來的結果是這樣的:

似蓮花

這也解釋了,這類型花的花瓣,大致上如何生長排列的,當然,為了簡化範例,我用了平面的菱形,實際的花瓣是有曲面的,要怎麼做出有曲面的花瓣 呢?你可以想想,也可以偷看一下 Lotus-like flower 的原始碼,其中使用了一個簡單的方式,做出有曲面的花瓣!