1 | goog.require('ol.Feature');
|
2 | goog.require('ol.Map');
|
3 | goog.require('ol.View');
|
4 | goog.require('ol.geom.LineString');
|
5 | goog.require('ol.layer.Vector');
|
6 | goog.require('ol.source.Vector');
|
7 |
|
8 | var radius = 10e6;
|
9 | var cos30 = Math.cos(Math.PI / 6);
|
10 | var sin30 = Math.sin(Math.PI / 6);
|
11 | var rise = radius * sin30;
|
12 | var run = radius * cos30;
|
13 |
|
14 | var triangle = new ol.geom.LineString([
|
15 | [0, radius], [run, -rise], [-run, -rise], [0, radius]
|
16 | ]);
|
17 |
|
18 | var feature = new ol.Feature(triangle);
|
19 |
|
20 | var layer = new ol.layer.Vector({
|
21 | source: new ol.source.Vector({
|
22 | features: [feature]
|
23 | })
|
24 | });
|
25 |
|
26 | var 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 |
|
35 | function 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 |
|
52 | function 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 |
|
61 | var firstNode = {
|
62 | point: [start[0] + dx / 3, start[1] + dy / 3]
|
63 | };
|
64 |
|
65 |
|
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 |
|
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 |
|
84 | function 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 |
|
98 | function 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 |
|
106 | var depthInput = document.getElementById('depth');
|
107 |
|
108 | function update() {
|
109 | makeFractal(Number(depthInput.value));
|
110 | }
|
111 |
|
112 | var updateTimer;
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 | depthInput.onchange = function() {
|
120 | window.clearTimeout(updateTimer);
|
121 | updateTimer = window.setTimeout(update, 200);
|
122 | };
|
123 |
|
124 | update();
|