Golden spiral


Golden spiral generator is a thing which may be a base for my further designs. It creates golden spirals linearly extruded with different parameters, such as scale, twist and so on.

Fibonacci sequence

One way to create a golden spiral is knowing how to generate the Fibonacci sequence. Almost all programmers take it as an exercise when they enter programming. When using OpenSCAD, we can obtain the n-th Fibonacci number from the following.

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

The Fibonacci sequence appears in biological settings. If you google search “Fibonacci nature” on images.google.com, you'll find many pictures of it. My thing Lotus-like flower also bases on the Fibonacci sequence.

Lotus-like flower

Golden rectangle

The Golden spiral on Wikipedia has a picture of a golden rectangle. It's a tiling with squares whose side lengths are successive Fibonacci numbers.

Golden rectangle

Let's use OpenSCAD to create a model like the above picture.

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

There's no problem to draw a square which uses a Fibonacci number as the side length. The point is observing that you have to rotate 90 degrees for each square and move double side length to align the side. The generated golden rectangle is as below.

Golden spiral

Golden spiral

You may create a golden spiral by drawing circular arcs connecting the opposite corners of squares in the Fibonacci tiling. The Fibonacci numbers are the radiuses of the arcs.

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

The golden spiral is shown below.

Golden spiral

Now you have an exercise. The above spiral is counter-clockwise. How to make a clockwise spiral? And, how to create a thing such as Golden spiral generator which can generate different visual effects?