258 Chapter 10—Web Workers
Math.round(Math.random()*(evt.data.height-1))];
for (var i=1; i<evt.data.parts; i++) {
var p2 = [Math.round(Math.random()*(evt.data.width-1)),
Math.round(Math.random()*(evt.data.height-1))];
var len = Math.sqrt((Math.pow(p2[0]-p1[0],2)
+Math.pow(p2[1]-p1[1],2)));
var profile = [];
for (var j=0; j<len-1; j++) {
...
var h = getHeight([x,y]);
The length in pixels (len) between the two random points (p1 and p2) is calcu-
lated via the Pythagorean theorem, using the JavaScript function Math.sqrt() (for
the square root) and Math.pow() (for squaring). Then a second loop runs over all
pixels along this route and extracts the altitude value from the array:
var getHeight = function(p) {
var pos = ((parseInt(p[1])*evt.data.width) +
parseInt(p[0]));
return evt.data.alpha[pos] * equidistance;
};
To determine the desired position within the one-dimensional array of alpha
channel values, we need to multiply the y-value by the canvas width and then add
the x-value. The attentive reader will have noticed another detail: Before return-
ing the determined value, it is multiplied by the variable equidistance. The rea-
son is that we can only save 256 different values per channel in an 8-bit image file.
But the area around Innsbruck, Austria, has an altitude difference of more than
256 meters, so the altitude in this PNG image is specified in steps of 20 meters.
If a new minimum value along a profile line is found, the calling script is notified
accordingly:
if (h < min) {
min = h;
if (evt.data.useWorker) {
postMessage({task:'newMin',min:min,id: evt.data.id});
}
}
The same applies of course for new maximum values. At the end of each loop
over all sections, the progress bar is updated, and as soon as all sections have
been calculated, the result, wrapped in the variable d, is sent back to the main
script. If the script is executed as a worker, the data is sent with postMessage(),
without a worker, the result is returned to the calling function with return: