• 10
• 10
• 12
• 12
• 14

# Land/Sea ratio from a Heightmap

This topic is 999 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have implemented in the Perlin's Simplex Noise which generates a Heightmap. This part is no problem.

It provides me a 2D array of numbers between 0 and 255 (values barely go over 100 in fact, but it's not a big issue).

From this Heightmap, I've predefined four constant ranges of altitude telling me if a point is a tile of:

• Deep Water (dark blue)
• Coastal Water (light blue)
• Flat terrain (green)
• Mountain (gray)

The problem with this method is it gives me some maps with water or land only.

?

So, I would like to be able to define a land/sea ratio from which I can deduce which range belongs to land tiles, and which range belong to water tiles.

I was thinking of using the heightmap's histogram without being really sure how I could use it (in the case this could work).

Edited by yahiko00

##### Share on other sites
I define my ranges according to the average altitude of the map and its standard deviation.

First, I compute the cumulative histogram cumHisto:
    var cumHisto = 0;

for (var i = 0; i < World.width; i++) {
for (var j = 0; j < World.height; j++) {
cumHisto += World.mapData[i][j];
} // for j
} // for i


Then, I compute the average altitude avgHeight:
    var nbPoints = World.width * World.height;
var avgAltitude = cumHisto / nbPoints;


I need a loop to compute the standard deviation stdevAltitude, based on the variance varAltitude:
    var varAltitude = 0;
for (var i = 0; i < World.width; i++) {
for (var j = 0; j < World.height; j++) {
var diff = World.mapData[i][j] - avgAltitude;
varAltitude += diff * diff;
} // for j
} // for i

var varAltitude = varAltitude / nbPoints;
var stdevAltitude = Math.sqrt(varAltitude);


Given the average altitude and its standard deviation, I can define four ranges which seem to give quite reliable results:
    for (var i = 0; i < World.width; i++) {
for (var j = 0; j < World.height; j++) {
if (World.mapData[i][j] < avgAltitude) {
World.mapData[i][j] = Terrain.DEEP_OCEAN;
}
else if (World.mapData[i][j] < avgAltitude + 0.5 * stdevAltitude) {
World.mapData[i][j] = Terrain.COASTAL_OCEAN;
}
else if (World.mapData[i][j] < avgAltitude + 2 * stdevAltitude) {
World.mapData[i][j] = Terrain.FLAT;
}
else {
World.mapData[i][j] = Terrain.MOUNTAIN;
}
} // for j
} // for i