forked from nikoladimitroff/canvas-demos
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkochs-snoflake.html
115 lines (94 loc) · 2.75 KB
/
kochs-snoflake.html
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<canvas id="flake" width="100%" height="100%">
<style>
html, body {
margin: 0;
padding: 0;
}
</style>
<script src="js/vector.js"></script>
<script src="js/resizer.js"></script>
<script>
var canvas = document.getElementById("flake"),
context = canvas.getContext("2d");
Resizer.installHandler(canvas);
var Triangle = function (p, q, r) {
this.points = [p, q, r];
}
var Line = function (p, q) {
this.points = [p, q];
}
function sign(x) {
if (x == 0) return 0;
if (x > 0) return 1;
return -1;
}
var center = new Vector2(0, 0);
function generateLines(p, q) {
var dist = p.distTo(q);
var middle = new Vector2((p.x + q.x) / 2, (p.y + q.y) / 2);
var size = dist / 3;
var normal = new Vector2((q.y - p.y) / (q.x - p.x), -1);
var normSize = Math.sqrt(3) / 2 * size;
var edge = p.sub(center);
var dotSign = sign(edge.dot(normal));
normal.normalize();
normal.scale(dotSign * normSize);
var first = new Vector2(1/3 * p.x + 2/3 * q.x, 1/3 * p.y + 2/3 * q.y);
var second = new Vector2(2/3 * p.x + 1/3 * q.x, 2/3 * p.y + 1/3 * q.y);
var third = new Vector2(middle.x + normal.x, middle.y + normal.y)
return [new Line(p, second), new Line(first, q), new Line(first, third), new Line(second, third)]
;
}
var size = 0.85 * Math.min(canvas.width, canvas.height);
var x = canvas.width / 2 - size / 2,
y = canvas.height / 2 + size / 3.4;
var first = new Vector2(x, y);
var second = new Vector2(x + size, y);
var third = new Vector2(x + size / 2, y - Math.sqrt(3) / 2 * size);
var lines = [
new Line(first, second),
new Line(first, third),
new Line(second, third)
];
center.x = 1/3 * (first.x + second.x + third.x),
center.y = 1/3 * (first.y + second.y + third.y);
var MAX_ITERATIONS = 5;
var iterations = 0;
function update() {
var next = [];
for (var i = 0; i < lines.length; i++) {
var points = lines[i].points;
var generated = generateLines(points[0], points[1]);
for (var j = 0; j < generated.length; j++) {
next.push(generated[j]);
}
}
lines = next;
if (iterations < MAX_ITERATIONS) {
iterations++;
setTimeout(update, 1000);
}
}
var color = "red";
function drawLine(p, q, color) {
context.beginPath();
context.strokeStyle = color;
context.moveTo(p.x, p.y);
context.lineTo(q.x, q.y);
context.closePath();
context.stroke();
}
function draw() {
context.clearRect(0, 0, canvas.width, canvas.height);
for (var j = 0; j < lines.length; j++) {
var points = lines[j].points;
drawLine(points[0], points[1], color);
}
requestAnimationFrame(draw);
}
function loop() {
draw();
setTimeout(update, 1000);
}
loop();
</script>