• Advertisement
Sign in to follow this  

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.

If you intended to correct an error in the post then please contact us.

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.

272884UBotMapGenerator6.png

 

230645UBotMapGenerator5.png?

 

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).

 

Thank you for your advice if any ;)

Edited by yahiko00

Share this post


Link to post
Share on other sites
Advertisement
Thank you for your reply. While you were writing your answer, I came up with another solution involving the histogram.
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
mini_837212Capturedcran20150801142639.pn mini_317439Capturedcran20150801142726.pn mini_441266Capturedcran20150801142737.pn mini_372853Capturedcran20150801142749.pn

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement