【问题标题】:Recursive javascript function will not return to parent call data?递归javascript函数不会返回父调用数据?
【发布时间】:2014-11-26 00:40:01
【问题描述】:

我正在开发一个 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 语句不再正确,即当分支太小时,程序就会陷入递归循环,其中大小仍然太小。这是分支长度的控制台日志::

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

它应该达到递归循环的基本情况(分支长度太小)并返回到前一个递归循环,但看起来它只是一遍又一遍地检查相同的长度,0.78125。我不知道为什么,请帮忙!

【问题讨论】:

标签: javascript html recursion fractals


【解决方案1】:

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

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

它产生了一种向左的螺旋结构

事实上,只有一个全局 child 变量。当第一个 sub-makeChild 运行时,它重新分配这个全局 child 变量,第二个 sub-makeChild 以这个修改后的变量开始。

你可能想要

var child = {len_x: ...

http://jsfiddle.net/hLxe4fx1/

【讨论】:

  • 我不敢相信我错过了,但它仍然只画了一半的树,我不知道出了什么问题。
  • 你只在main中调用一次makeChildren
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2017-09-24
    • 1970-01-01
    • 2016-01-18
    • 2012-05-29
    • 2023-03-24
    • 2010-09-21
    • 2019-04-25
    • 2015-09-19
    相关资源
    最近更新 更多