Ошибка превышения максимального размера стека вызовов при реализации Fractal plant при обработке JS

Я пытаюсь реализовать фрактальный завод (до уровня - 6) при обработке javascript. Я получаю сообщение об ошибке «Превышен максимальный размер стека вызовов», хотя базовые условия выполняются.

Вот код: Первая функция пользовательской линии рисования рисует линию на основе длины, угла и исходной точки. Функция увеличения увеличивает угол на 25 градусов. Функция декремента уменьшает угол на 25 градусов.

var customDrawLine = function(x, y, length, angle)
{
    var f={x2:'', y2:''};
    f.x2 = x+(sqrt(sq(length)/(1+sq(tan (angle)))));
    f.y2 = y + ((f.x2-x) * tan (angle));
    line(x, y, f.x2, f.y2);
    return f;
};
var incrementAngle = function(angle)
{
    return (angle+25);
};
var decrementAngle = function(angle)
{
    return (angle-25);
};

var fProductionRule = function(x, y, z, degrees, flag)
{
    var l = {x1:'', y1:''};
    if(flag === 1)
    {
        for (var a=0; a<2;a++)
        {
           l = customDrawLine(l.x1, l.y1, z, degrees);
        }
    }
    else
    {
        l = customDrawLine(l.x1, l.y1, z, degrees);
    }
    return l;
};
var xProductionRule = function(x, y, degrees, nLevel, flag)
{
    var k = {x1:'', y1:''};
    var m;
    k.x1 = x;
    k.y1 = y;
    m = degrees;
    for(var z=0; z<7; z++)
    {
        var f = fProductionRule(k.x1, k.y1, (10-z), m, flag);
        m = incrementAngle(m);
        flag = 1;
        {
            {
                xProductionRule(f.x2,f.y2, m, z);
            }
            m = decrementAngle(m);
            xProductionRule(f.x2,f.y2, m, z);
        }
        m = decrementAngle(m);
        f = fProductionRule(k.x1, k.y1, (10-z), m, flag);
        {
            m = decrementAngle(m);
            f = fProductionRule(k.x1, k.y1, (10-z), m, flag);
            xProductionRule(f.x2,f.y2, m, z);
        }
        m = incrementAngle(m);
        xProductionRule(f.x2,f.y2, m, z);
       }
   };
var drawShape = function(x, y, degrees) 
{
   xProductionRule(x, y, degrees, 0, 0);
};
drawShape(10, 380, 25);

person Kanwar Pannu    schedule 19.12.2015    source источник
comment
Я использую страницу википедии ссылка для создания фрактального растения.   -  person Kanwar Pannu    schedule 19.12.2015
comment
пожалуйста, отформатируйте код   -  person Tamas Hegedus    schedule 19.12.2015
comment
Спасибо, теперь лучше читать! Кроме того, добро пожаловать в StackOverflow!   -  person Tamas Hegedus    schedule 19.12.2015
comment
Спасибо за теплый прием :-)   -  person Kanwar Pannu    schedule 19.12.2015
comment
Пожалуйста, упростите код, также используя f.x2=x+length*Math.cos(angle); f.y2=y+length*Math.sin(angle);. Также позаботьтесь о том, чтобы аргументы угла интерпретировались как в радианах. Если вы даете степени, вы должны сначала преобразовать.   -  person Lutz Lehmann    schedule 27.12.2015


Ответы (1)


Ваш код содержит бесконечную рекурсию, так как xProductionRule безоговорочно вызывает себя.

Чтобы рисовать фракталы, вы должны либо ограничить глубину рекурсии, либо запретить рендеринг частей меньше определенного размера (например, 1 пиксель).

Я вижу, что у xProductionRule есть 5 аргументов, один из них называется nLevel, но этот аргумент нигде не используется, по факту вы вызываете функцию всего с 4 параметрами. Я думаю, вы должны были использовать этот аргумент, чтобы ограничить глубину рекурсии. Добавьте некоторую проверку (nLevel < 7) в функцию и сделайте так, чтобы каждый рекурсивный вызов включал nLevel+1 в качестве параметра.

На мой взгляд, основываясь на упомянутой вами статье в Википедии, скелет вашего кода должен быть структурирован примерно так:

function drawA(depth, ... /* placement information */) {
    // here, draw the current branch
    // and then continue with it's children
    if (depth > 0) {
        drawA(depth - 1, ... /* derived placement information  */)
        drawB(depth - 1, ... /* another derived placement information  */)
    }
}

function drawB(depth, ... /* placement information */) {
    // here, draw the current branch
    // and then continue with it's children
    if (depth > 0) {
        drawA(depth - 1, ... /* derived placement information  */)
    }
}

drawA(7, ... /* placement of the root branch */)

Я не вижу места, где вам понадобилась бы 7-петля.

person Tamas Hegedus    schedule 19.12.2015
comment
Спасибо... Я заменил переменную nLevel на z из цикла. Также изменен цикл на (for(; z‹7;)) ‹br/›Все та же проблема - person Kanwar Pannu; 19.12.2015
comment
Честно говоря, я не очень понимаю, почему у вас вообще есть петля. По ссылке, на которую вы ссылаетесь, они рисуют растение, имея одного или двух дочерних элементов для каждого узла. Используя 7-кратный цикл, вы в основном делаете 7 дочерних элементов узла. - person Tamas Hegedus; 19.12.2015
comment
Я использую его для рисования растений до n=6. Не будет ли это работать таким образом? - person Kanwar Pannu; 19.12.2015
comment
Я думаю, что это не способ сделать это. Вам не нужны никакие циклы, но вам нужна правильная рекурсия. Я добавил код в свой ответ, чтобы дать вам некоторое представление. - person Tamas Hegedus; 19.12.2015