commit
message
making progress toward using webworkers for long-running algorithms
author
Ben Vogt <[email protected]>
date
2016-05-14 04:44:26
stats
4 file(s) changed,
559 insertions(+),
581 deletions(-)
files
erosion.js
index.html
landmap.js
main.js
1diff --git a/erosion.js b/erosion.js
2new file mode 100644
3index 0000000..e399ab4
4--- /dev/null
5+++ b/erosion.js
6@@ -0,0 +1,16 @@
7+self.importScripts('landmap.js');
8+self.addEventListener('message', function(e) {
9+ var terrain = new LandMap({
10+ containerId: "container-5"
11+ });
12+ terrain.generate(0.75, "standard");
13+ terrain.complexErosion({
14+ carryingCapacity: 1.0,
15+ depositionSpeed: 0.1,
16+ iterations: 3,
17+ drops: 2000000,
18+ one: "standard",
19+ two: "complexErosion-8000000-3ipd"
20+ });
21+ self.postMessage(terrain);
22+}, false);
23diff --git a/index.html b/index.html
24index fbc95f8..3c9e61b 100644
25--- a/index.html
26+++ b/index.html
27@@ -3,6 +3,7 @@
28 <title>Terrain Maps</title>
29 <link rel="stylesheet" type="text/css" href="style.css">
30 <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
31+ <script type="text/javascript" src="landmap.js"></script>
32 <script type="text/javascript" src="main.js"></script>
33 </head>
34 <body>
35diff --git a/landmap.js b/landmap.js
36new file mode 100644
37index 0000000..34f9375
38--- /dev/null
39+++ b/landmap.js
40@@ -0,0 +1,538 @@
41+function indexOfMax(arr) {
42+ if (arr.length === 0) {
43+ return -1;
44+ }
45+
46+ var max = arr[0];
47+ var maxIndex = 0;
48+
49+ for (var ind = 1; ind < arr.length; ind++) {
50+ if (arr[ind] > max) {
51+ maxIndex = ind;
52+ max = arr[ind];
53+ }
54+ }
55+ return maxIndex;
56+}
57+
58+function indexOfMin(arr) {
59+ if (arr.length === 0) {
60+ return -1;
61+ }
62+
63+ var min = arr[0];
64+ var minIndex = 0;
65+
66+ for (var ind = 1; ind < arr.length; ind++) {
67+ if (arr[ind] < min) {
68+ minIndex = ind;
69+ min = arr[ind];
70+ }
71+ }
72+ return minIndex;
73+}
74+
75+// options can be a serialized LandMap
76+function LandMap(options) {
77+ var level = 8;
78+ this.containerId = options.containerId;
79+ this.size = Math.pow(2, level) + 1;
80+ this.max = this.size - 1;
81+ this.maps = options.maps || {};
82+}
83+
84+LandMap.prototype.get = function(which, x, y) {
85+ if (x < 0 || x > this.max || y < 0 || y > this.max) {
86+ return -1;
87+ } else {
88+ return this.maps[which][x + this.size * y];
89+ }
90+};
91+
92+LandMap.prototype.set = function(which, x, y, value) {
93+ this.maps[which][(x + this.size * y)] = value;
94+};
95+
96+LandMap.prototype.generate = function(deviationAmount, feature) {
97+ var self = this;
98+
99+ if (!(feature in self.maps)) {
100+ this.maps[feature] = new Array(this.size * this.size);
101+ }
102+
103+ this.set(feature, 0, 0, Math.random() * self.max);
104+ this.set(feature, this.max, 0, Math.random() * self.max);
105+ this.set(feature, this.max, this.max, Math.random() * self.max);
106+ this.set(feature, 0, this.max, Math.random() * self.max);
107+
108+ subdivide(this.max);
109+
110+ function subdivide(size) {
111+ var x, y, half = size / 2;
112+ var scale = deviationAmount * size;
113+ if (half < 1) return;
114+
115+ for (y = half; y < self.max; y += size) {
116+ for (x = half; x < self.max; x += size) {
117+ square(feature, x, y, half, Math.random() * scale * 2 - scale);
118+ }
119+ }
120+ for (y = 0; y <= self.max; y += half) {
121+ for (x = (y + half) % size; x <= self.max; x += size) {
122+ diamond(feature, x, y, half, Math.random() * scale * 2 - scale);
123+ }
124+ }
125+ subdivide(size / 2);
126+ }
127+
128+ function average(values) {
129+ var valid = values.filter(function(val) {
130+ return val !== -1;
131+ });
132+ var total = valid.reduce(function(sum, val) {
133+ return sum + val;
134+ }, 0);
135+ return total / valid.length;
136+ }
137+
138+ function square(which, x, y, size, offset) {
139+ var ave = average([
140+ self.get(which, x - size, y - size), // upper left
141+ self.get(which, x + size, y - size), // upper right
142+ self.get(which, x + size, y + size), // lower right
143+ self.get(which, x - size, y + size) // lower left
144+ ]);
145+ self.set(which, x, y, ave + offset);
146+ }
147+
148+ function diamond(which, x, y, size, offset) {
149+ var ave = average([
150+ self.get(which, x, y - size), // top
151+ self.get(which, x + size, y), // right
152+ self.get(which, x, y + size), // bottom
153+ self.get(which, x - size, y) // left
154+ ]);
155+ self.set(which, x, y, ave + offset);
156+ }
157+};
158+
159+LandMap.prototype.smooth = function(amount, featureFrom, featureTo) {
160+ if (!(featureTo in this.maps)) {
161+ this.maps[featureTo] = new Array(this.size * this.size);
162+ }
163+
164+ var self = this;
165+ var MARGIN = amount;
166+ for (var y = 0; y < this.size; y++) {
167+ for (var x = 0; x < this.size; x++) {
168+ var nextValue = self.get(featureFrom, x, y);
169+ var nextValueCount = 0;
170+ for (var xRange = Math.max(x - Math.round(MARGIN), 0); xRange < Math.min(x + Math.round(MARGIN), this.size); xRange++) {
171+ for (var yRange = Math.max(y - Math.round(MARGIN), 0); yRange < Math.min(y + Math.round(MARGIN), this.size); yRange++) {
172+ if (distanceBetween(x, y, xRange, yRange) <= MARGIN) {
173+ var value = self.get(featureFrom, xRange, yRange);
174+ nextValue = nextValue + value;
175+ nextValueCount++;
176+ }
177+ }
178+ }
179+ var finalVal = ((nextValue / nextValueCount));
180+ self.set(featureTo, x, y, finalVal);
181+ }
182+ }
183+
184+ function distanceBetween(ax, ay, bx, by) {
185+ return Math.abs(Math.sqrt((ax - bx) * (ax - bx) + (ay - by) * (ay - by)));
186+ }
187+};
188+
189+LandMap.prototype.combine = function(one, two, three, result) {
190+
191+ function percent(value, max, min) {
192+ return value / Math.abs((max - min));
193+ }
194+
195+ if (!(result in this.maps)) {
196+ this.maps[result] = new Array(this.size * this.size);
197+ }
198+
199+ var max = Number.MIN_SAFE_INTEGER;
200+ var min = Number.MAX_SAFE_INTEGER;
201+ for (var y = 0; y < this.size; y++) {
202+ for (var x = 0; x < this.size; x++) {
203+ var val = this.get(two, x, y);
204+ if (val !== undefined) {
205+ max = Math.max(max, val);
206+ min = Math.min(min, val);
207+ }
208+ }
209+ }
210+
211+ for (var y = 0; y < this.size; y++) {
212+ for (var x = 0; x < this.size; x++) {
213+ var featureOne = this.get(one, x, y);
214+ var featureTwo = this.get(two, x, y);
215+ var featureThree = this.get(three, x, y);
216+ if (featureOne !== undefined && featureTwo !== undefined && featureThree !== undefined) {
217+ var featureThreePercent = percent(featureThree, min, max);
218+ var val = (1 - featureThreePercent) * featureOne + featureThreePercent * featureTwo;
219+ this.set(result, x, y, val);
220+ }
221+ }
222+ }
223+};
224+
225+LandMap.prototype.grd = function(amount, percent, featureFrom, featureTo) {
226+ this.maps[featureTo] = new Array(this.size * this.size);
227+
228+ for (var y = 0; y < this.size; y++) {
229+ for (var x = 0; x < this.size; x++) {
230+ this.set(featureTo, x, y, this.get(featureFrom, x, y));
231+ }
232+ }
233+
234+ var operationAray = new Array(this.size * this.size);
235+ var size = this.size
236+ for (var y = 0; y < this.size; y++) {
237+ for (var x = 0; x < this.size; x++) {
238+ operationAray[(x + size * y)] = [0];
239+ }
240+ }
241+
242+ var MARGIN = amount;
243+ for (var i = 0; i < MARGIN; i++) {
244+ operationAray[(x + this.size * y)] = [0];
245+ var max = Number.MIN_SAFE_INTEGER;
246+ var min = Number.MAX_SAFE_INTEGER;
247+ for (var y = 0; y < this.size; y++) {
248+ for (var x = 0; x < this.size; x++) {
249+ var val = this.get(featureTo, x, y);
250+ if (val !== undefined) {
251+ max = Math.max(max, val);
252+ min = Math.min(min, val);
253+ }
254+ }
255+ }
256+
257+ // iterate through all
258+ for (var y = MARGIN; y < this.size - MARGIN; y++) {
259+ for (var x = MARGIN; x < this.size - MARGIN; x++) {
260+ var neighbors = [
261+ this.get(featureTo, x - 1, y),
262+ this.get(featureTo, x + 1, y),
263+ this.get(featureTo, x, y - 1),
264+ this.get(featureTo, x, y + 1)
265+ ];
266+ operationAray[(x + size * y)].push(this.get(featureTo, x, y));
267+ var index = indexOfMax(featureTo);
268+ var thisValue = this.get(featureTo, x, y);
269+ if (neighbors[index] > thisValue) {
270+ if (index == 0) {
271+ // WEST (left)
272+ operationAray[(x + size * y)].push(this.get(featureTo, x - 1, y) * percent);
273+ operationAray[((x - 1) + size * y)].push(this.get(featureTo, x - 1, y) * (percent) * (-1));
274+ } else if (index == 1) {
275+ // EAST (right)
276+ operationAray[(x + size * y)].push(this.get(featureTo, x + 1, y) * percent);
277+ operationAray[((x + 1) + size * y)].push(this.get(featureTo, x + 1, y) * (percent) * (-1));
278+ } else if (index == 2) {
279+ // NORTH (up)
280+ operationAray[(x + size * y)].push(this.get(featureTo, x, y - 1) * percent);
281+ operationAray[(x + size * (y - 1))].push(this.get(featureTo, x - 1, y) * (percent) * (-1));
282+ } else if (index == 3) {
283+ // SOUTH (down)
284+ operationAray[(x + size * y)].push(this.get(featureTo, x, y + 1) * percent);
285+ operationAray[(x + size * (y + 1))].push(this.get(featureTo, x, y + 1) * (percent) * (-1));
286+ }
287+ }
288+ }
289+ }
290+ //iterate through summing the operationAray, and setting it
291+ for (var y = MARGIN; y < size - MARGIN; y++) {
292+ for (var x = MARGIN; x < size - MARGIN; x++) {
293+ var value = operationAray[(x + size * y)].reduce(function(a, b) {
294+ return a + b;
295+ }, 0);
296+ this.set(featureTo, x, y, value);
297+ operationAray[(x + size * y)] = [value];
298+ }
299+ }
300+ }
301+};
302+
303+LandMap.prototype.simpleErosion = function(options) {
304+ var Kq = options.carryingCapacity;
305+ var Kd = options.depositionSpeed;
306+ var iterations = options.iterations;
307+ var drops = options.drops;
308+ var one = options.one;
309+ var two = options.two;
310+
311+ var HeightMap = new Array(this.size * this.size);
312+ for (var y = 0; y < this.size; y++) {
313+ for (var x = 0; x < this.size; x++) {
314+ HeightMap[(x + this.size * y)] = this.get(one, x, y);
315+ }
316+ }
317+
318+ var HMAP_SIZE = this.size;
319+
320+ function HMAP_INDEX(x, y) {
321+ var val = (x + HMAP_SIZE * y)
322+ return val;
323+ }
324+
325+ function HMAP_VALUE(x, y) {
326+ return HeightMap[(x + HMAP_SIZE * y)];
327+ }
328+
329+ function DEPOSIT_AT(X, Y) {
330+ var c = 0.0;
331+ var v = 1.05;
332+ var maxVelocity = 10.0;
333+
334+ // For the number of iterations
335+ for (var iter = 0; iter < iterations; iter++) {
336+ v = Math.min(v, maxVelocity); // limiting velocity
337+ var val = HMAP_VALUE(X, Y);
338+ var nv = [
339+ HMAP_VALUE(X, Y - 1), //NORTH
340+ HMAP_VALUE(X, Y + 1), //SOUTH
341+ HMAP_VALUE(X + 1, Y), //EAST
342+ HMAP_VALUE(X - 1, Y) //WEST
343+ ];
344+
345+ var minInd = indexOfMin(nv);
346+ // if the lowest neighbor is NOT greater than the current value
347+ if (nv[minInd] < val) {
348+ //deposit or erode
349+ var vtc = Kd * v * Math.abs(nv[minInd]); // value to steal is depositionSpeed * velocity * abs(slope);
350+ // if carrying amount is greater than Kq
351+ if (c > Kq) {
352+ //DEPOSIT
353+ c -= vtc;
354+ HeightMap[HMAP_INDEX(X, Y)] += vtc;
355+ } else {
356+ //ERODE
357+ // if carrying + value to steal > carrying cap
358+ if (c + vtc > Kq) {
359+ var delta = c + vtc - Kq;
360+ c += delta;
361+ HeightMap[HMAP_INDEX(X, Y)] -= delta;
362+ } else {
363+ c += vtc;
364+ HeightMap[HMAP_INDEX(X, Y)] -= vtc;
365+ }
366+ }
367+
368+ // move to next value
369+ if (minInd == 0) {
370+ //NORTH
371+ Y -= 1
372+ }
373+ if (minInd == 1) {
374+ //SOUTH
375+ Y += 1
376+ }
377+ if (minInd == 2) {
378+ //EAST
379+ X += 1
380+ }
381+ if (minInd == 3) {
382+ //WEST
383+ X -= 1
384+ }
385+
386+ // limiting to edge of map
387+ if (X > this.size - 1) {
388+ X = this.size;
389+ }
390+ if (Y > this.size - 1) {
391+ Y = this.size;
392+ }
393+ if (Y < 0) {
394+ Y = 0;
395+ }
396+ if (X < 0) {
397+ X = 0;
398+ }
399+ }
400+ }
401+ }
402+
403+ for (var drop = 0; drop < drops; drop++) {
404+ DEPOSIT_AT(Math.floor(Math.random() * this.size), Math.floor(Math.random() * this.size));
405+ this.maps[two] = HeightMap;
406+ }
407+};
408+
409+LandMap.prototype.complexErosion = function(options) {
410+ var Kq = options.carryingCapacity;
411+ var Kd = options.depositionSpeed;
412+ var iterations = options.iterations;
413+ var drops = options.drops;
414+ var one = options.one;
415+ var two = options.two;
416+
417+ var HeightMap = new Array(this.size * this.size);
418+ for (var y = 0; y < this.size; y++) {
419+ for (var x = 0; x < this.size; x++) {
420+ HeightMap[(x + this.size * y)] = this.get(one, x, y);
421+ }
422+ }
423+
424+ var HMAP_SIZE = this.size;
425+
426+ function HMAP_INDEX(x, y) {
427+ var val = (x + HMAP_SIZE * y)
428+ return val;
429+ }
430+
431+ function HMAP_VALUE(x, y) {
432+ return HeightMap[(x + HMAP_SIZE * y)];
433+ }
434+
435+ function DEPOSIT_AT(X, Y) {
436+ var c = 0.0;
437+ var v = 1.05;
438+ var minSlope = 1.15;
439+ var maxVelocity = 10.0;
440+
441+ // For the number of iterations
442+ for (var iter = 0; iter < iterations; iter++) {
443+ v = Math.min(v, maxVelocity); // limiting velocity
444+ var val = HMAP_VALUE(X, Y);
445+ var nv = [
446+ HMAP_VALUE(X, Y - 1), //NORTH
447+ HMAP_VALUE(X, Y + 1), //SOUTH
448+ HMAP_VALUE(X + 1, Y), //EAST
449+ HMAP_VALUE(X - 1, Y) //WEST
450+ ];
451+
452+ var minInd = indexOfMin(nv);
453+ // if the lowest neighbor is NOT greater than the current value
454+ if (nv[minInd] < val) {
455+ //deposit or erode
456+ var slope = Math.min(minSlope, val - nv[minInd])
457+ var vtc = Kd * v * slope; // value to steal is depositionSpeed * velocity * abs(slope);
458+ // if carrying amount is greater than Kq
459+ if (c > Kq) {
460+ //DEPOSIT
461+ c -= vtc;
462+ HeightMap[HMAP_INDEX(X, Y)] += vtc;
463+ } else {
464+ //ERODE
465+ // if carrying + value to steal > carrying cap
466+ if (c + vtc > Kq) {
467+ var delta = c + vtc - Kq;
468+ c += delta;
469+ HeightMap[HMAP_INDEX(X, Y)] -= delta;
470+ } else {
471+ c += vtc;
472+ HeightMap[HMAP_INDEX(X, Y)] -= vtc;
473+ }
474+ }
475+
476+ // move to next value
477+ if (minInd == 0) {
478+ //NORTH
479+ Y -= 1
480+ }
481+ if (minInd == 1) {
482+ //SOUTH
483+ Y += 1
484+ }
485+ if (minInd == 2) {
486+ //EAST
487+ X += 1
488+ }
489+ if (minInd == 3) {
490+ //WEST
491+ X -= 1
492+ }
493+
494+ // limiting to edge of map
495+ if (X > this.size - 1) {
496+ X = this.size;
497+ }
498+ if (Y > this.size - 1) {
499+ Y = this.size;
500+ }
501+ if (Y < 0) {
502+ Y = 0;
503+ }
504+ if (X < 0) {
505+ X = 0;
506+ }
507+ }
508+ }
509+ }
510+
511+ for (var drop = 0; drop < drops; drop++) {
512+ DEPOSIT_AT(Math.floor(Math.random() * this.size), Math.floor(Math.random() * this.size));
513+ this.maps[two] = HeightMap;
514+ }
515+};
516+
517+LandMap.prototype.spinner = function() {
518+ var spinner = '<img class="spinner" width="24" height="24" src="data:image/gif;base64,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" />';
519+ document.getElementById(this.containerId).innerHTML = spinner;
520+}
521+
522+LandMap.prototype.draw = function() {
523+ var html = '<div class="row">';
524+ var featureCount = 0;
525+ for (feature in this.maps) {
526+ html += '<div class="four columns"><strong>' + feature + '</strong><div class="box"><span id="' + this.containerId + feature + '"></span><span id="' + feature + '-description"></span></div></div>';
527+ featureCount++;
528+ if (featureCount == 3) {
529+ html += '</div><div class="row">'
530+ featureCount = 0;
531+ }
532+ }
533+ document.getElementById(this.containerId).innerHTML = html;
534+ for (feature in this.maps) {
535+ var display = document.getElementById("tmp");
536+ var ctx = display.getContext('2d');
537+ var width = display.width = 256;
538+ var height = display.height = 256;
539+ var self = this;
540+
541+ var cellWidth = 1;
542+
543+ function drawCell(x, y, inensity) {
544+ ctx.fillStyle = inensity;
545+ ctx.fillRect(x * cellWidth, y * cellWidth, cellWidth, cellWidth);
546+ }
547+
548+ // finding max, min
549+ var max = Number.MIN_SAFE_INTEGER;
550+ var min = Number.MAX_SAFE_INTEGER;
551+ for (var y = 0; y < this.size; y++) {
552+ for (var x = 0; x < this.size; x++) {
553+ var val = this.get(feature, x, y);
554+ if (val !== undefined) {
555+ max = Math.max(max, val);
556+ min = Math.min(min, val);
557+ }
558+ }
559+ }
560+ // Drawing each cell
561+ for (var y = 0; y < this.size; y++) {
562+ for (var x = 0; x < this.size; x++) {
563+ var val = this.get(feature, x, y);
564+ if (val !== undefined) {
565+ drawCell(x, y, brightness(val, max, min));
566+ }
567+ }
568+ }
569+
570+ document.getElementById(this.containerId + feature).innerHTML = '<img src="' + display.toDataURL("image/png") + '" class="u-max-full-width map"/>';
571+ }
572+
573+ function brightness(value, max, min) {
574+ var delta = Math.abs((max - min));
575+ var b = Math.floor((value / delta) * 255);
576+ return 'rgba(' + b + ',' + b + ',' + b + ',1)';
577+ }
578+};
579diff --git a/main.js b/main.js
580index 5026d9d..63772b2 100644
581--- a/main.js
582+++ b/main.js
583@@ -1,544 +1,6 @@
584+var worker;
585 $(document).ready(function() {
586
587- function indexOfMax(arr) {
588- if (arr.length === 0) {
589- return -1;
590- }
591-
592- var max = arr[0];
593- var maxIndex = 0;
594-
595- for (var ind = 1; ind < arr.length; ind++) {
596- if (arr[ind] > max) {
597- maxIndex = ind;
598- max = arr[ind];
599- }
600- }
601- return maxIndex;
602- }
603-
604- function indexOfMin(arr) {
605- if (arr.length === 0) {
606- return -1;
607- }
608-
609- var min = arr[0];
610- var minIndex = 0;
611-
612- for (var ind = 1; ind < arr.length; ind++) {
613- if (arr[ind] < min) {
614- minIndex = ind;
615- min = arr[ind];
616- }
617- }
618- return minIndex;
619- }
620-
621- function LandMap(options) {
622- var level = 8;
623- this.containerId = options.containerId;
624- this.title = options.title;
625- this.size = Math.pow(2, level) + 1;
626- this.max = this.size - 1;
627- this.maps = {};
628- }
629-
630- LandMap.prototype.get = function(which, x, y) {
631- if (x < 0 || x > this.max || y < 0 || y > this.max) {
632- return -1;
633- } else {
634- return this.maps[which][x + this.size * y];
635- }
636- };
637-
638- LandMap.prototype.set = function(which, x, y, value) {
639- this.maps[which][(x + this.size * y)] = value;
640- };
641-
642- LandMap.prototype.generate = function(deviationAmount, feature) {
643- var self = this;
644-
645- if (!(feature in self.maps)) {
646- this.maps[feature] = new Array(this.size * this.size);
647- }
648-
649- this.set(feature, 0, 0, Math.random() * self.max);
650- this.set(feature, this.max, 0, Math.random() * self.max);
651- this.set(feature, this.max, this.max, Math.random() * self.max);
652- this.set(feature, 0, this.max, Math.random() * self.max);
653-
654- subdivide(this.max);
655-
656- function subdivide(size) {
657- var x, y, half = size / 2;
658- var scale = deviationAmount * size;
659- if (half < 1) return;
660-
661- for (y = half; y < self.max; y += size) {
662- for (x = half; x < self.max; x += size) {
663- square(feature, x, y, half, Math.random() * scale * 2 - scale);
664- }
665- }
666- for (y = 0; y <= self.max; y += half) {
667- for (x = (y + half) % size; x <= self.max; x += size) {
668- diamond(feature, x, y, half, Math.random() * scale * 2 - scale);
669- }
670- }
671- subdivide(size / 2);
672- }
673-
674- function average(values) {
675- var valid = values.filter(function(val) {
676- return val !== -1;
677- });
678- var total = valid.reduce(function(sum, val) {
679- return sum + val;
680- }, 0);
681- return total / valid.length;
682- }
683-
684- function square(which, x, y, size, offset) {
685- var ave = average([
686- self.get(which, x - size, y - size), // upper left
687- self.get(which, x + size, y - size), // upper right
688- self.get(which, x + size, y + size), // lower right
689- self.get(which, x - size, y + size) // lower left
690- ]);
691- self.set(which, x, y, ave + offset);
692- }
693-
694- function diamond(which, x, y, size, offset) {
695- var ave = average([
696- self.get(which, x, y - size), // top
697- self.get(which, x + size, y), // right
698- self.get(which, x, y + size), // bottom
699- self.get(which, x - size, y) // left
700- ]);
701- self.set(which, x, y, ave + offset);
702- }
703- };
704-
705- LandMap.prototype.smooth = function(amount, featureFrom, featureTo) {
706- if (!(featureTo in this.maps)) {
707- this.maps[featureTo] = new Array(this.size * this.size);
708- }
709-
710- var self = this;
711- var MARGIN = amount;
712- for (var y = 0; y < this.size; y++) {
713- for (var x = 0; x < this.size; x++) {
714- var nextValue = self.get(featureFrom, x, y);
715- var nextValueCount = 0;
716- for (var xRange = Math.max(x - Math.round(MARGIN), 0); xRange < Math.min(x + Math.round(MARGIN), this.size); xRange++) {
717- for (var yRange = Math.max(y - Math.round(MARGIN), 0); yRange < Math.min(y + Math.round(MARGIN), this.size); yRange++) {
718- if (distanceBetween(x, y, xRange, yRange) <= MARGIN) {
719- var value = self.get(featureFrom, xRange, yRange);
720- nextValue = nextValue + value;
721- nextValueCount++;
722- }
723- }
724- }
725- var finalVal = ((nextValue / nextValueCount));
726- self.set(featureTo, x, y, finalVal);
727- }
728- }
729-
730- function distanceBetween(ax, ay, bx, by) {
731- return Math.abs(Math.sqrt((ax - bx) * (ax - bx) + (ay - by) * (ay - by)));
732- }
733- };
734-
735- LandMap.prototype.combine = function(one, two, three, result) {
736-
737- function percent(value, max, min) {
738- return value / Math.abs((max - min));
739- }
740-
741- if (!(result in this.maps)) {
742- this.maps[result] = new Array(this.size * this.size);
743- }
744-
745- var max = Number.MIN_SAFE_INTEGER;
746- var min = Number.MAX_SAFE_INTEGER;
747- for (var y = 0; y < this.size; y++) {
748- for (var x = 0; x < this.size; x++) {
749- var val = this.get(two, x, y);
750- if (val !== undefined) {
751- max = Math.max(max, val);
752- min = Math.min(min, val);
753- }
754- }
755- }
756-
757- for (var y = 0; y < this.size; y++) {
758- for (var x = 0; x < this.size; x++) {
759- var featureOne = this.get(one, x, y);
760- var featureTwo = this.get(two, x, y);
761- var featureThree = this.get(three, x, y);
762- if (featureOne !== undefined && featureTwo !== undefined && featureThree !== undefined) {
763- var featureThreePercent = percent(featureThree, min, max);
764- var val = (1 - featureThreePercent) * featureOne + featureThreePercent * featureTwo;
765- this.set(result, x, y, val);
766- }
767- }
768- }
769- };
770-
771- LandMap.prototype.grd = function(amount, percent, featureFrom, featureTo) {
772- this.maps[featureTo] = new Array(this.size * this.size);
773-
774- for (var y = 0; y < this.size; y++) {
775- for (var x = 0; x < this.size; x++) {
776- this.set(featureTo, x, y, this.get(featureFrom, x, y));
777- }
778- }
779-
780- var operationAray = new Array(this.size * this.size);
781- var size = this.size
782- for (var y = 0; y < this.size; y++) {
783- for (var x = 0; x < this.size; x++) {
784- operationAray[(x + size * y)] = [0];
785- }
786- }
787-
788- var MARGIN = amount;
789- for (var i = 0; i < MARGIN; i++) {
790- operationAray[(x + this.size * y)] = [0];
791- var max = Number.MIN_SAFE_INTEGER;
792- var min = Number.MAX_SAFE_INTEGER;
793- for (var y = 0; y < this.size; y++) {
794- for (var x = 0; x < this.size; x++) {
795- var val = this.get(featureTo, x, y);
796- if (val !== undefined) {
797- max = Math.max(max, val);
798- min = Math.min(min, val);
799- }
800- }
801- }
802-
803- // iterate through all
804- for (var y = MARGIN; y < this.size - MARGIN; y++) {
805- for (var x = MARGIN; x < this.size - MARGIN; x++) {
806- var neighbors = [
807- this.get(featureTo, x - 1, y),
808- this.get(featureTo, x + 1, y),
809- this.get(featureTo, x, y - 1),
810- this.get(featureTo, x, y + 1)
811- ];
812- operationAray[(x + size * y)].push(this.get(featureTo, x, y));
813- var index = indexOfMax(featureTo);
814- var thisValue = this.get(featureTo, x, y);
815- if (neighbors[index] > thisValue) {
816- if (index == 0) {
817- // WEST (left)
818- operationAray[(x + size * y)].push(this.get(featureTo, x - 1, y) * percent);
819- operationAray[((x - 1) + size * y)].push(this.get(featureTo, x - 1, y) * (percent) * (-1));
820- } else if (index == 1) {
821- // EAST (right)
822- operationAray[(x + size * y)].push(this.get(featureTo, x + 1, y) * percent);
823- operationAray[((x + 1) + size * y)].push(this.get(featureTo, x + 1, y) * (percent) * (-1));
824- } else if (index == 2) {
825- // NORTH (up)
826- operationAray[(x + size * y)].push(this.get(featureTo, x, y - 1) * percent);
827- operationAray[(x + size * (y - 1))].push(this.get(featureTo, x - 1, y) * (percent) * (-1));
828- } else if (index == 3) {
829- // SOUTH (down)
830- operationAray[(x + size * y)].push(this.get(featureTo, x, y + 1) * percent);
831- operationAray[(x + size * (y + 1))].push(this.get(featureTo, x, y + 1) * (percent) * (-1));
832- }
833- }
834- }
835- }
836- //iterate through summing the operationAray, and setting it
837- for (var y = MARGIN; y < size - MARGIN; y++) {
838- for (var x = MARGIN; x < size - MARGIN; x++) {
839- var value = operationAray[(x + size * y)].reduce(function(a, b) {
840- return a + b;
841- }, 0);
842- this.set(featureTo, x, y, value);
843- operationAray[(x + size * y)] = [value];
844- }
845- }
846- }
847- };
848-
849- LandMap.prototype.simpleErosion = function(options) {
850- var Kq = options.carryingCapacity;
851- var Kd = options.depositionSpeed;
852- var iterations = options.iterations;
853- var drops = options.drops;
854- var one = options.one;
855- var two = options.two;
856-
857- var HeightMap = new Array(this.size * this.size);
858- for (var y = 0; y < this.size; y++) {
859- for (var x = 0; x < this.size; x++) {
860- HeightMap[(x + this.size * y)] = this.get(one, x, y);
861- }
862- }
863-
864- var HMAP_SIZE = this.size;
865-
866- function HMAP_INDEX(x, y) {
867- var val = (x + HMAP_SIZE * y)
868- return val;
869- }
870-
871- function HMAP_VALUE(x, y) {
872- return HeightMap[(x + HMAP_SIZE * y)];
873- }
874-
875- function DEPOSIT_AT(X, Y) {
876- var c = 0.0;
877- var v = 1.05;
878- var maxVelocity = 10.0;
879-
880- // For the number of iterations
881- for (var iter = 0; iter < iterations; iter++) {
882- v = Math.min(v, maxVelocity); // limiting velocity
883- var val = HMAP_VALUE(X, Y);
884- var nv = [
885- HMAP_VALUE(X, Y - 1), //NORTH
886- HMAP_VALUE(X, Y + 1), //SOUTH
887- HMAP_VALUE(X + 1, Y), //EAST
888- HMAP_VALUE(X - 1, Y) //WEST
889- ];
890-
891- var minInd = indexOfMin(nv);
892- // if the lowest neighbor is NOT greater than the current value
893- if (nv[minInd] < val) {
894- //deposit or erode
895- var vtc = Kd * v * Math.abs(nv[minInd]); // value to steal is depositionSpeed * velocity * abs(slope);
896- // if carrying amount is greater than Kq
897- if (c > Kq) {
898- //DEPOSIT
899- c -= vtc;
900- HeightMap[HMAP_INDEX(X, Y)] += vtc;
901- } else {
902- //ERODE
903- // if carrying + value to steal > carrying cap
904- if (c + vtc > Kq) {
905- var delta = c + vtc - Kq;
906- c += delta;
907- HeightMap[HMAP_INDEX(X, Y)] -= delta;
908- } else {
909- c += vtc;
910- HeightMap[HMAP_INDEX(X, Y)] -= vtc;
911- }
912- }
913-
914- // move to next value
915- if (minInd == 0) {
916- //NORTH
917- Y -= 1
918- }
919- if (minInd == 1) {
920- //SOUTH
921- Y += 1
922- }
923- if (minInd == 2) {
924- //EAST
925- X += 1
926- }
927- if (minInd == 3) {
928- //WEST
929- X -= 1
930- }
931-
932- // limiting to edge of map
933- if (X > this.size - 1) {
934- X = this.size;
935- }
936- if (Y > this.size - 1) {
937- Y = this.size;
938- }
939- if (Y < 0) {
940- Y = 0;
941- }
942- if (X < 0) {
943- X = 0;
944- }
945- }
946- }
947- }
948-
949- for (var drop = 0; drop < drops; drop++) {
950- DEPOSIT_AT(Math.floor(Math.random() * this.size), Math.floor(Math.random() * this.size));
951- this.maps[two] = HeightMap;
952- }
953- };
954-
955- LandMap.prototype.complexErosion = function(options) {
956- var Kq = options.carryingCapacity;
957- var Kd = options.depositionSpeed;
958- var iterations = options.iterations;
959- var drops = options.drops;
960- var one = options.one;
961- var two = options.two;
962-
963- var HeightMap = new Array(this.size * this.size);
964- for (var y = 0; y < this.size; y++) {
965- for (var x = 0; x < this.size; x++) {
966- HeightMap[(x + this.size * y)] = this.get(one, x, y);
967- }
968- }
969-
970- var HMAP_SIZE = this.size;
971-
972- function HMAP_INDEX(x, y) {
973- var val = (x + HMAP_SIZE * y)
974- return val;
975- }
976-
977- function HMAP_VALUE(x, y) {
978- return HeightMap[(x + HMAP_SIZE * y)];
979- }
980-
981- function DEPOSIT_AT(X, Y) {
982- var c = 0.0;
983- var v = 1.05;
984- var minSlope = 1.15;
985- var maxVelocity = 10.0;
986-
987- // For the number of iterations
988- for (var iter = 0; iter < iterations; iter++) {
989- v = Math.min(v, maxVelocity); // limiting velocity
990- var val = HMAP_VALUE(X, Y);
991- var nv = [
992- HMAP_VALUE(X, Y - 1), //NORTH
993- HMAP_VALUE(X, Y + 1), //SOUTH
994- HMAP_VALUE(X + 1, Y), //EAST
995- HMAP_VALUE(X - 1, Y) //WEST
996- ];
997-
998- var minInd = indexOfMin(nv);
999- // if the lowest neighbor is NOT greater than the current value
1000- if (nv[minInd] < val) {
1001- //deposit or erode
1002- var slope = Math.min(minSlope, val - nv[minInd])
1003- var vtc = Kd * v * slope; // value to steal is depositionSpeed * velocity * abs(slope);
1004- // if carrying amount is greater than Kq
1005- if (c > Kq) {
1006- //DEPOSIT
1007- c -= vtc;
1008- HeightMap[HMAP_INDEX(X, Y)] += vtc;
1009- } else {
1010- //ERODE
1011- // if carrying + value to steal > carrying cap
1012- if (c + vtc > Kq) {
1013- var delta = c + vtc - Kq;
1014- c += delta;
1015- HeightMap[HMAP_INDEX(X, Y)] -= delta;
1016- } else {
1017- c += vtc;
1018- HeightMap[HMAP_INDEX(X, Y)] -= vtc;
1019- }
1020- }
1021-
1022- // move to next value
1023- if (minInd == 0) {
1024- //NORTH
1025- Y -= 1
1026- }
1027- if (minInd == 1) {
1028- //SOUTH
1029- Y += 1
1030- }
1031- if (minInd == 2) {
1032- //EAST
1033- X += 1
1034- }
1035- if (minInd == 3) {
1036- //WEST
1037- X -= 1
1038- }
1039-
1040- // limiting to edge of map
1041- if (X > this.size - 1) {
1042- X = this.size;
1043- }
1044- if (Y > this.size - 1) {
1045- Y = this.size;
1046- }
1047- if (Y < 0) {
1048- Y = 0;
1049- }
1050- if (X < 0) {
1051- X = 0;
1052- }
1053- }
1054- }
1055- }
1056-
1057- for (var drop = 0; drop < drops; drop++) {
1058- DEPOSIT_AT(Math.floor(Math.random() * this.size), Math.floor(Math.random() * this.size));
1059- this.maps[two] = HeightMap;
1060- }
1061- };
1062-
1063- LandMap.prototype.spinner = function() {
1064- var spinner = '<img class="spinner" width="24" height="24" src="data:image/gif;base64,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" />';
1065- document.getElementById(this.containerId).innerHTML = spinner;
1066- }
1067-
1068- LandMap.prototype.draw = function() {
1069- var html = '<div class="row">';
1070- var featureCount = 0;
1071- for (feature in this.maps) {
1072- html += '<div class="four columns"><strong>' + feature + '</strong><div class="box"><span id="' + this.containerId + feature + '"></span><span id="' + feature + '-description"></span></div></div>';
1073- featureCount++;
1074- if (featureCount == 3) {
1075- html += '</div><div class="row">'
1076- featureCount = 0;
1077- }
1078- }
1079- document.getElementById(this.containerId).innerHTML = html;
1080- for (feature in this.maps) {
1081- var display = document.getElementById("tmp");
1082- var ctx = display.getContext('2d');
1083- var width = display.width = 256;
1084- var height = display.height = 256;
1085- var self = this;
1086-
1087- var cellWidth = 1;
1088-
1089- function drawCell(x, y, inensity) {
1090- ctx.fillStyle = inensity;
1091- ctx.fillRect(x * cellWidth, y * cellWidth, cellWidth, cellWidth);
1092- }
1093-
1094- // finding max, min
1095- var max = Number.MIN_SAFE_INTEGER;
1096- var min = Number.MAX_SAFE_INTEGER;
1097- for (var y = 0; y < this.size; y++) {
1098- for (var x = 0; x < this.size; x++) {
1099- var val = this.get(feature, x, y);
1100- if (val !== undefined) {
1101- max = Math.max(max, val);
1102- min = Math.min(min, val);
1103- }
1104- }
1105- }
1106- // Drawing each cell
1107- for (var y = 0; y < this.size; y++) {
1108- for (var x = 0; x < this.size; x++) {
1109- var val = this.get(feature, x, y);
1110- if (val !== undefined) {
1111- drawCell(x, y, brightness(val, max, min));
1112- }
1113- }
1114- }
1115-
1116- document.getElementById(this.containerId + feature).innerHTML = '<img src="' + display.toDataURL("image/png") + '" class="u-max-full-width map"/>';
1117- }
1118-
1119- function brightness(value, max, min) {
1120- var delta = Math.abs((max - min));
1121- var b = Math.floor((value / delta) * 255);
1122- return 'rgba(' + b + ',' + b + ',' + b + ',1)';
1123- }
1124- };
1125-
1126 $("#standard").click(function() {
1127 var standardMap = new LandMap({
1128 containerId: "container-1"
1129@@ -591,46 +53,14 @@ $(document).ready(function() {
1130 });
1131
1132 $("#complexErosion").click(function() {
1133- var terrain = new LandMap({
1134- containerId: "container-5"
1135- });
1136- terrain.spinner();
1137- setTimeout(function() {
1138- terrain.generate(0.75, "standard");
1139- // terrain.complexErosion({
1140- // carryingCapacity: 1.5,
1141- // depositionSpeed: 0.03,
1142- // iterations: 10,
1143- // drops: 1000000,
1144- // one: "standard",
1145- // two: "complexErosion-1000000-10ipd"
1146- // });
1147- // terrain.complexErosion({
1148- // carryingCapacity: 1.5,
1149- // depositionSpeed: 0.03,
1150- // iterations: 20,
1151- // drops: 1000000,
1152- // one: "standard",
1153- // two: "complexErosion-1000000-20ipd"
1154- // });
1155- // terrain.complexErosion({
1156- // carryingCapacity: 1.5,
1157- // depositionSpeed: 0.03,
1158- // iterations: 3,
1159- // drops: 4000000,
1160- // one: "standard",
1161- // two: "complexErosion-4000000-3ipd"
1162- // });
1163- terrain.complexErosion({
1164- carryingCapacity: 1.0,
1165- depositionSpeed: 0.1,
1166- iterations: 3,
1167- drops: 2000000,
1168- one: "standard",
1169- two: "complexErosion-8000000-3ipd"
1170- });
1171+ var terrain;
1172+ worker = new Worker('erosion.js');
1173+ worker.postMessage(0);
1174+ worker.addEventListener('message', function(e) {
1175+ console.log(e.data.maps)
1176+ terrain = new LandMap(e.data);
1177+ console.log(terrain.maps)
1178 terrain.draw();
1179- }, 1000);
1180-
1181+ }, false);
1182 });
1183 })