0

My applogies for the title as I do not know the correct term for my problem.

I'm using Simplex Noise (with 8 octaves) to generate a height map for my terrain. To get the terrain blend in, I calculated which biome fits the location best using a temperature value and a rainfall value and got the squared value via:

Math.abs((biome.optimumTemperature-temp)*(biome.optimumTemperature-temp) + (biome.optimumRainfall-rain)*(biome.optimumRainfall-rain));

This value is then used to get the biome that affects the point the most (only 3 biomes are tested) i.e 1/(squared value) meaning the closer the ideal conditions are the more terrain control the biome has. But I don't know how to make the sum of Weights equal to 1.

Example 1:

Biome 0: FOREST Weight:0.04317983014648879  
Biome 1: MOUNTAINS Weight:0.9954832102244979  
Biome 2: PLAINS Weight:0.06793829435632236  

Here, the sum is: ≈1,10660133 which is greater than 1

Example 2:

FOREST Weight:0.01621210578957933  
MOUNTAINS Weight:0.023389024085188184  
PLAINS Weight:0.017797794332510785  

Here, the sum is: ≈0.0573989242 which is less than 1

To prevent an influence that approaches infinity if biome.optimumTemperature = temp and biome.optimumRainfall = rain meaning that later on it would become 1 / 0 (Bad) I have clamped the squared value to a maximum of 1 for each of the 3.

My question is how do I distribute the influence to all 3 biomes according to the conditions?

Note: it is okay for a biome to have an influence of 1 if it matches temp and rain perfectly but in that case the other 2 biomes should have an influence of 0.

ganjaam
  • 1,030
  • 3
  • 17
  • 29
hampus toft
  • 55
  • 10

1 Answers1

1

It seems like you want to normalize the numbers. This is done by dividing each number by the total sum:

double a, b, c;
double sum = a + b + c;
double normalizedA = a / sum;
double normalizedB = b / sum;
double normalizedC = c / sum;

This ensures that the total sum of the new values becomes 1 (plus or minus any rounding errors from dealing with floating-point numbers) while retaining the relative sizes of the different numbers.

BambooleanLogic
  • 7,530
  • 3
  • 30
  • 56
  • Thanks a lot. I just realized that i want one more thing. A lower cap of the normalized value such that if i get ```0.997, 0.001, 0.002``` it will instead put ```1.0, 0.0, 0.0``` do i edit my question to cover this? – hampus toft Jun 22 '20 at 11:17
  • @hampustoft One way would be to define some threshold `double t = 0.01;`. Then, for each number, set it to zero if less than `t`, otherwise subtracting `t`, like so: `a = (a < t) ? 0 : a - t;`. Then, you can normalize again like above. Note that this will skew the normalization slightly, even if no value gets set to 0. Larger numbers weigh slightly heavier than normal compared to smaller numbers. For terrain generation, this is likely unnoticeable. – BambooleanLogic Jun 22 '20 at 12:19