mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-22 12:01:23 +01:00
feat: rework temperature generation alg
This commit is contained in:
parent
fbb605d01d
commit
42b0cafecd
7 changed files with 128 additions and 96 deletions
66
main.js
66
main.js
|
|
@ -5,8 +5,8 @@
|
|||
// set debug options
|
||||
const PRODUCTION = location.hostname && location.hostname !== "localhost" && location.hostname !== "127.0.0.1";
|
||||
const DEBUG = localStorage.getItem("debug");
|
||||
const INFO = DEBUG || !PRODUCTION;
|
||||
const TIME = DEBUG || !PRODUCTION;
|
||||
const INFO = true;
|
||||
const TIME = true;
|
||||
const WARN = true;
|
||||
const ERROR = true;
|
||||
|
||||
|
|
@ -179,15 +179,17 @@ function onZoom() {
|
|||
const onZoomDebouced = debounce(onZoom, 50);
|
||||
const zoom = d3.zoom().scaleExtent([1, 20]).on("zoom", onZoomDebouced);
|
||||
|
||||
// default options
|
||||
// default options, based on Earth data
|
||||
let options = {
|
||||
pinNotes: false,
|
||||
showMFCGMap: true,
|
||||
winds: [225, 45, 225, 315, 135, 315],
|
||||
tempNorthPole: 0,
|
||||
tempSouthPole: 0,
|
||||
temperatureEquator: 27,
|
||||
temperatureNorthPole: -30,
|
||||
temperatureSouthPole: -15,
|
||||
stateLabelsMode: "auto"
|
||||
};
|
||||
|
||||
let mapCoordinates = {}; // map coordinates on globe
|
||||
let populationRate = +document.getElementById("populationRateInput").value;
|
||||
let distanceScale = +document.getElementById("distanceScaleInput").value;
|
||||
|
|
@ -469,7 +471,7 @@ function applyDefaultBiomesSystem() {
|
|||
const biomesMartix = [
|
||||
// hot ↔ cold [>19°C; <-4°C]; dry ↕ wet
|
||||
new Uint8Array([1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10]),
|
||||
new Uint8Array([3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 9, 9, 9, 9, 10, 10, 10]),
|
||||
new Uint8Array([1, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 9, 9, 9, 9, 10, 10, 10]),
|
||||
new Uint8Array([5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 9, 9, 9, 9, 9, 10, 10, 10]),
|
||||
new Uint8Array([5, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10]),
|
||||
new Uint8Array([7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10])
|
||||
|
|
@ -1010,29 +1012,43 @@ function calculateTemperatures() {
|
|||
TIME && console.time("calculateTemperatures");
|
||||
const cells = grid.cells;
|
||||
cells.temp = new Int8Array(cells.i.length); // temperature array
|
||||
const tEq = +temperatureEquatorInput.value;
|
||||
const tNorthPole = +temperatureNorthPoleInput.value;
|
||||
const tSouthPole = +temperatureSouthPoleInput.value;
|
||||
//Update Settings to match the slider(there may be a better solution)
|
||||
options.tempSouthPole = +tSouthPole;
|
||||
options.tempNorthPole = +tNorthPole;
|
||||
const tNDelta = tEq - tNorthPole;
|
||||
const tSDelta = tEq - tSouthPole;
|
||||
const int = d3.easePolyInOut.exponent(0.5); // interpolation function
|
||||
|
||||
d3.range(0, cells.i.length, grid.cellsX).forEach(function (r) {
|
||||
const y = grid.points[r][1];
|
||||
const lat = (mapCoordinates.latN - (y / graphHeight) * mapCoordinates.latT); // [-90; 90]
|
||||
const initTemp = tEq - (Math.max(rn(lat / 90, 2), 0) * tNDelta - Math.min(rn(lat / 90, 2), 0) * tSDelta);
|
||||
for (let i = r; i < r + grid.cellsX; i++) {
|
||||
cells.temp[i] = minmax(initTemp - convertToFriendly(cells.h[i]), -128, 127);
|
||||
const {temperatureEquator, temperatureNorthPole, temperatureSouthPole} = options;
|
||||
const tropics = [16, -20]; // tropics zone
|
||||
const tropicalGradient = 0.15;
|
||||
|
||||
const tempNorthTropic = temperatureEquator - tropics[0] * tropicalGradient;
|
||||
const northernGradient = (tempNorthTropic - temperatureNorthPole) / (90 - tropics[0]);
|
||||
|
||||
const tempSouthTropic = temperatureEquator + tropics[1] * tropicalGradient;
|
||||
const southernGradient = (tempSouthTropic - temperatureSouthPole) / (90 + tropics[1]);
|
||||
|
||||
const exponent = +heightExponentInput.value;
|
||||
|
||||
for (let rowCellId = 0; rowCellId < cells.i.length; rowCellId += grid.cellsX) {
|
||||
const [, y] = grid.points[rowCellId];
|
||||
const rowLatitude = mapCoordinates.latN - (y / graphHeight) * mapCoordinates.latT; // [90; -90]
|
||||
const tempSeaLevel = calculateSeaLevelTemp(rowLatitude);
|
||||
DEBUG && console.info(`${rn(rowLatitude)}° sea temperature: ${rn(tempSeaLevel)}°C`);
|
||||
|
||||
for (let cellId = rowCellId; cellId < rowCellId + grid.cellsX; cellId++) {
|
||||
const tempAltitudeDrop = getAltitudeTemperatureDrop(cells.h[cellId]);
|
||||
cells.temp[cellId] = minmax(tempSeaLevel - tempAltitudeDrop, -128, 127);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// temperature decreases by 6.5 degree C per 1km
|
||||
function convertToFriendly(h) {
|
||||
function calculateSeaLevelTemp(latitude) {
|
||||
const isTropical = latitude <= 16 && latitude >= -20;
|
||||
if (isTropical) return temperatureEquator - Math.abs(latitude) * tropicalGradient;
|
||||
|
||||
return latitude > 0
|
||||
? tempNorthTropic - (latitude - tropics[0]) * northernGradient
|
||||
: tempSouthTropic + (latitude - tropics[1]) * southernGradient;
|
||||
}
|
||||
|
||||
// temperature drops by 6.5°C per 1km of altitude
|
||||
function getAltitudeTemperatureDrop(h) {
|
||||
if (h < 20) return 0;
|
||||
const exponent = +heightExponentInput.value;
|
||||
const height = Math.pow(h - 18, exponent);
|
||||
return rn((height / 1000) * 6.5);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue