UNPKG

2.81 kBJavaScriptView Raw
1goog.require('ol.Feature');
2goog.require('ol.Map');
3goog.require('ol.View');
4goog.require('ol.geom.LineString');
5goog.require('ol.layer.Vector');
6goog.require('ol.source.Vector');
7
8var radius = 10e6;
9var cos30 = Math.cos(Math.PI / 6);
10var sin30 = Math.sin(Math.PI / 6);
11var rise = radius * sin30;
12var run = radius * cos30;
13
14var triangle = new ol.geom.LineString([
15 [0, radius], [run, -rise], [-run, -rise], [0, radius]
16]);
17
18var feature = new ol.Feature(triangle);
19
20var layer = new ol.layer.Vector({
21 source: new ol.source.Vector({
22 features: [feature]
23 })
24});
25
26var map = new ol.Map({
27 layers: [layer],
28 target: 'map',
29 view: new ol.View({
30 center: [0, 0],
31 zoom: 1
32 })
33});
34
35function makeFractal(depth) {
36 var geometry = triangle.clone();
37 var graph = coordsToGraph(geometry.getCoordinates());
38 for (var i = 0; i < depth; ++i) {
39 var node = graph;
40 while (node.next) {
41 var next = node.next;
42 injectNodes(node);
43 node = next;
44 }
45 }
46 var coordinates = graphToCoords(graph);
47 document.getElementById('count').innerHTML = coordinates.length;
48 geometry.setCoordinates(coordinates);
49 feature.setGeometry(geometry);
50}
51
52function injectNodes(startNode) {
53 var endNode = startNode.next;
54
55 var start = startNode.point;
56 var end = startNode.next.point;
57 var dx = end[0] - start[0];
58 var dy = end[1] - start[1];
59
60 // first point at 1/3 along the segment
61 var firstNode = {
62 point: [start[0] + dx / 3, start[1] + dy / 3]
63 };
64
65 // second point at peak of _/\_
66 var r = Math.sqrt(dx * dx + dy * dy) / (2 * cos30);
67 var a = Math.atan2(dy, dx) + Math.PI / 6;
68 var secondNode = {
69 point: [start[0] + r * Math.cos(a), start[1] + r * Math.sin(a)]
70 };
71
72 // third point at 2/3 along the segment
73 var thirdNode = {
74 point: [end[0] - dx / 3, end[1] - dy / 3]
75 };
76
77 startNode.next = firstNode;
78 firstNode.next = secondNode;
79 secondNode.next = thirdNode;
80 thirdNode.next = endNode;
81}
82
83
84function coordsToGraph(coordinates) {
85 var graph = {
86 point: coordinates[0]
87 };
88 var length = coordinates.length;
89 for (var level = 0, node = graph; level < length - 1; ++level) {
90 node.next = {
91 point: coordinates[level + 1]
92 };
93 node = node.next;
94 }
95 return graph;
96}
97
98function graphToCoords(graph) {
99 var coordinates = [graph.point];
100 for (var node = graph, i = 1; node.next; node = node.next, ++i) {
101 coordinates[i] = node.next.point;
102 }
103 return coordinates;
104}
105
106var depthInput = document.getElementById('depth');
107
108function update() {
109 makeFractal(Number(depthInput.value));
110}
111
112var updateTimer;
113
114
115/**
116 * Regenerate fractal on depth change. Change events are debounced so updates
117 * only occur every 200ms.
118 */
119depthInput.onchange = function() {
120 window.clearTimeout(updateTimer);
121 updateTimer = window.setTimeout(update, 200);
122};
123
124update();