mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
river generator - subs confluence to select main stem
This commit is contained in:
parent
5c0b92c542
commit
77f371e28f
2 changed files with 25 additions and 12 deletions
|
|
@ -31,7 +31,11 @@
|
||||||
const land = cells.i.filter(i => h[i] >= 20).sort((a, b) => h[b] - h[a]);
|
const land = cells.i.filter(i => h[i] >= 20).sort((a, b) => h[b] - h[a]);
|
||||||
const lakeOutCells = Lakes.setClimateData(h);
|
const lakeOutCells = Lakes.setClimateData(h);
|
||||||
|
|
||||||
|
let step = 0;
|
||||||
|
|
||||||
land.forEach(function (i) {
|
land.forEach(function (i) {
|
||||||
|
step++;
|
||||||
|
|
||||||
cells.fl[i] += grid.cells.prec[cells.g[i]]; // flux from precipitation
|
cells.fl[i] += grid.cells.prec[cells.g[i]]; // flux from precipitation
|
||||||
const [x, y] = p[i];
|
const [x, y] = p[i];
|
||||||
|
|
||||||
|
|
@ -59,7 +63,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
lake.outlet = cells.r[lakeCell];
|
lake.outlet = cells.r[lakeCell];
|
||||||
flowDown(i, cells.fl[i], cells.fl[lakeCell], lake.outlet);
|
flowDown(i, cells.fl[lakeCell], lake.outlet);
|
||||||
}
|
}
|
||||||
|
|
||||||
// assign all tributary rivers to outlet basin
|
// assign all tributary rivers to outlet basin
|
||||||
|
|
@ -100,15 +104,24 @@
|
||||||
riverNext++;
|
riverNext++;
|
||||||
}
|
}
|
||||||
|
|
||||||
flowDown(min, cells.fl[min], cells.fl[i], cells.r[i], i);
|
flowDown(min, cells.fl[i], cells.r[i], i, step);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function flowDown(toCell, toFlux, fromFlux, river, fromCell = 0) {
|
function flowDown(toCell, fromFlux, river, fromCell, step) {
|
||||||
|
const toFlux = cells.fl[toCell] - cells.conf[toCell];
|
||||||
|
// prettier-ignore
|
||||||
|
if (step) debug.append("text")
|
||||||
|
.attr("x", pack.cells.p[fromCell][0])
|
||||||
|
.attr("y", pack.cells.p[fromCell][1])
|
||||||
|
.text(`${step}: ${fromFlux} -> ${toFlux}`)
|
||||||
|
.attr("font-size", "1.5px");
|
||||||
|
|
||||||
if (cells.r[toCell]) {
|
if (cells.r[toCell]) {
|
||||||
// downhill cell already has river assigned
|
// downhill cell already has river assigned
|
||||||
if (toFlux < fromFlux) {
|
|
||||||
cells.conf[toCell] = cells.fl[toCell]; // mark confluence
|
if (fromFlux > toFlux) {
|
||||||
|
cells.conf[toCell] += cells.fl[toCell]; // mark confluence
|
||||||
if (h[toCell] >= 20) riversData.find(r => r.river === cells.r[toCell]).parent = river; // min river is a tributary of current river
|
if (h[toCell] >= 20) riversData.find(r => r.river === cells.r[toCell]).parent = river; // min river is a tributary of current river
|
||||||
cells.r[toCell] = river; // re-assign river if downhill part has less flux
|
cells.r[toCell] = river; // re-assign river if downhill part has less flux
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -155,16 +168,16 @@
|
||||||
|
|
||||||
const source = riverPoints[0].cell;
|
const source = riverPoints[0].cell;
|
||||||
const mouth = riverPoints[riverPoints.length - 2].cell;
|
const mouth = riverPoints[riverPoints.length - 2].cell;
|
||||||
|
const parent = riverPoints[0].parent || 0;
|
||||||
|
|
||||||
const widthFactor = rn(0.8 + Math.random() * 0.4, 1); // river width modifier [.8, 1.2]
|
const widthFactor = parent ? 1 : 1.4;
|
||||||
const sourceWidth = cells.h[source] >= 20 ? 0.1 : rn(Math.min(Math.max((cells.fl[source] / 500) ** 0.4, 0.5), 1.7), 2);
|
const sourceWidth = cells.h[source] >= 20 ? 0.1 : rn(Math.min(Math.max((cells.fl[source] / 500) ** 0.4, 0.5), 1.6), 2);
|
||||||
|
|
||||||
const riverCells = riverPoints.map(point => point.cell);
|
const riverCells = riverPoints.map(point => point.cell);
|
||||||
const riverMeandered = addMeandering(riverCells, sourceWidth * 10, 0.5);
|
const riverMeandered = addMeandering(riverCells, sourceWidth * 10, 0.5);
|
||||||
const [path, length, offset] = getPath(riverMeandered, widthFactor, sourceWidth);
|
const [path, length, offset] = getPath(riverMeandered, widthFactor, sourceWidth);
|
||||||
riverPaths.push([path, r]);
|
riverPaths.push([path, r]);
|
||||||
|
|
||||||
const parent = riverPoints[0].parent || 0;
|
|
||||||
const width = rn(offset ** 2, 2); // mounth width in km
|
const width = rn(offset ** 2, 2); // mounth width in km
|
||||||
const discharge = last(riverPoints).flux; // in m3/s
|
const discharge = last(riverPoints).flux; // in m3/s
|
||||||
|
|
||||||
|
|
@ -295,7 +308,7 @@
|
||||||
const factor = riverLength / points.length;
|
const factor = riverLength / points.length;
|
||||||
let offset;
|
let offset;
|
||||||
|
|
||||||
// store points on both sides to build a valid polygon
|
// store points on both sides to build a polygon
|
||||||
const riverPointsLeft = [];
|
const riverPointsLeft = [];
|
||||||
const riverPointsRight = [];
|
const riverPointsRight = [];
|
||||||
|
|
||||||
|
|
@ -316,12 +329,12 @@
|
||||||
const cosOffset = Math.cos(angle) * offset;
|
const cosOffset = Math.cos(angle) * offset;
|
||||||
|
|
||||||
riverPointsLeft.push([x1 - sinOffset, y1 + cosOffset]);
|
riverPointsLeft.push([x1 - sinOffset, y1 + cosOffset]);
|
||||||
riverPointsRight.unshift([x1 + sinOffset, y1 - cosOffset]);
|
riverPointsRight.push([x1 + sinOffset, y1 - cosOffset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate polygon path and return
|
// generate polygon path and return
|
||||||
lineGen.curve(d3.curveCatmullRom.alpha(0.1));
|
lineGen.curve(d3.curveCatmullRom.alpha(0.1));
|
||||||
const right = lineGen(riverPointsRight);
|
const right = lineGen(riverPointsRight.reverse());
|
||||||
let left = lineGen(riverPointsLeft);
|
let left = lineGen(riverPointsLeft);
|
||||||
left = left.substring(left.indexOf("C"));
|
left = left.substring(left.indexOf("C"));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -616,7 +616,7 @@ function addRiverOnClick() {
|
||||||
|
|
||||||
const river = rivers.find(r => r.i === riverId);
|
const river = rivers.find(r => r.i === riverId);
|
||||||
const sourceWidth = 0.1;
|
const sourceWidth = 0.1;
|
||||||
const widthFactor = river?.widthFactor || rn(0.8 + Math.random() * 0.4, 1);
|
const widthFactor = river?.widthFactor || (parent ? 1 : 1.4);
|
||||||
|
|
||||||
const riverMeandered = Rivers.addMeandering(riverCells, sourceWidth * 10, 0.5);
|
const riverMeandered = Rivers.addMeandering(riverCells, sourceWidth * 10, 0.5);
|
||||||
const [path, length, offset] = Rivers.getPath(riverMeandered, widthFactor, sourceWidth);
|
const [path, length, offset] = Rivers.getPath(riverMeandered, widthFactor, sourceWidth);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue