mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 01:41:22 +01:00
Independent North and South Poles temperature (#972)
* Poles to have Different Temperature (Ref: Axial Tilt suggestion) (#964) * Initial Idea * Changed Names: Currently still only on NorthTemperature reliant, compadible version * Restored Generation of Temperature * Temperature Function found * Version Bump * Scuffed Saving solution * Current Version(without the save changes) * Globe Temperature Display * Individual Regeneration of Temperatures * Fixed Loading and Saving New Maps save a Dummy 0 at settings[17] * Final Version Bump (currently no description for the Update) --------- Co-authored-by: Azgaar <maxganiev@yandex.com> * chore: formatting * refactor: temperature inputs * feat: rework temperature generation alg * style: respore winds button * refactor: update options on load, don't update temperature UI * refactor: no need to keep compatibility here * fix: load temp setting from .map file --------- Co-authored-by: Leo <leonard.krusch@gmx.de>
This commit is contained in:
parent
7b3f897bdb
commit
b3e2aa00e7
9 changed files with 240 additions and 155 deletions
63
main.js
63
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,13 +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],
|
||||
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;
|
||||
|
|
@ -467,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])
|
||||
|
|
@ -968,7 +972,7 @@ function defineMapSize() {
|
|||
|
||||
const part = grid.features.some(f => f.land && f.border); // if land goes over map borders
|
||||
const max = part ? 80 : 100; // max size
|
||||
const lat = () => gauss(P(0.5) ? 40 : 60, 15, 25, 75); // latitude shift
|
||||
const lat = () => gauss(P(0.5) ? 40 : 60, 20, 25, 75); // latitude shift
|
||||
|
||||
if (!part) {
|
||||
if (template === "Pangea") return [100, 50];
|
||||
|
|
@ -1003,30 +1007,49 @@ function calculateMapCoordinates() {
|
|||
mapCoordinates = {latT, latN, latS, lonT: lon * 2, lonW: -lon, lonE: lon};
|
||||
}
|
||||
|
||||
// temperature model
|
||||
// temperature model, trying to follow real-world data
|
||||
// based on http://www-das.uwyo.edu/~geerts/cwx/notes/chap16/Image64.gif
|
||||
function calculateTemperatures() {
|
||||
TIME && console.time("calculateTemperatures");
|
||||
const cells = grid.cells;
|
||||
cells.temp = new Int8Array(cells.i.length); // temperature array
|
||||
|
||||
const tEq = +temperatureEquatorInput.value;
|
||||
const tPole = +temperaturePoleInput.value;
|
||||
const tDelta = tEq - tPole;
|
||||
const int = d3.easePolyInOut.exponent(0.5); // interpolation function
|
||||
const {temperatureEquator, temperatureNorthPole, temperatureSouthPole} = options;
|
||||
const tropics = [16, -20]; // tropics zone
|
||||
const tropicalGradient = 0.15;
|
||||
|
||||
d3.range(0, cells.i.length, grid.cellsX).forEach(function (r) {
|
||||
const y = grid.points[r][1];
|
||||
const lat = Math.abs(mapCoordinates.latN - (y / graphHeight) * mapCoordinates.latT); // [0; 90]
|
||||
const initTemp = tEq - int(lat / 90) * tDelta;
|
||||
for (let i = r; i < r + grid.cellsX; i++) {
|
||||
cells.temp[i] = minmax(initTemp - convertToFriendly(cells.h[i]), -128, 127);
|
||||
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