I am experimenting with a new algorithm for random landscape generation. This method was my idea, so it may turn out to be impossible. In the meantime, I'm trying to smooth this thing out.
public static void generate(){
for(int x = -64; x <= 64; x++){
for(int y = -64; y <= 64; y++){
double val = 2d;
for(int i = x - 4; i <= x + 4; i++){
for(int j = y - 4; j <= y + 4; j++){
double w = Math.pow(hypotenuse(x, y, i, j), 1);
val += (1 * (random(i, j) / w));
}
}
tileSet(x, y, val);
}
}
}
Before I explain this code, let me say that this is a 2D game, and so the heightmap is types of tiles instead of actual height. Water is lowest (0), then sand, grass, and tree (3). For testing, I am looping from -64 to 64 in both dimensions. For each tile, a value (starting with 2 or grass) is declared. Then we loop around this tile (-4 to 4 is an arbitrary amount, I have not been able to achieve significant differences in results by modifying this value, but 4 seems okay). Now, variable w stands for weight. The farther away each (i, j) point is from (x, y) the less weight the random value is given before it is added onto val. I have experimented with different exponents for w, and different multipliers for the next line (in the example both cases are 1); lower exponents and multipliers seem to widen the end result without necessarily smoothing, higher ones do the opposite and you get more trees closer to water with less grass and sand in between.
Here is the method random()
public static double random(int x, int y){
Random random = new Random(seed * 17717171L + x * 22222223L + y * 111181111L);
return random.nextGaussian() / 2d;
}
After those inner loops finished, the value of x, y is set.
Here's one run
Here's a multiplier of .5, meaning val += (.5 * (random(i, j) / w));
As you can see, there is more sand and grass, significantly less trees (and water overall), but still just as many little bumps. It does not effectively change the scale therefore.
Thank you for your time!
Yes There is, Use a Terrain Plugin so when you have a Part you only click on the plugin, select type of terrain and click on the part you will see how it turn a into the terrain.
What you're doing is known as inverse distance weighting. As the article points out, the key parameter is the exponent of the weight. So in your code, try
double w = Math.pow(hypotenuse(x, y, i, j), p);
taking p
to be 0.25, 0.5, 1.0, 2.0,
etc.
Also a slight variant on your algorithm that'd probably make reasoning about the algorithm easier: rather than generating a random value for each cell and adding to to neighbouring cells, start off by generating a random value at each cell corner, then use inverse distance weighting measured from the cell centres to calculate your cell values.
Using this scheme, the random values that contribute to a cell's value are all treated in a uniform manner, rather than one random value getting a weighting of 1 and the others getting inverse-distance weighted.
You might also be interested in gradient noise if you haven't encountered it already.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With