mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-22 03:51:23 +01:00
feat: routes - cleanup code
This commit is contained in:
parent
22edfb0dec
commit
597f6ddd75
2 changed files with 13 additions and 113 deletions
|
|
@ -108,8 +108,6 @@ window.Routes = (function () {
|
||||||
TIME && console.time("generateSeaRoutes");
|
TIME && console.time("generateSeaRoutes");
|
||||||
const seaRoutes = [];
|
const seaRoutes = [];
|
||||||
|
|
||||||
let skip = false;
|
|
||||||
|
|
||||||
for (const [featureId, featurePorts] of Object.entries(portsByFeature)) {
|
for (const [featureId, featurePorts] of Object.entries(portsByFeature)) {
|
||||||
const points = featurePorts.map(burg => [burg.x, burg.y]);
|
const points = featurePorts.map(burg => [burg.x, burg.y]);
|
||||||
const urquhartEdges = calculateUrquhartEdges(points);
|
const urquhartEdges = calculateUrquhartEdges(points);
|
||||||
|
|
@ -117,27 +115,6 @@ window.Routes = (function () {
|
||||||
urquhartEdges.forEach(([fromId, toId]) => {
|
urquhartEdges.forEach(([fromId, toId]) => {
|
||||||
const start = featurePorts[fromId].cell;
|
const start = featurePorts[fromId].cell;
|
||||||
const exit = featurePorts[toId].cell;
|
const exit = featurePorts[toId].cell;
|
||||||
|
|
||||||
if (skip) return;
|
|
||||||
if (start === 444 && exit === 297) {
|
|
||||||
// if (segment.join(",") === "124,122,120") debugger;
|
|
||||||
skip = true;
|
|
||||||
|
|
||||||
for (const con of connections) {
|
|
||||||
const [from, to] = con[0].split("-").map(Number);
|
|
||||||
const [x1, y1] = cells.p[from];
|
|
||||||
const [x2, y2] = cells.p[to];
|
|
||||||
debug
|
|
||||||
.append("line")
|
|
||||||
.attr("x1", x1)
|
|
||||||
.attr("y1", y1)
|
|
||||||
.attr("x2", x2)
|
|
||||||
.attr("y2", y2)
|
|
||||||
.attr("stroke", "red")
|
|
||||||
.attr("stroke-width", 0.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const segments = findPathSegments({isWater: true, connections, start, exit});
|
const segments = findPathSegments({isWater: true, connections, start, exit});
|
||||||
for (const segment of segments) {
|
for (const segment of segments) {
|
||||||
addConnections(segment, ROUTES.SEA_ROUTE);
|
addConnections(segment, ROUTES.SEA_ROUTE);
|
||||||
|
|
@ -195,8 +172,8 @@ window.Routes = (function () {
|
||||||
const TYPE_MODIFIERS = {
|
const TYPE_MODIFIERS = {
|
||||||
"-1": 1, // coastline
|
"-1": 1, // coastline
|
||||||
"-2": 1.8, // sea
|
"-2": 1.8, // sea
|
||||||
"-3": 3, // open sea
|
"-3": 4, // open sea
|
||||||
"-4": 5, // ocean
|
"-4": 6, // ocean
|
||||||
default: 8 // far ocean
|
default: 8 // far ocean
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -209,8 +186,6 @@ window.Routes = (function () {
|
||||||
const queue = new FlatQueue();
|
const queue = new FlatQueue();
|
||||||
queue.push(start, 0);
|
queue.push(start, 0);
|
||||||
|
|
||||||
const isDebug = start === 444 && exit === 297;
|
|
||||||
|
|
||||||
return isWater ? findWaterPath() : findLandPath();
|
return isWater ? findWaterPath() : findLandPath();
|
||||||
|
|
||||||
function findLandPath() {
|
function findLandPath() {
|
||||||
|
|
@ -219,26 +194,26 @@ window.Routes = (function () {
|
||||||
const next = queue.pop();
|
const next = queue.pop();
|
||||||
|
|
||||||
for (const neibCellId of cells.c[next]) {
|
for (const neibCellId of cells.c[next]) {
|
||||||
if (cells.h[neibCellId] < 20) continue; // ignore water cells
|
if (neibCellId === exit) {
|
||||||
|
from[neibCellId] = next;
|
||||||
|
return from;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cells.h[neibCellId] < 20) continue; // ignore water cells
|
||||||
const habitability = biomesData.habitability[cells.biome[neibCellId]];
|
const habitability = biomesData.habitability[cells.biome[neibCellId]];
|
||||||
if (!habitability) continue; // inhabitable cells are not passable (eg. lava, glacier)
|
if (!habitability) continue; // inhabitable cells are not passable (eg. lava, glacier)
|
||||||
|
|
||||||
const distanceCost = dist2(cells.p[next], cells.p[neibCellId]);
|
const distanceCost = dist2(cells.p[next], cells.p[neibCellId]);
|
||||||
|
|
||||||
const habitabilityModifier = 1 + Math.max(100 - habitability, 0) / 1000; // [1, 1.1];
|
const habitabilityModifier = 1 + Math.max(100 - habitability, 0) / 1000; // [1, 1.1];
|
||||||
const heightModifier = 1 + Math.max(cells.h[neibCellId] - 25, 25) / 25; // [1, 3];
|
const heightModifier = 1 + Math.max(cells.h[neibCellId] - 25, 25) / 25; // [1, 3];
|
||||||
const connectionModifier = connections.has(`${next}-${neibCellId}`) ? 1 : 3;
|
const connectionModifier = connections.has(`${next}-${neibCellId}`) ? 1 : 2;
|
||||||
const burgModifier = cells.burg[neibCellId] ? 1 : 3;
|
const burgModifier = cells.burg[neibCellId] ? 1 : 3;
|
||||||
|
|
||||||
const cellsCost = distanceCost * habitabilityModifier * heightModifier * connectionModifier * burgModifier;
|
const cellsCost = distanceCost * habitabilityModifier * heightModifier * connectionModifier * burgModifier;
|
||||||
const totalCost = priority + cellsCost;
|
const totalCost = priority + cellsCost;
|
||||||
|
|
||||||
if (from[neibCellId] || totalCost >= cost[neibCellId]) continue;
|
if (totalCost >= cost[neibCellId]) continue;
|
||||||
from[neibCellId] = next;
|
from[neibCellId] = next;
|
||||||
|
|
||||||
if (neibCellId === exit) return from;
|
|
||||||
|
|
||||||
cost[neibCellId] = totalCost;
|
cost[neibCellId] = totalCost;
|
||||||
queue.push(neibCellId, totalCost);
|
queue.push(neibCellId, totalCost);
|
||||||
}
|
}
|
||||||
|
|
@ -251,16 +226,13 @@ window.Routes = (function () {
|
||||||
while (queue.length) {
|
while (queue.length) {
|
||||||
const priority = queue.peekValue();
|
const priority = queue.peekValue();
|
||||||
const next = queue.pop();
|
const next = queue.pop();
|
||||||
isDebug && console.log("next", next);
|
|
||||||
|
|
||||||
for (const neibCellId of cells.c[next]) {
|
for (const neibCellId of cells.c[next]) {
|
||||||
if (neibCellId === exit) {
|
if (neibCellId === exit) {
|
||||||
isDebug && console.log(`neib ${neibCellId} is exit`);
|
|
||||||
from[neibCellId] = next;
|
from[neibCellId] = next;
|
||||||
return from;
|
return from;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (from[neibCellId]) continue; // don't go back
|
|
||||||
if (cells.h[neibCellId] >= 20) continue; // ignore land cells
|
if (cells.h[neibCellId] >= 20) continue; // ignore land cells
|
||||||
if (temp[cells.g[neibCellId]] < MIN_PASSABLE_SEA_TEMP) continue; // ignore too cold cells
|
if (temp[cells.g[neibCellId]] < MIN_PASSABLE_SEA_TEMP) continue; // ignore too cold cells
|
||||||
|
|
||||||
|
|
@ -271,19 +243,8 @@ window.Routes = (function () {
|
||||||
const cellsCost = distanceCost * typeModifier * connectionModifier;
|
const cellsCost = distanceCost * typeModifier * connectionModifier;
|
||||||
const totalCost = priority + cellsCost;
|
const totalCost = priority + cellsCost;
|
||||||
|
|
||||||
if (isDebug) {
|
|
||||||
const lost = totalCost >= cost[neibCellId];
|
|
||||||
console.log(
|
|
||||||
`neib ${neibCellId}`,
|
|
||||||
`cellCost ${rn(cellsCost)}`,
|
|
||||||
`new ${rn(totalCost)} ${lost ? ">=" : "<"} prev ${rn(cost[neibCellId])}.`,
|
|
||||||
`${lost ? "lost" : "won"}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (totalCost >= cost[neibCellId]) continue;
|
if (totalCost >= cost[neibCellId]) continue;
|
||||||
from[neibCellId] = next;
|
from[neibCellId] = next;
|
||||||
|
|
||||||
cost[neibCellId] = totalCost;
|
cost[neibCellId] = totalCost;
|
||||||
queue.push(neibCellId, totalCost);
|
queue.push(neibCellId, totalCost);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -393,7 +393,6 @@ function drawTemp() {
|
||||||
const start = findStart(i, t);
|
const start = findStart(i, t);
|
||||||
if (!start) continue;
|
if (!start) continue;
|
||||||
used[i] = 1;
|
used[i] = 1;
|
||||||
//debug.append("circle").attr("r", 3).attr("cx", vertices.p[start][0]).attr("cy", vertices.p[start][1]).attr("fill", "red").attr("stroke", "black").attr("stroke-width", .3);
|
|
||||||
|
|
||||||
const chain = connectVertices(start, t); // vertices chain to form a path
|
const chain = connectVertices(start, t); // vertices chain to form a path
|
||||||
const relaxed = chain.filter((v, i) => i % 4 === 0 || vertices.c[v].some(c => c >= n));
|
const relaxed = chain.filter((v, i) => i % 4 === 0 || vertices.c[v].some(c => c >= n));
|
||||||
|
|
@ -1638,9 +1637,6 @@ function drawRoutes() {
|
||||||
TIME && console.time("drawRoutes");
|
TIME && console.time("drawRoutes");
|
||||||
const {cells, burgs} = pack;
|
const {cells, burgs} = pack;
|
||||||
|
|
||||||
const SHARP_ANGLE = 135;
|
|
||||||
const VERY_SHARP_ANGLE = 115;
|
|
||||||
|
|
||||||
const points = adjustBurgPoints(); // mutable array of points
|
const points = adjustBurgPoints(); // mutable array of points
|
||||||
const routePaths = {};
|
const routePaths = {};
|
||||||
|
|
||||||
|
|
@ -1651,27 +1647,12 @@ function drawRoutes() {
|
||||||
searoutes: d3.curveCatmullRom.alpha(0.5),
|
searoutes: d3.curveCatmullRom.alpha(0.5),
|
||||||
default: d3.curveCatmullRom.alpha(0.1)
|
default: d3.curveCatmullRom.alpha(0.1)
|
||||||
};
|
};
|
||||||
|
const SHARP_ANGLE = 135;
|
||||||
|
const VERY_SHARP_ANGLE = 115;
|
||||||
|
|
||||||
for (const {i, group, cells} of pack.routes) {
|
for (const {i, group, cells} of pack.routes) {
|
||||||
// if (group !== "searoutes") straightenPathAngles(cells); // mutates points
|
if (group !== "searoutes") straightenPathAngles(cells); // mutates points
|
||||||
const pathPoints = getPathPoints(cells);
|
|
||||||
|
|
||||||
// TODO: temporary view for searoutes
|
|
||||||
if (group) {
|
|
||||||
const pathPoints = cells.map(cellId => points[cellId]);
|
const pathPoints = cells.map(cellId => points[cellId]);
|
||||||
const color = getMixedColor("#000000", 0.6);
|
|
||||||
const line = "M" + pathPoints.join("L");
|
|
||||||
pathPoints.forEach(([x, y]) =>
|
|
||||||
debug.append("circle").attr("r", 0.7).attr("cx", x).attr("cy", y).attr("fill", color)
|
|
||||||
);
|
|
||||||
if (!routePaths[group]) routePaths[group] = [];
|
|
||||||
routePaths[group].push(`<path id="route${i}" d="${line}" stroke=${color} />`);
|
|
||||||
|
|
||||||
// lineGen.curve(curves[group] || curves.default);
|
|
||||||
// const path = round(lineGen(pathPoints), 1);
|
|
||||||
// routePaths[group].push(`<path id="route${i}" d="${path}" stroke-width="0.15"/> `);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
lineGen.curve(curves[group] || curves.default);
|
lineGen.curve(curves[group] || curves.default);
|
||||||
const path = round(lineGen(pathPoints), 1);
|
const path = round(lineGen(pathPoints), 1);
|
||||||
|
|
@ -1685,8 +1666,6 @@ function drawRoutes() {
|
||||||
routes.select("#" + group).html(routePaths[group].join(""));
|
routes.select("#" + group).html(routePaths[group].join(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
drawCellsValue(pack.cells.i);
|
|
||||||
|
|
||||||
TIME && console.timeEnd("drawRoutes");
|
TIME && console.timeEnd("drawRoutes");
|
||||||
|
|
||||||
function adjustBurgPoints() {
|
function adjustBurgPoints() {
|
||||||
|
|
@ -1733,46 +1712,6 @@ function drawRoutes() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPathPoints(cellIds) {
|
|
||||||
const pathPoints = cellIds.map(cellId => points[cellId]);
|
|
||||||
|
|
||||||
if (pathPoints.length === 2) {
|
|
||||||
// curve and shorten 2-points line
|
|
||||||
const [[x1, y1], [x2, y2]] = pathPoints;
|
|
||||||
|
|
||||||
const middleX = (x1 + x2) / 2;
|
|
||||||
const middleY = (y1 + y2) / 2;
|
|
||||||
|
|
||||||
// add shifted point at the middle to curve the line a bit
|
|
||||||
const NORMAL_LENGTH = 0.3;
|
|
||||||
const normal = getNormal([x1, y1], [x2, y2]);
|
|
||||||
const sign = cellIds[0] % 2 ? 1 : -1;
|
|
||||||
const normalX = middleX + NORMAL_LENGTH * Math.cos(normal) * sign;
|
|
||||||
const normalY = middleY + NORMAL_LENGTH * Math.sin(normal) * sign;
|
|
||||||
|
|
||||||
// make line shorter to avoid overlapping with other lines
|
|
||||||
const SHORT_LINE_LENGTH_MODIFIER = 0.8;
|
|
||||||
const distX = x2 - x1;
|
|
||||||
const distY = y2 - y1;
|
|
||||||
const nx1 = x1 + distX * SHORT_LINE_LENGTH_MODIFIER;
|
|
||||||
const ny1 = y1 + distY * SHORT_LINE_LENGTH_MODIFIER;
|
|
||||||
const nx2 = x2 - distX * SHORT_LINE_LENGTH_MODIFIER;
|
|
||||||
const ny2 = y2 - distY * SHORT_LINE_LENGTH_MODIFIER;
|
|
||||||
|
|
||||||
return [
|
|
||||||
[nx1, ny1],
|
|
||||||
[normalX, normalY],
|
|
||||||
[nx2, ny2]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return pathPoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNormal([x1, y1], [x2, y2]) {
|
|
||||||
return Math.atan2(y1 - y2, x1 - x2) + Math.PI / 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleMilitary() {
|
function toggleMilitary() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue