mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 01:41:22 +01:00
precipitation generation - minor fix
This commit is contained in:
parent
01116addfc
commit
0de5b7c6cd
1 changed files with 35 additions and 24 deletions
59
main.js
59
main.js
|
|
@ -957,27 +957,32 @@ function calculateTemperatures() {
|
||||||
function generatePrecipitation() {
|
function generatePrecipitation() {
|
||||||
TIME && console.time("generatePrecipitation");
|
TIME && console.time("generatePrecipitation");
|
||||||
prec.selectAll("*").remove();
|
prec.selectAll("*").remove();
|
||||||
const cells = grid.cells;
|
const {cells, cellsX, cellsY} = grid;
|
||||||
cells.prec = new Uint8Array(cells.i.length); // precipitation array
|
cells.prec = new Uint8Array(cells.i.length); // precipitation array
|
||||||
const modifier = precInput.value / 100; // user's input
|
const modifier = precInput.value / 100; // user's input
|
||||||
const cellsX = grid.cellsX,
|
const {winds} = options;
|
||||||
cellsY = grid.cellsY;
|
|
||||||
|
const MAX_PASSABLE_ELEVATION = 85;
|
||||||
|
|
||||||
let westerly = [],
|
let westerly = [],
|
||||||
easterly = [],
|
easterly = [],
|
||||||
southerly = 0,
|
southerly = 0,
|
||||||
northerly = 0;
|
northerly = 0;
|
||||||
|
|
||||||
{
|
const isWest = tier => winds[tier] > 40 && winds[tier] < 140;
|
||||||
// latitude bands
|
const isEast = tier => winds[tier] > 220 && winds[tier] < 320;
|
||||||
// x4 = 0-5 latitude: wet through the year (rising zone)
|
const isSouth = tier => winds[tier] > 100 && winds[tier] < 260;
|
||||||
// x2 = 5-20 latitude: wet summer (rising zone), dry winter (sinking zone)
|
const isNorth = tier => winds[tier] > 280 && winds[tier] < 80;
|
||||||
// x1 = 20-30 latitude: dry all year (sinking zone)
|
|
||||||
// x2 = 30-50 latitude: wet winter (rising zone), dry summer (sinking zone)
|
// latitude bands info
|
||||||
// x3 = 50-60 latitude: wet all year (rising zone)
|
// x4 = 0-5 latitude: wet through the year (rising zone)
|
||||||
// x2 = 60-70 latitude: wet summer (rising zone), dry winter (sinking zone)
|
// x2 = 5-20 latitude: wet summer (rising zone), dry winter (sinking zone)
|
||||||
// x1 = 70-90 latitude: dry all year (sinking zone)
|
// x1 = 20-30 latitude: dry all year (sinking zone)
|
||||||
}
|
// x2 = 30-50 latitude: wet winter (rising zone), dry summer (sinking zone)
|
||||||
const lalitudeModifier = [4, 2, 2, 2, 1, 1, 2, 2, 2, 2, 3, 3, 2, 2, 1, 1, 1, 0.5]; // by 5d step
|
// x3 = 50-60 latitude: wet all year (rising zone)
|
||||||
|
// x2 = 60-70 latitude: wet summer (rising zone), dry winter (sinking zone)
|
||||||
|
// x1 = 70-90 latitude: dry all year (sinking zone)
|
||||||
|
const lalitudeModifier = [4, 2, 2, 2, 1, 1, 2, 2, 2, 2, 3, 3, 2, 2, 1, 1, 1, 0.5];
|
||||||
|
|
||||||
// difine wind directions based on cells latitude and prevailing winds there
|
// difine wind directions based on cells latitude and prevailing winds there
|
||||||
d3.range(0, cells.i.length, cellsX).forEach(function (c, i) {
|
d3.range(0, cells.i.length, cellsX).forEach(function (c, i) {
|
||||||
|
|
@ -985,15 +990,17 @@ function generatePrecipitation() {
|
||||||
const band = ((Math.abs(lat) - 1) / 5) | 0;
|
const band = ((Math.abs(lat) - 1) / 5) | 0;
|
||||||
const latMod = lalitudeModifier[band];
|
const latMod = lalitudeModifier[band];
|
||||||
const tier = (Math.abs(lat - 89) / 30) | 0; // 30d tiers from 0 to 5 from N to S
|
const tier = (Math.abs(lat - 89) / 30) | 0; // 30d tiers from 0 to 5 from N to S
|
||||||
if (options.winds[tier] > 40 && options.winds[tier] < 140) westerly.push([c, latMod, tier]);
|
|
||||||
else if (options.winds[tier] > 220 && options.winds[tier] < 320) easterly.push([c + cellsX - 1, latMod, tier]);
|
if (isWest(tier)) westerly.push([c, latMod, tier]);
|
||||||
if (options.winds[tier] > 100 && options.winds[tier] < 260) northerly++;
|
else if (isEast(tier)) easterly.push([c + cellsX - 1, latMod, tier]);
|
||||||
else if (options.winds[tier] > 280 || options.winds[tier] < 80) southerly++;
|
if (isSouth(tier)) northerly++;
|
||||||
|
if (isNorth(tier)) southerly++;
|
||||||
});
|
});
|
||||||
|
|
||||||
// distribute winds by direction
|
// distribute winds by direction
|
||||||
if (westerly.length) passWind(westerly, 120 * modifier, 1, cellsX);
|
if (westerly.length) passWind(westerly, 120 * modifier, 1, cellsX);
|
||||||
if (easterly.length) passWind(easterly, 120 * modifier, -1, cellsX);
|
if (easterly.length) passWind(easterly, 120 * modifier, -1, cellsX);
|
||||||
|
|
||||||
const vertT = southerly + northerly;
|
const vertT = southerly + northerly;
|
||||||
if (northerly) {
|
if (northerly) {
|
||||||
const bandN = ((Math.abs(mapCoordinates.latN) - 1) / 5) | 0;
|
const bandN = ((Math.abs(mapCoordinates.latN) - 1) / 5) | 0;
|
||||||
|
|
@ -1001,6 +1008,7 @@ function generatePrecipitation() {
|
||||||
const maxPrecN = (northerly / vertT) * 60 * modifier * latModN;
|
const maxPrecN = (northerly / vertT) * 60 * modifier * latModN;
|
||||||
passWind(d3.range(0, cellsX, 1), maxPrecN, cellsX, cellsY);
|
passWind(d3.range(0, cellsX, 1), maxPrecN, cellsX, cellsY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (southerly) {
|
if (southerly) {
|
||||||
const bandS = ((Math.abs(mapCoordinates.latS) - 1) / 5) | 0;
|
const bandS = ((Math.abs(mapCoordinates.latS) - 1) / 5) | 0;
|
||||||
const latModS = mapCoordinates.latT > 60 ? d3.mean(lalitudeModifier) : lalitudeModifier[bandS];
|
const latModS = mapCoordinates.latT > 60 ? d3.mean(lalitudeModifier) : lalitudeModifier[bandS];
|
||||||
|
|
@ -1010,18 +1018,21 @@ function generatePrecipitation() {
|
||||||
|
|
||||||
function passWind(source, maxPrec, next, steps) {
|
function passWind(source, maxPrec, next, steps) {
|
||||||
const maxPrecInit = maxPrec;
|
const maxPrecInit = maxPrec;
|
||||||
|
|
||||||
for (let first of source) {
|
for (let first of source) {
|
||||||
if (first[0]) {
|
if (first[0]) {
|
||||||
maxPrec = Math.min(maxPrecInit * first[1], 255);
|
maxPrec = Math.min(maxPrecInit * first[1], 255);
|
||||||
first = first[0];
|
first = first[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
let humidity = maxPrec - cells.h[first]; // initial water amount
|
let humidity = maxPrec - cells.h[first]; // initial water amount
|
||||||
if (humidity <= 0) continue; // if first cell in row is too elevated cosdired wind dry
|
if (humidity <= 0) continue; // if first cell in row is too elevated cosdired wind dry
|
||||||
|
|
||||||
for (let s = 0, current = first; s < steps; s++, current += next) {
|
for (let s = 0, current = first; s < steps; s++, current += next) {
|
||||||
// no flux on permafrost
|
if (cells.temp[current] < -5) continue; // no flux in permafrost
|
||||||
if (cells.temp[current] < -5) continue;
|
|
||||||
// water cell
|
|
||||||
if (cells.h[current] < 20) {
|
if (cells.h[current] < 20) {
|
||||||
|
// water cell
|
||||||
if (cells.h[current + next] >= 20) {
|
if (cells.h[current + next] >= 20) {
|
||||||
cells.prec[current + next] += Math.max(humidity / rand(10, 20), 1); // coastal precipitation
|
cells.prec[current + next] += Math.max(humidity / rand(10, 20), 1); // coastal precipitation
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1032,16 +1043,16 @@ function generatePrecipitation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// land cell
|
// land cell
|
||||||
const precipitation = getPrecipitation(humidity, current, next);
|
const isPassable = cells.h[current + next] <= MAX_PASSABLE_ELEVATION;
|
||||||
|
const precipitation = isPassable ? getPrecipitation(humidity, current, next) : humidity;
|
||||||
cells.prec[current] += precipitation;
|
cells.prec[current] += precipitation;
|
||||||
const evaporation = precipitation > 1.5 ? 1 : 0; // some humidity evaporates back to the atmosphere
|
const evaporation = precipitation > 1.5 ? 1 : 0; // some humidity evaporates back to the atmosphere
|
||||||
humidity = Math.min(Math.max(humidity - precipitation + evaporation, 0), maxPrec);
|
humidity = isPassable ? Math.min(Math.max(humidity - precipitation + evaporation, 0), maxPrec) : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPrecipitation(humidity, i, n) {
|
function getPrecipitation(humidity, i, n) {
|
||||||
if (cells.h[i + n] > 85) return humidity; // 85 is max passable height
|
|
||||||
const normalLoss = Math.max(humidity / (10 * modifier), 1); // precipitation in normal conditions
|
const normalLoss = Math.max(humidity / (10 * modifier), 1); // precipitation in normal conditions
|
||||||
const diff = Math.max(cells.h[i + n] - cells.h[i], 0); // difference in height
|
const diff = Math.max(cells.h[i + n] - cells.h[i], 0); // difference in height
|
||||||
const mod = (cells.h[i + n] / 70) ** 2; // 50 stands for hills, 70 for mountains
|
const mod = (cells.h[i + n] / 70) ** 2; // 50 stands for hills, 70 for mountains
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue