递归javascript函数不会返回父调用数据?

时间:2014-11-26 00:40:02

标签: javascript html5 recursion fractals

我正在开发一个HTML5 / JS项目,用于在画布上绘制二进制分形树。

HTML5 ::

<!DOCTYPE html>
<html>
  <body>
    <canvas id="canvas1" width="500" height="500"></canvas>
    <br />
    <script src="tree.js"></script>
    <button id="button1" type="button" onclick="main()">Start</button>
  </body>
</html>

的Javascript ::

var scale = 0.5;
var min_len = 1;
//setup canvas
var c = document.getElementById("canvas1");
var ctx = c.getContext("2d");
ctx.moveTo(250, 500);

//returns length of branch
function len(branch) {

    return Math.sqrt( Math.pow(branch.len_x, 2) + Math.pow(branch.len_y, 2) );
}

//draws from start to length of branch
function drawBranch(start, branch) {

    ctx.moveTo(start.x, start.y);
    ctx.lineTo(start.x + branch.len_x, start.y - branch.len_y);
    ctx.stroke();
}

//recursively builds binary fractal tree
function makeChildren(start, theta, parent) {

    if(len(parent) >= min_len) {
        drawBranch(start, parent);

        //linear transformation applied to parent branch which rotates and scales to produce child branch
        child = {len_x: ( parent.len_x * Math.cos(theta) - parent.len_y * Math.sin(theta) ) * scale,
                 len_y: ( parent.len_x * Math.sin(theta) + parent.len_y * Math.cos(theta) ) * scale};

        //recursively build left and right branches of tree
        makeChildren( {x: start.x + parent.len_x, y: start.y - parent.len_y}, theta, child);
        makeChildren( {x: start.x + parent.len_x, y: start.y - parent.len_y}, theta * (-1), child);
    }
}

function main() {

    //initialize tree
    makeChildren( {x: 250, y: 500}, Math.PI / 4, {len_x: 0, len_y: 100} );
}

当我运行我的代码时,它产生一个面向左侧的螺旋结构(抱歉无法发布图像)。

问题在于makeChildren函数中的长度检查,一旦if语句不再为真,即当分支太小时,程序就会陷入递归循环,其中大小仍然太小。这是分支长度::

的控制台日志

[Log] 100(tree.js,第24行)

[日志] 49.99999999999999(tree.js,第24行)

[Log] 25(tree.js,第24行)

[Log] 12.5(tree.js,第24行)

[Log] 6.25(tree.js,第24行)

[日志] 3.125(tree.js,第24行)

[日志] 1.5624999999999998(tree.js,第24行)

[Log] 0.7812499999999999(tree.js,第24行)

[Log] 0.7812499999999999(tree.js,第24行)

[Log] 0.7812499999999999(tree.js,第24行)

[Log] 0.7812499999999999(tree.js,第24行)

[Log] 0.7812499999999999(tree.js,第24行)

[Log] 0.7812499999999999(tree.js,第24行)

[Log] 0.7812499999999999(tree.js,第24行)

[Log] 0.7812499999999999(tree.js,第24行)

它应该达到递归循环的基本情况(分支长度太小)并返回到先前的递归循环,但看起来它只是一遍又一遍地检查相同的长度,0.78125。我无法弄清楚原因,请帮忙!

2 个答案:

答案 0 :(得分:1)

  

一遍又一遍地检查相同长度,0.78125

每个级别的递归都会使调用次数加倍。它将达到基本情况,如...... 128(?)次。

  

它产生一个面向左侧的螺旋形结构

实际上,只有一个全局child变量。当第一个子makeChild运行时,它会重新分配此全局child变量,第二个子makeChild将以此修改后的变量开始。

你可能想要

var child = {len_x: ...

http://jsfiddle.net/hLxe4fx1/

答案 1 :(得分:0)

我得出了相同的结论,但客人比我快:)要知道为什么会发生这种情况,请记住Objects are Passed by Referencechild未定义,它位于全球scope

另一个jsfiddle http://jsfiddle.net/6pjduncg/