I recently saw this video about the dragon curve in Jurassic park and being the completely incorrigible nerd that I am, I figured “How hard can it be to build that thing”. In javascript. Cause fuck it, I guess.

The best explanation I found on how to actually generate it was this wikipedia article. More specifically there is a very elegant iteration function system that doesn’t even involve the complex plane (from my limited research, that complex plane seems to be pretty unavoidable when dealing with fractals)

Pictured: Math Pictured: Math

But because I’m terrified of matrix transformations I wanted to solve it another way. Basically: the way you would physically fold some paper (as explained in the video above)

Pictured: Not Math Pictured: Not Math

The general rule is this: Turn every line-segment into a 90 degree corner, alternating between “turning” right and turning left. So with an array “lines” starting with an original one that I arbitrarily put somewhere, every iteration does the following:

        // start rotation to the right
        rotationAngle = 45;
    
        for(var i in lines) {
            var originalLine = lines[i];
    
            var p1 = originalLine[0];
            var p2 = originalLine[1];
    
            // pytharogas, bitches
            var d = Math.sqrt(Math.abs(p1.x - p2.x) + Math.abs(p1.y - p2.y));
            // squares. Math.
            var distanceToP2 = Math.sqrt(2 * Math.pow(d/2, 2));
    
            var r = distanceToP2 / d;
    
            // this is the halfway point between point1 and point2
            var p3 = {
                'x': r * p2.x + (1 - r) * p1.x,
                'y': r * p2.y + (1 - r) * p1.y
            };
    
            // first line takes over p1 of original
            var line1 = [originalLine[0]];
    
            // rotate the halfway-point around p1 45 degrees OR -45 degrees
            var line1p2 = rotate_point(p3.x, p3.y, line1[0].x, line1[0].y, rotationAngle);
            line1.push(line1p2);
    
            // line 2 starts with p2 of line1 and ends with p2 of the original line
            var line2 = [line1p2, originalLine[1]];
    
            newLines.push(line1);
            newLines.push(line2);
    
            // alternate rotation angle
            rotationAngle *= -1;
        }
    
        lines = newLines;
    
        // this just draws lines on a canvas. Boring stuff.
        drawLines();

rotate_point just does this:

    function rotate_point(pointX, pointY, originX, originY, angle) {
        angle = angle * Math.PI / 180.0;
        return {
            x: Math.cos(angle) * (pointX-originX) - Math.sin(angle) * (pointY-originY) + originX,
            y: Math.sin(angle) * (pointX-originX) + Math.cos(angle) * (pointY-originY) + originY
        };
    }

The more mathematical-minded among you will notice this does exactly what the matrix-transformation does, but with steps in between.

Try it out below!