Fibonacci sequence animation

556 views Asked by At

I am currently attempting to program the Fibonacci Sequence animation on a HTML5 canvas using JavaScript.

I have calculated the Fibonacci numbers and am able to add the squares to a grid layout. The trouble I am having is being able to calculate the offset so they will automatically fit together side by side nicely. Does anyone have any pointers to how this can be achieved.

here is my JavaScript Code:

var canvas;
var context;

function init(){

    canvas = document.getElementById('canvas');
    context = canvas.getContext('2d');

    drawgrid();
    drawlines();

}


function drawgrid(){

    context.strokeStyle="LightGrey";

    for(var i = 0; i < 600; i+=20){

        context.beginPath();
        context.moveTo(i, 0);
        context.lineTo(i, 600);
        context.stroke();

        context.beginPath();
        context.moveTo(0, i);
        context.lineTo(600, i);
        context.stroke();

    }

}

function drawlines(){

    context.strokeStyle="blue";
    var startLeft = (canvas.width / 2) - 20;
    var startTop = (canvas.height / 2) - 20;

    var first = 1;
    var second = 1;
    var next = 0;
    var c = 0;
    var count = 0;

    for (var i = 0; i < 5; i++){

        if ( c <= 1 ){

            next = 1;

        }else{

            next = first + second;
            first = second;
            second = next;

        }

        c++;
        next *= 20;


        //This is a minor attempt at offsetting which does not work what so ever
        switch(count) {
            case 1:
                startLeft += next;
                break;
            case 2:
                startTop-=next;
                break;
            case 3:
                startTop -= next - 20;
                startLeft -= next;
                break;
            case 4:
                startTop += next - 80;
                startLeft += next - 160;
                break;
        }

        context.beginPath();
        context.rect(startLeft,startTop,next,next);
        context.stroke();

        count++;

        if (count > 4){

            count = 1;

        }

        startLeft = (canvas.width / 2) - 20;
        startTop = (canvas.height / 2) - 20;

    }

}

JSFiddle: http://jsfiddle.net/schoolboytom/73prkp8L/

1

There are 1 answers

0
Julien Grégoire On BEST ANSWER

One way would be to keep track of all coordinates at all times and increment depending of the orientation of the following square to place. I think your whole structure is ok, but there are some info lacking, mainly keeping bottom and right coordinates.

Something like this seems to work (I've put increment of 10 to see if the logic was ok, but it should work with any):

function drawlines() {

    context.strokeStyle = "blue";
    var curLeft = (canvas.width / 2) - 10;
    var curTop = (canvas.height / 2) - 10;
    //You add right and bottom position to help calculate positioning later.
    var curRight = curLeft + 10;
    var curBottom = curTop + 10;

    var first = 0;
    var second = 1;
    var next = 10;
    var c = 0;
    //You draw the first square out of the loop cause it's conditions are
    //not exactly the same, meaning its positioning is not dependent on previous square
    context.beginPath();
    context.rect(curLeft, curTop, next, next);
    context.stroke();

    for (var i = 1; i <= 9; i++) {

        next = first + second;
        first = second;
        second = next;

        next *= 10;
        //changed this to fetch if square should be added right, top, left or bottom
        count = i % 4

        //You switch depending on where you're at. Each direction has its increment pattern.
        //For example to add right you keep bottom, but get current right to get left positioning
        //and you increment top depending on next value. The structure is 
        //similar to yours but since you now have right and bottom it's 
        //easier to place each square correctly
        switch (count) {
            case 0:

                curRight = curLeft + next
                curLeft = curLeft
                curTop = curBottom
                curBottom = curBottom + next

                break;
            case 1:
                curLeft = curRight
                curRight = curRight + next
                curTop = curBottom - next
                curBottom = curBottom

                break;

            case 2:
                curLeft = curRight - next
                curRight = curRight
                curBottom = curTop
                curTop = curBottom - next
                break;
            case 3:
                curRight = curLeft
                curLeft = curLeft - next
                curBottom = curTop + next
                curTop = curTop
                break;
        }
       // the rest is pretty much the same
        context.beginPath();
        context.rect(curLeft, curTop, next, next);
        context.stroke();

        count++;

    }

}

See fiddle: http://jsfiddle.net/a0aLg6Ly/3/