-
Notifications
You must be signed in to change notification settings - Fork 0
/
fractal-tree.js
71 lines (59 loc) · 1.84 KB
/
fractal-tree.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
class Tree {
/**
* Fractal tree
* @param {CanvasRenderingContext2D} ctx2d
* @param {Vector2} origin
*/
constructor(ctx2d, origin, options = {
branchLength: 100,
levels: 10,
leanFactor: 15,
growthFactor: 0.8
}) {
this.ctx = ctx2d;
this.origin = origin;
this.cfg = options;
}
setConfig(config, value) {
this.cfg[config] = value;
}
drawTree() {
// Clear canvas
this.ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
// Start tree
this.drawBranch(this.cfg.levels, origin, 90, this.cfg.branchLength);
}
/**
* Draws a tree branch in the tree's canvas context.
* @param {number} level Branch level
* @param {Vector2} origin Origin vector
* @param {number} direction Direction in degrees
* @param {number} subBranches Amount of sub branches
*/
drawBranch(level, origin, direction, length) {
// Branch existance conditions
if (level < 1) return;
level--;
// Canvas context
const ctx = this.ctx;
// Branch properties
const angle = degToRad(direction);
// Calculate end vector
const target = new Vector2(
origin.x + Math.cos(angle) * length,
origin.y - Math.sin(angle) * length
);
// Make path
ctx.beginPath();
ctx.moveTo(origin.x, origin.y);
ctx.lineTo(target.x, target.y);
// Draw path
this.ctx.stroke();
// Make new branches
const nextLean = this.cfg.leanFactor;
const nextLength = length * this.cfg.growthFactor
this.drawBranch(level, target, direction + nextLean, nextLength);
this.drawBranch(level, target, direction - nextLean, nextLength);
return target;
}
}