I'm working on an HTML5/JS project to draw a binary fractal tree on a canvas.
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} );
}
When I run my code it produces a left-ward facing spiral kind of structure (sorry can't post images yet).
The problem is with the length check in the makeChildren function, once the if statement is not longer true i.e. when the branch is too small, the program gets caught in a recursive loop where the size remains too small. Here's the console log of the branch lengths::
[Log] 100 (tree.js, line 24)
[Log] 49.99999999999999 (tree.js, line 24)
[Log] 25 (tree.js, line 24)
[Log] 12.5 (tree.js, line 24)
[Log] 6.25 (tree.js, line 24)
[Log] 3.125 (tree.js, line 24)
[Log] 1.5624999999999998 (tree.js, line 24)
[Log] 0.7812499999999999 (tree.js, line 24)
[Log] 0.7812499999999999 (tree.js, line 24)
[Log] 0.7812499999999999 (tree.js, line 24)
[Log] 0.7812499999999999 (tree.js, line 24)
[Log] 0.7812499999999999 (tree.js, line 24)
[Log] 0.7812499999999999 (tree.js, line 24)
[Log] 0.7812499999999999 (tree.js, line 24)
[Log] 0.7812499999999999 (tree.js, line 24)
It should reach the base case for the recursive loop (branch length too small) and return to the previous recursive loop, but it looks like it just keeps checking the same length, 0.78125, over and over again. I can't figure out why, please help!
Each level of recursion doubles the number of calls. It's going to reach that base case like ... 128 (?) times.
As it is, there's a single global
child
variable. When the first sub-makeChild
runs, it reassigns this globalchild
variable, and the second sub-makeChild
starts with this modified one.You probably wanted
http://jsfiddle.net/hLxe4fx1/