Рекурсия навсегда.

Фрактал - это структура, бесконечный узор, который формируется простым набором правил, применяемых рекурсивно. Природа полна фракталов. Деревья, реки, ракушки, ураганы…

Чтобы создать фрактал, мы собираемся начать с нуля и постепенно продвигаться. Мы будем использовать холст в качестве контекста рисования. Начнем с настройки холста.

const c = document.getElementById("myCanvas");
const ctx = c.getContext("2d");

Затем первый строительный блок - это функция для рисования линии на холсте от начальной точки (p0) до конечной точки (p1).

function drawLine(p0, p1, color="black"){
    ctx.beginPath();
    ctx.moveTo(p0.x, p0.y);
    ctx.lineTo(p0.x, p1.y);
    ctx.strokeStyle = color;
    ctx.stroke();
}

Давай поиграем с этим немного

for(var i=0; i<100; i++){ 
    let y = 400 - (400 / (i/2));
    drawLine({x:0, y}, {x: 400, y});
}

Хорошо, мы можем рисовать линии. Следующая наша задача - нарисовать треугольник.

function drawTriangle(p0, p1, p2) {
    drawLine(p0, p1)
    drawLine(p1, p2)
    drawLine(p2, p0)
}

Потом немного поигрался.

for(var i=0; i<100; i++){ 
    let y = i * 4;
    drawTriangle({x: 10, y}, {x: 150, y:10}, {x: 300, y}) 
}

Хорошо, хватит эксперимента. Как мы обсуждали ранее, фрактал формируется рекурсивной рукой, которая рисует одно и то же снова и снова в разных масштабах, не нарушая общей схемы.

На практике мы не можем рисовать бесконечные фрактальные узоры. Нам нужна максимальная глубина. Глубина, которая будет использоваться для завершения рекурсии.

function drawFract(p0, p1, p2, limit){
    if(limit > 0){
        const pA = {
           x: p0.x + (p1.x - p0.x)/2,
           y: p0.y - (p0.y - p1.y)/2
        };
        const pB = {
           x: p1.x + (p2.x - p1.x)/2,
           y: p1.y - (p1.y - p2.y)/2
        };
        const pC = {
           x: p0.x + (p2.x - p0.x)/2,
           y: p0.y
        };
        drawFract(p0, pA, pC, limit-1);
        drawFract(pA, p1, pB, limit-1);
        drawFract(pC, pB, p2, limit-1);
    } 
    else {
        drawTriangle(p0,p1,p2);    
    }
}

Для каждого уровня глубины мы делим область на три части (в нашем эксперименте три треугольника). Если достигнута конечная глубина, рисуется только треугольник. Например, максимальная глубина 1 создает три внутренних треугольника.

Вы можете получить полный исходный код на странице https://gist.github.com/yortuc/b065a0f08b09bf06f769e8a5100a885c

Удачного взлома.