-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
116 lines (105 loc) · 3.96 KB
/
index.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
116
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="Tomo Wang">
<title>Koch Snowflake</title>
<style>
html, body {
margin: 0;
padding: 0;
}
#container {
margin: auto;
}
svg path {
fill: #fff;
stroke: #000;
stroke-width: 1;
}
</style>
</head>
<body>
<!-- Placed at the end of the document so the pages load faster -->
<div id="container"><svg><path></path></svg></div>
<script type="text/javascript" src="dat.gui.min.js"></script>
<script>
var PI = Math.PI, sin = Math.sin, cos = Math.cos, tan = Math.tan, atan = Math.atan;
function distance (x1, y1, x2, y2) {
return Math.sqrt((x1 -= x2) * x1 + (y1 -= y2) * y1);
}
// given two points, return five koch points
function koch(s, e) {
var x1 = s[0], y1 = s[1], x2 = e[0], y2 = e[1],
oneThird_x = (x2 - x1) / 3, oneThird_y = (y2 - y1) / 3,
d = distance(x1, y1, x2, y2),
p = [
[x1, y1],
[x1 + oneThird_x, y1 + oneThird_y],
[0, 0], // to be calculated
[x1 + oneThird_x * 2, y1 + oneThird_y * 2],
[x2, y2]
];
var r = d / 2 / cos(PI / 6), angle = 0;
if (x2 == x1) {
angle = y2 - y1 > 0 ? PI / 2 : -PI / 2;
} else {
angle = atan((y2 - y1) / (x2 - x1));
if (x2 - x1 < 0) {
angle = angle + PI;
}
}
angle = angle + PI / 6;
p[2][0] = x1 + cos(angle) * r;
p[2][1] = y1 + sin(angle) * r;
return p;
}
var div = document.getElementById('container');
var svg = document.querySelector('svg');
var path = document.querySelector('path');
var Snowflake = function () {
this.radius = 600;
this.iterate = 4;
};
Snowflake.prototype.render = function () {
var radius = this.radius,
iterate = this.iterate;
// three init points of triangle
var triangle = [[radius / 2, 0], [0, radius * sin(PI / 3)], [radius, radius * sin(PI / 3)]];
var s, e, points, new_points, p, all_points = [];
div.style.width = radius + 'px';
svg.setAttribute('width', radius + '');
svg.setAttribute('height', radius / sin(PI / 3) + '');
for (var k = 0; k < 3; k++) {
s = triangle[k];
e = triangle[(k + 1) % 3];
points = koch(s, e);
for (var i = 0; i < iterate; i++) {
new_points = [];
for (var j = 0; j < points.length - 1; j++) {
s = points[j];
e = points[j+1];
new_points.pop();
p = koch(s, e);
new_points = new_points.concat(p);
}
points = new_points;
}
all_points = all_points.concat(points);
all_points.pop();
}
path.setAttribute('d', 'M' + all_points.join('L') + 'z');
};
window.onload = function() {
var snowflake = new Snowflake();
var gui = new dat.GUI();
gui.add(snowflake, 'radius').min(200).max(800).step(100).onFinishChange(snowflake.render.bind(snowflake));
gui.add(snowflake, 'iterate').min(2).max(6).step(1).onFinishChange(snowflake.render.bind(snowflake));
snowflake.render();
};
</script>
</body>
</html>