mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 17:51:24 +01:00
refactor: heightmap config
This commit is contained in:
parent
6b2de4d20e
commit
d18636eb8f
9 changed files with 214 additions and 121 deletions
|
|
@ -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}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
}
|
||||
57
src/modules/coordinates.ts
Normal file
57
src/modules/coordinates.ts
Normal 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};
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ window.Submap = (function () {
|
|||
Lakes.openNearSeaLakes(grid);
|
||||
}
|
||||
|
||||
OceanLayers();
|
||||
OceanLayers(grid);
|
||||
|
||||
calculateMapCoordinates();
|
||||
// calculateTemperatures();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue