Height map generator [WIP] 1

[Work in Progress]

Until now I have been using perlin noise classes from other sources to make my procedural worlds. I didn’t really like the idea of using classes from others for it, so I made my own class from scratch to get the results I need, with a total different approach. I am unsure how I came up with this idea, I just did, and it worked. It needs a lot of tweaking still, but it’s starting to look like what I hoped it would do.

I found this picture, which basically explains what I am trying to do. (Click for animation)

Things to fix:

  1. It seems the result is often devided in squares of 2*2, this is ugly. I lack the knowledge to explain the problem better in English.
  2. The result seems to be rather diagonal, I might leave this as it is. I am not annoyed by it per se, but it wasn’t my intention.

Screenshot of my result: (click for larger image)

Theory (not practice):

Step 1:

Create a small 2D array, with random integers, this is done at the point you make the class instance. The class takes 3 parameters, Seed, Resolution, and Height, Seed is the seed for the randomizer, Resolution is the width and height for the default array (a resolution of either 4 or 8 works best, but for this example we use 2.) and last, height. Height is the upper bound of the randomizer. The lower bound is always zero. So, lets initiate the class. The StartMap[][] is being made. The resolution is 2 and the height is 10.

Depending on the seed, the output may look something like this:

Step 2:

Give it the first pass, what the pass does, is make a new array, with double the resolution of the previous pass. Because we didn’t have a pass before, we are going to use the startmap. Call pass(startmap). It creates the new array with double the resolution, and applies a simple formula to fill the array relative to the old array. The relative positions for the old values look like this.

Now, for each int, in the 2 dimensional array, it’s going to take the average between the two closest relative locations. On top of the average, it’s going to add (or substract) a slight random value. The outcome should look something like this.

So, when you apply several passes, the resolution of the map gets bigger and bigger. After 3 or 4 passes you will have a coherent random map of the size like the screenshot above.

I still need a lot of thinking to do to let it do exactly this, but I am getting there. The code as is, could be used as an heightmap, you get a 2D array of integers, which could be translated to the y axis for points in a plane, so you get procedural terrain :).

For this example I made every tile with a value  < 5 = water, and > 5 = grass.

Source:

import java.util.Random;

public class FractalNoise {
	Random RND;
	public int StartMap[][];
public FractalNoise(int Seed, int Resolution, int Height)
{
	RND = new Random(Seed);
	StartMap = new int[Resolution][Resolution];
	for(int x =0; x < StartMap[0].length; x++)
	{
		for(int y =0; y < StartMap[1].length; y++)
    	{
    		StartMap[x][y] = RND.nextInt(Height); //create initial noise map
    	}
	}
}

	public int[][] Pass( int[][] InputMap) //Inputmap is either the startmap (a 2 dimensional array with random integers) or the output of this function.
	{
	  int Map[][] = new int[InputMap[0].length * 2][InputMap[1].length * 2]; //Map will be the output, the output is 2 times the size of the input

	  for(int x = 0; x < InputMap[0].length * 2; x ++)
	  {

		  for(int y = 0; y < InputMap[1].length * 2; y ++) 		  { 		    if(x > 1 && y > 1 && x < Map[0].length - 2 && y < Map[1].length - 2)
		    {
		      Map[x][y] = (RND.nextInt(4) - 2)  + (InputMap[x / 2][y / 2] + InputMap[x / 2 + 1][y / 2 + 1]) / 2; //for each cell in the output map, take the relative cell in input map, and take a random number between the cells on both sides.
		    }
		    else
		    {
		     Map[x][y] = 0;
		    }

		  }

	  }

	  return Map;
	}
}

One comment on “Height map generator [WIP]

  1. Pingback: Random Heightmap generator continued

Leave a Reply