forked from trpomoais2018/fg02-lsystem
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLsystem.js
60 lines (56 loc) · 1.88 KB
/
Lsystem.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
class LSystem {
constructor(axiom, rule) {
this.axiom = axiom;
this.rule = rule;
}
buildSequence(depth) {
let result = this.axiom;
for (let i = 0; i < depth; i++) {
let sequence1 = "";
for (let j = 0; j < result.length; j++) {
if (this.rule[result[j]] === undefined)
sequence1 += result[j];
else
sequence1 += this.rule[result[j]];
}
result = sequence1;
}
return result;
}
}
const snowflacke = new LSystem("[F]+[F]+[F]+[F]+[F]+[F]", {"F" : "F[+FF][-FF]FF[+F][-F]FF"});
const bush = new LSystem("F", {"F" : "-F+F+[+F-F-]-[-F+F+F]"});
function drawFractal(fractal, context, startPos) {
context.beginPath();
if(fractal == "bush") {
drawFigure(startPos, context, {system : bush, depth : 5, length : 10, angle : Math.PI/8})
}
else{
drawFigure(startPos, context, {system : snowflacke, depth : 3, length : 3, angle : Math.PI/3})
}
context.stroke();
}
function drawFigure(position, context, figure) {
const sequence = figure.system.buildSequence(figure.depth);
const actions = buidRulesRunner(context, position, figure.length, figure.angle);
for (let i = 0; i < sequence.length; i++) {
if (actions[sequence[i]] != undefined)
actions[sequence[i]]();
}
}
function buidRulesRunner(drawingContext, startPos, length, angle) {
let position = startPos;
let stack = [];
let alphabet = {};
alphabet['F'] = () => {
drawingContext.moveTo(position.x, position.y);
position.x += Math.cos(position.angle) * length;
position.y += Math.sin(position.angle) * length;
drawingContext.lineTo(position.x, position.y);
}
alphabet['+'] = () => position.angle += angle;
alphabet['-'] = () => position.angle -= angle;
alphabet['['] = () => stack.push({x: position.x, y:position.y, angle: position.angle });
alphabet[']'] = () => position = stack.pop();
return alphabet;
}