mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-21 19:41: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");
|
||||
const seaRoutes = [];
|
||||
|
||||
let skip = false;
|
||||
|
||||
for (const [featureId, featurePorts] of Object.entries(portsByFeature)) {
|
||||
const points = featurePorts.map(burg => [burg.x, burg.y]);
|
||||
const urquhartEdges = calculateUrquhartEdges(points);
|
||||
|
|
@ -117,27 +115,6 @@ window.Routes = (function () {
|
|||
urquhartEdges.forEach(([fromId, toId]) => {
|
||||
const start = featurePorts[fromId].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});
|
||||
for (const segment of segments) {
|
||||
addConnections(segment, ROUTES.SEA_ROUTE);
|
||||
|
|
@ -195,8 +172,8 @@ window.Routes = (function () {
|
|||
const TYPE_MODIFIERS = {
|
||||
"-1": 1, // coastline
|
||||
"-2": 1.8, // sea
|
||||
"-3": 3, // open sea
|
||||
"-4": 5, // ocean
|
||||
"-3": 4, // open sea
|
||||
"-4": 6, // ocean
|
||||
default: 8 // far ocean
|
||||
};
|
||||
|
||||
|
|
@ -209,8 +186,6 @@ window.Routes = (function () {
|
|||
const queue = new FlatQueue();
|
||||
queue.push(start, 0);
|
||||
|
||||
const isDebug = start === 444 && exit === 297;
|
||||
|
||||
return isWater ? findWaterPath() : findLandPath();
|
||||
|
||||
function findLandPath() {
|
||||
|
|
@ -219,26 +194,26 @@ window.Routes = (function () {
|
|||
const next = queue.pop();
|
||||
|
||||
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]];
|
||||
if (!habitability) continue; // inhabitable cells are not passable (eg. lava, glacier)
|
||||
|
||||
const distanceCost = dist2(cells.p[next], cells.p[neibCellId]);
|
||||
|
||||
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 connectionModifier = connections.has(`${next}-${neibCellId}`) ? 1 : 3;
|
||||
const connectionModifier = connections.has(`${next}-${neibCellId}`) ? 1 : 2;
|
||||
const burgModifier = cells.burg[neibCellId] ? 1 : 3;
|
||||
|
||||
const cellsCost = distanceCost * habitabilityModifier * heightModifier * connectionModifier * burgModifier;
|
||||
const totalCost = priority + cellsCost;
|
||||
|
||||
if (from[neibCellId] || totalCost >= cost[neibCellId]) continue;
|
||||
if (totalCost >= cost[neibCellId]) continue;
|
||||
from[neibCellId] = next;
|
||||
|
||||
if (neibCellId === exit) return from;
|
||||
|
||||
cost[neibCellId] = totalCost;
|
||||
queue.push(neibCellId, totalCost);
|
||||
}
|
||||
|
|
@ -251,16 +226,13 @@ window.Routes = (function () {
|
|||
while (queue.length) {
|
||||
const priority = queue.peekValue();
|
||||
const next = queue.pop();
|
||||
isDebug && console.log("next", next);
|
||||
|
||||
for (const neibCellId of cells.c[next]) {
|
||||
if (neibCellId === exit) {
|
||||
isDebug && console.log(`neib ${neibCellId} is exit`);
|
||||
from[neibCellId] = next;
|
||||
return from;
|
||||
}
|
||||
|
||||
// if (from[neibCellId]) continue; // don't go back
|
||||
if (cells.h[neibCellId] >= 20) continue; // ignore land 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 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;
|
||||
from[neibCellId] = next;
|
||||
|
||||
cost[neibCellId] = totalCost;
|
||||
queue.push(neibCellId, totalCost);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -393,7 +393,6 @@ function drawTemp() {
|
|||
const start = findStart(i, t);
|
||||
if (!start) continue;
|
||||
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 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");
|
||||
const {cells, burgs} = pack;
|
||||
|
||||
const SHARP_ANGLE = 135;
|
||||
const VERY_SHARP_ANGLE = 115;
|
||||
|
||||
const points = adjustBurgPoints(); // mutable array of points
|
||||
const routePaths = {};
|
||||
|
||||
|
|
@ -1651,27 +1647,12 @@ function drawRoutes() {
|
|||
searoutes: d3.curveCatmullRom.alpha(0.5),
|
||||
default: d3.curveCatmullRom.alpha(0.1)
|
||||
};
|
||||
const SHARP_ANGLE = 135;
|
||||
const VERY_SHARP_ANGLE = 115;
|
||||
|
||||
for (const {i, group, cells} of pack.routes) {
|
||||
// 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 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;
|
||||
}
|
||||
if (group !== "searoutes") straightenPathAngles(cells); // mutates points
|
||||
const pathPoints = cells.map(cellId => points[cellId]);
|
||||
|
||||
lineGen.curve(curves[group] || curves.default);
|
||||
const path = round(lineGen(pathPoints), 1);
|
||||
|
|
@ -1685,8 +1666,6 @@ function drawRoutes() {
|
|||
routes.select("#" + group).html(routePaths[group].join(""));
|
||||
}
|
||||
|
||||
drawCellsValue(pack.cells.i);
|
||||
|
||||
TIME && console.timeEnd("drawRoutes");
|
||||
|
||||
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() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue