refactor: heightmap config

This commit is contained in:
Azgaar 2022-07-11 00:16:18 +03:00
parent 6b2de4d20e
commit d18636eb8f
9 changed files with 214 additions and 121 deletions

View file

@ -148,22 +148,127 @@ interface HeightMapTemplate {
id: number;
name: string;
template: string;
probability: number;
probability: number; // selection probability, Int
coversGlobe: number; // chance to cover the whole globe [0, 1]
size: {
expected: number;
deviation: number;
min: number;
max?: number;
};
}
export const heightmapTemplates: Dict<HeightMapTemplate> = {
volcano: {id: 0, name: "Volcano", template: volcano, probability: 3},
highIsland: {id: 1, name: "High Island", template: highIsland, probability: 19},
lowIsland: {id: 2, name: "Low Island", template: lowIsland, probability: 9},
continents: {id: 3, name: "Continents", template: continents, probability: 16},
archipelago: {id: 4, name: "Archipelago", template: archipelago, probability: 18},
atoll: {id: 5, name: "Atoll", template: atoll, probability: 1},
mediterranean: {id: 6, name: "Mediterranean", template: mediterranean, probability: 5},
peninsula: {id: 7, name: "Peninsula", template: peninsula, probability: 3},
pangea: {id: 8, name: "Pangea", template: pangea, probability: 5},
isthmus: {id: 9, name: "Isthmus", template: isthmus, probability: 2},
shattered: {id: 10, name: "Shattered", template: shattered, probability: 7},
taklamakan: {id: 11, name: "Taklamakan", template: taklamakan, probability: 1},
oldWorld: {id: 12, name: "Old World", template: oldWorld, probability: 8},
fractious: {id: 13, name: "Fractious", template: fractious, probability: 3}
volcano: {
id: 0,
name: "Volcano",
template: volcano,
probability: 3,
coversGlobe: 0,
size: {expected: 20, deviation: 20, min: 10}
},
highIsland: {
id: 1,
name: "High Island",
template: highIsland,
probability: 19,
coversGlobe: 0.25,
size: {expected: 30, deviation: 20, min: 15}
},
lowIsland: {
id: 2,
name: "Low Island",
template: lowIsland,
probability: 9,
coversGlobe: 0.1,
size: {expected: 30, deviation: 20, min: 15}
},
continents: {
id: 3,
name: "Continents",
template: continents,
probability: 16,
coversGlobe: 0.5,
size: {expected: 30, deviation: 20, min: 15}
},
archipelago: {
id: 4,
name: "Archipelago",
template: archipelago,
probability: 18,
coversGlobe: 0.35,
size: {expected: 30, deviation: 20, min: 15}
},
atoll: {
id: 5,
name: "Atoll",
template: atoll,
probability: 1,
coversGlobe: 0,
size: {expected: 5, deviation: 10, min: 2}
},
mediterranean: {
id: 6,
name: "Mediterranean",
template: mediterranean,
probability: 5,
coversGlobe: 0,
size: {expected: 25, deviation: 30, min: 15, max: 80}
},
peninsula: {
id: 7,
name: "Peninsula",
template: peninsula,
probability: 3,
coversGlobe: 0,
size: {expected: 15, deviation: 15, min: 5, max: 80}
},
pangea: {
id: 8,
name: "Pangea",
template: pangea,
probability: 5,
coversGlobe: 1,
size: {expected: 70, deviation: 20, min: 30}
},
isthmus: {
id: 9,
name: "Isthmus",
template: isthmus,
probability: 2,
coversGlobe: 0,
size: {expected: 15, deviation: 20, min: 3, max: 80}
},
shattered: {
id: 10,
name: "Shattered",
template: shattered,
probability: 7,
coversGlobe: 0.7,
size: {expected: 30, deviation: 20, min: 15}
},
taklamakan: {
id: 11,
name: "Taklamakan",
template: taklamakan,
probability: 1,
coversGlobe: 0,
size: {expected: 30, deviation: 20, min: 15}
},
oldWorld: {
id: 12,
name: "Old World",
template: oldWorld,
probability: 8,
coversGlobe: 0.35,
size: {expected: 30, deviation: 20, min: 15}
},
fractious: {
id: 13,
name: "Fractious",
template: fractious,
probability: 3,
coversGlobe: 0.2,
size: {expected: 30, deviation: 20, min: 15}
}
};

View file

@ -1,30 +1,32 @@
interface PrecreatedHeightmap {
id: number;
name: string;
size: number;
latitude: number;
}
export const precreatedHeightmaps: Dict<PrecreatedHeightmap> = {
"africa-centric": {id: 0, name: "Africa Centric"},
arabia: {id: 1, name: "Arabia"},
atlantics: {id: 2, name: "Atlantics"},
britain: {id: 3, name: "Britain"},
caribbean: {id: 4, name: "Caribbean"},
"east-asia": {id: 5, name: "East Asia"},
eurasia: {id: 6, name: "Eurasia"},
europe: {id: 7, name: "Europe"},
"europe-accented": {id: 8, name: "Europe Accented"},
"europe-and-central-asia": {id: 9, name: "Europe and Central Asia"},
"europe-central": {id: 10, name: "Europe Central"},
"europe-north": {id: 11, name: "Europe North"},
greenland: {id: 12, name: "Greenland"},
hellenica: {id: 13, name: "Hellenica"},
iceland: {id: 14, name: "Iceland"},
"indian-ocean": {id: 15, name: "Indian Ocean"},
"mediterranean-sea": {id: 16, name: "Mediterranean Sea"},
"middle-east": {id: 17, name: "Middle East"},
"north-america": {id: 18, name: "North America"},
"us-centric": {id: 19, name: "US-centric"},
"us-mainland": {id: 20, name: "US Mainland"},
world: {id: 21, name: "World"},
"world-from-pacific": {id: 22, name: "World from Pacific"}
"africa-centric": {id: 0, name: "Africa Centric", size: 45, latitude: 53},
arabia: {id: 1, name: "Arabia", size: 20, latitude: 35},
atlantics: {id: 2, name: "Atlantics", size: 42, latitude: 23},
britain: {id: 3, name: "Britain", size: 7, latitude: 20},
caribbean: {id: 4, name: "Caribbean", size: 15, latitude: 40},
"east-asia": {id: 5, name: "East Asia", size: 11, latitude: 28},
eurasia: {id: 6, name: "Eurasia", size: 38, latitude: 19},
europe: {id: 7, name: "Europe", size: 20, latitude: 16},
"europe-accented": {id: 8, name: "Europe Accented", size: 14, latitude: 22},
"europe-and-central-asia": {id: 9, name: "Europe and Central Asia", size: 25, latitude: 10},
"europe-central": {id: 10, name: "Europe Central", size: 11, latitude: 22},
"europe-north": {id: 11, name: "Europe North", size: 7, latitude: 18},
greenland: {id: 12, name: "Greenland", size: 22, latitude: 7},
hellenica: {id: 13, name: "Hellenica", size: 8, latitude: 27},
iceland: {id: 14, name: "Iceland", size: 2, latitude: 15},
"indian-ocean": {id: 15, name: "Indian Ocean", size: 45, latitude: 55},
"mediterranean-sea": {id: 16, name: "Mediterranean Sea", size: 10, latitude: 29},
"middle-east": {id: 17, name: "Middle East", size: 8, latitude: 31},
"north-america": {id: 18, name: "North America", size: 37, latitude: 17},
"us-centric": {id: 19, name: "US-centric", size: 66, latitude: 27},
"us-mainland": {id: 20, name: "US Mainland", size: 16, latitude: 30},
world: {id: 21, name: "World", size: 78, latitude: 27},
"world-from-pacific": {id: 22, name: "World from Pacific", size: 75, latitude: 32}
};

View file

@ -220,7 +220,7 @@ export function open(options) {
Lakes.addLakesInDeepDepressions(grid);
Lakes.openNearSeaLakes(grid);
}
OceanLayers();
OceanLayers(grid);
calculateTemperatures();
generatePrecipitation();
reGraph();
@ -339,7 +339,7 @@ export function open(options) {
markupGridFeatures();
if (erosionAllowed) addLakesInDeepDepressions();
OceanLayers();
OceanLayers(grid);
calculateTemperatures();
generatePrecipitation();
reGraph();

View file

@ -1,75 +0,0 @@
import {byId} from "utils/shorthands";
import {gauss, P} from "utils/probabilityUtils";
import {locked} from "scripts/options/lock";
import {rn} from "utils/numberUtils";
// define map size and position based on template and random factor
export function defineMapSize() {
const [size, latitude] = getSizeAndLatitude();
const randomize = new URL(window.location.href).searchParams.get("options") === "default"; // ignore stored options
if (randomize || !locked("mapSize")) mapSizeOutput.value = mapSizeInput.value = rn(size);
if (randomize || !locked("latitude")) latitudeOutput.value = latitudeInput.value = rn(latitude);
function getSizeAndLatitude() {
const template = byId("templateInput").value; // heightmap template
if (template === "africa-centric") return [45, 53];
if (template === "arabia") return [20, 35];
if (template === "atlantics") return [42, 23];
if (template === "britain") return [7, 20];
if (template === "caribbean") return [15, 40];
if (template === "east-asia") return [11, 28];
if (template === "eurasia") return [38, 19];
if (template === "europe") return [20, 16];
if (template === "europe-accented") return [14, 22];
if (template === "europe-and-central-asia") return [25, 10];
if (template === "europe-central") return [11, 22];
if (template === "europe-north") return [7, 18];
if (template === "greenland") return [22, 7];
if (template === "hellenica") return [8, 27];
if (template === "iceland") return [2, 15];
if (template === "indian-ocean") return [45, 55];
if (template === "mediterranean-sea") return [10, 29];
if (template === "middle-east") return [8, 31];
if (template === "north-america") return [37, 17];
if (template === "us-centric") return [66, 27];
if (template === "us-mainland") return [16, 30];
if (template === "world") return [78, 27];
if (template === "world-from-pacific") return [75, 32];
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
if (!part) {
if (template === "Pangea") return [100, 50];
if (template === "Shattered" && P(0.7)) return [100, 50];
if (template === "Continents" && P(0.5)) return [100, 50];
if (template === "Archipelago" && P(0.35)) return [100, 50];
if (template === "High Island" && P(0.25)) return [100, 50];
if (template === "Low Island" && P(0.1)) return [100, 50];
}
if (template === "Pangea") return [gauss(70, 20, 30, max), lat()];
if (template === "Volcano") return [gauss(20, 20, 10, max), lat()];
if (template === "Mediterranean") return [gauss(25, 30, 15, 80), lat()];
if (template === "Peninsula") return [gauss(15, 15, 5, 80), lat()];
if (template === "Isthmus") return [gauss(15, 20, 3, 80), lat()];
if (template === "Atoll") return [gauss(5, 10, 2, max), lat()];
return [gauss(30, 20, 15, max), lat()]; // Continents, Archipelago, High Island, Low Island
}
}
// calculate map position on globe
export function calculateMapCoordinates() {
const size = +byId("mapSizeOutput").value;
const latShift = +byId("latitudeOutput").value;
const latT = rn((size / 100) * 180, 1);
const latN = rn(90 - ((180 - latT) * latShift) / 100, 1);
const latS = rn(latN - latT, 1);
const lon = rn(Math.min(((graphWidth / graphHeight) * latT) / 2, 180));
return {latT, latN, latS, lonT: lon * 2, lonW: -lon, lonE: lon};
}

View file

@ -0,0 +1,57 @@
import {heightmapTemplates} from "config/heightmap-templates";
import {precreatedHeightmaps} from "config/precreated-heightmaps";
import {locked} from "scripts/options/lock";
import {getInputNumber, getInputValue, setInputValue} from "utils/nodeUtils";
import {rn} from "utils/numberUtils";
import {gauss, P} from "utils/probabilityUtils";
// define map size and position based on template and random factor
export function defineMapSize(touchesEdges: boolean) {
const randomize = new URL(window.location.href).searchParams.get("options") === "default"; // ignore stored options
if (!randomize && locked("mapSize") && locked("mapLatitude")) return;
const [size, latitude] = getSizeAndLatitude(touchesEdges);
if (!locked("mapSize")) {
setInputValue("mapSizeOutput", size);
setInputValue("mapSizeInput", size);
}
if (!locked("latitude")) {
setInputValue("latitudeOutput", latitude);
setInputValue("latitudeInput", latitude);
}
}
function getSizeAndLatitude(touchesEdges: boolean) {
const heightmap = getInputValue("templateInput"); // heightmap template
if (heightmap in precreatedHeightmaps) {
const {size, latitude} = precreatedHeightmaps[heightmap];
return [size, latitude];
}
if (heightmap in heightmapTemplates) {
const {coversGlobe, size} = heightmapTemplates[heightmap];
if (!touchesEdges && P(coversGlobe)) return [100, 50]; // whole globe
const {expected, deviation, min, max = touchesEdges ? 80 : 100} = size;
const mapSize = gauss(expected, deviation, min, max);
const latitude = gauss(P(0.5) ? 40 : 60, 15, 25, 75, 0); // latitude shift
return [mapSize, latitude];
}
return [100, 50]; // exception
}
// calculate map position on globe
export function calculateMapCoordinates() {
const size = getInputNumber("mapSizeOutput");
const latShift = getInputNumber("latitudeOutput");
const latT = rn((size / 100) * 180, 1);
const latN = rn(90 - ((180 - latT) * latShift) / 100, 1);
const latS = rn(latN - latT, 1);
const lon = rn(Math.min(((graphWidth / graphHeight) * latT) / 2, 180));
return {latT, latN, latS, lonT: lon * 2, lonW: -lon, lonE: lon};
}

View file

@ -7,9 +7,10 @@ import {P} from "utils/probabilityUtils";
import {round} from "utils/stringUtils";
window.OceanLayers = (function () {
function render() {
function render(grid) {
const outline = oceanLayers.attr("layers");
if (outline === "none") return;
TIME && console.time("drawOceanLayers");
const lineGen = d3.line().curve(d3.curveBasisClosed);

View file

@ -122,7 +122,7 @@ window.Submap = (function () {
Lakes.openNearSeaLakes(grid);
}
OceanLayers();
OceanLayers(grid);
calculateMapCoordinates();
// calculateTemperatures();

View file

@ -459,7 +459,7 @@ styleOceanPatternOpacity.addEventListener("input", function () {
outlineLayers.addEventListener("change", function () {
oceanLayers.selectAll("path").remove();
oceanLayers.attr("layers", this.value);
OceanLayers();
OceanLayers(grid);
});
styleHeightmapScheme.addEventListener("change", function () {
@ -836,7 +836,7 @@ function updateElements() {
if (layerIsOn("toggleHeight")) drawHeightmap();
if (legend.selectAll("*").size() && window.redrawLegend) redrawLegend();
oceanLayers.selectAll("path").remove();
OceanLayers();
OceanLayers(grid);
Zoom.invoke();
}

View file

@ -125,11 +125,14 @@ async function updateGrid(precreatedGraph?: IGrid) {
updatedGrid.cells.t = distanceField;
updatedGrid.features = features;
const touchesEdges = features.some(feature => feature && feature.land && feature.border);
defineMapSize(touchesEdges);
Lakes.addLakesInDeepDepressions(updatedGrid);
Lakes.openNearSeaLakes(updatedGrid);
OceanLayers();
defineMapSize();
OceanLayers(updatedGrid);
window.mapCoordinates = calculateMapCoordinates();
calculateTemperatures();
generatePrecipitation();