Published
Edited
Dec 19, 2019
1 fork
2 stars
Insert cell
md`# Binary Tree`
Insert cell
paper = require("paper");
Insert cell
Insert cell
tree(1)
Insert cell
tree(2)
Insert cell
tree(3)
Insert cell
tree(4)
Insert cell
tree(5)
Insert cell
tree(6)
Insert cell
tree(7)
Insert cell
tree(8)
Insert cell
function tree(n=9, angle=45, width=450, height=500, root=475) {
let canvas = this || DOM.canvas(width, height);
let ps = canvas.ps || (() => {
let ps = new paper.PaperScope();
ps.setup(canvas);
return ps;
})();
canvas.ps = ps;
let axiom = ["0"];
let grammar = {
"0": ["1[0]0"],
"1": ["11"],
"[": "[",
"]": "]",
}
let code = axiom;
for (let i = 0; i < n; i++) {
code = code.map(l => grammar[l]).join("").split("")
}
console.log(code)
draw(grammar, ps, code, angle, height / Math.pow(2,n), root, width);

return canvas;
}
Insert cell
function draw(grammar, ps, code, rotate, magnitude, root, width) {
let angle = Math.PI / 2;
let start = new ps.Point(width / 2, 475);
let stack = []
let curr = start;
let next = start;
let state = new State(curr, angle);
for (let char of code) {
switch(char) {
case "1":
next = new ps.Point(get_next(curr, angle, magnitude));
let seg = ps.Path.Line(curr, next);
seg.strokeColor = "black";
curr = next;
break;
case "0":
next = new ps.Point(get_next(curr, angle, magnitude));
let leaf = new ps.Path.Line(curr, next);
leaf.strokeColor = "black";
curr = next;
break;
case "[":
stack.push(new State(new paper.Point(curr), angle));
angle = turn_left(angle, rotate);
break;
case "]":
state = stack.pop();
curr = state.curr;
angle = turn_right(state.angle, rotate);
break;
}
}
}

Insert cell
function turn_left(angle, rotate) {
const left = rotate / 180 * Math.PI;
return (angle + left) % (2 * Math.PI);
}
Insert cell
function turn_right(angle, rotate) {
const right = rotate / 180 * Math.PI;
return (angle - right) % (2 * Math.PI);
}
Insert cell
function get_next(curr, angle, magnitude) {
let x = magnitude * Math.cos(angle);
let y = magnitude * Math.sin(angle);
return new paper.Point(curr.x + x, curr.y - y);
}
Insert cell
class State {
constructor(curr, angle) {
this.curr = curr;
this.angle = angle;
}
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more