From e427050369cb654251829bc01103d9a48bcdb071 Mon Sep 17 00:00:00 2001 From: max Date: Sun, 21 Aug 2022 00:02:32 +0300 Subject: [PATCH] refactor: roads generation - reduce curves on routes rendering --- src/layers/renderers/drawRoutes.ts | 77 ++++++++++++------- src/modules/markers-generator.js | 8 +- src/scripts/generation/grid/lakes.ts | 4 +- src/scripts/generation/pack/generateRoutes.ts | 5 -- src/utils/debugUtils.ts | 11 +++ 5 files changed, 68 insertions(+), 37 deletions(-) diff --git a/src/layers/renderers/drawRoutes.ts b/src/layers/renderers/drawRoutes.ts index f9672af9..d7308bea 100644 --- a/src/layers/renderers/drawRoutes.ts +++ b/src/layers/renderers/drawRoutes.ts @@ -1,5 +1,4 @@ import * as d3 from "d3"; -import {drawPoint} from "utils/debugUtils"; import {round} from "utils/stringUtils"; @@ -9,35 +8,16 @@ export function drawRoutes() { const {cells, burgs} = pack; const lineGen = d3.line().curve(d3.curveCatmullRom.alpha(0.1)); - const getBurgCoords = (burgId: number): TPoint => { - if (!burgId) throw new Error("burgId must be positive"); - const burg = burgs[burgId] as IBurg; - return [burg.x, burg.y]; - }; - - const getPathPoints = (cellIds: number[]): TPoints => - cellIds.map(cellId => { - const burgId = cells.burg[cellId]; - if (burgId) return getBurgCoords(burgId); - - return cells.p[cellId]; - }); - - const normalizePoints = (points: TPoints): TPoints => - points.map(([x, y], index) => { - return [x, y]; - - if (i === 17) { - cells.forEach(cellId => drawPoint(pack.cells.p[cellId])); - } - }); + const SHARP_ANGLE = 135; + const VERY_SHARP_ANGLE = 115; + const points = adjustBurgPoints(); // mutable array of points const routePaths: Dict = {}; for (const {i, type, cells} of pack.routes) { - const points = getPathPoints(cells); - const normalizedPoints = normalizePoints(points); - const path = round(lineGen(normalizedPoints)!, 1); + straightenPathAngles(cells); // mutates points + const pathPoints = cells.map(cellId => points[cellId]); + const path = round(lineGen(pathPoints)!, 1); if (!routePaths[type]) routePaths[type] = []; routePaths[type].push(``); @@ -46,4 +26,49 @@ export function drawRoutes() { for (const type in routePaths) { routes.select(`[data-type=${type}]`).html(routePaths[type].join("")); } + + function adjustBurgPoints() { + const points = Array.from(cells.p); + + for (const burg of burgs) { + if (burg.i === 0) continue; + const {cell, x, y} = burg as IBurg; + points[cell] = [x, y]; + } + + return points; + } + + function straightenPathAngles(cellIds: number[]) { + for (let i = 1; i < cellIds.length - 1; i++) { + const cellId = cellIds[i]; + if (cells.burg[cellId]) continue; + + const prev = points[cellIds[i - 1]]; + const that = points[cellId]; + const next = points[cellIds[i + 1]]; + + const dAx = prev[0] - that[0]; + const dAy = prev[1] - that[1]; + const dBx = next[0] - that[0]; + const dBy = next[1] - that[1]; + const angle = (Math.atan2(dAx * dBy - dAy * dBx, dAx * dBx + dAy * dBy) * 180) / Math.PI; + + if (Math.abs(angle) < SHARP_ANGLE) { + const middleX = (prev[0] + next[0]) / 2; + const middleY = (prev[1] + next[1]) / 2; + + if (Math.abs(angle) < VERY_SHARP_ANGLE) { + const newX = (that[0] + middleX * 2) / 3; + const newY = (that[1] + middleY * 2) / 3; + points[cellId] = [newX, newY]; + continue; + } + + const newX = (that[0] + middleX) / 2; + const newY = (that[1] + middleY) / 2; + points[cellId] = [newX, newY]; + } + } + } } diff --git a/src/modules/markers-generator.js b/src/modules/markers-generator.js index b02db878..bcd12577 100644 --- a/src/modules/markers-generator.js +++ b/src/modules/markers-generator.js @@ -1,8 +1,7 @@ import * as d3 from "d3"; -import {TIME} from "config/logging"; +import {TIME, DEBUG} from "config/logging"; import {last} from "utils/arrayUtils"; -import {rn} from "utils/numberUtils"; import {rand, P, gauss, ra, rw} from "utils/probabilityUtils"; import {capitalize} from "utils/stringUtils"; import {convertTemperature, getFriendlyHeight, getBurgPopulation} from "utils/unitUtils"; @@ -112,8 +111,9 @@ window.Markers = (function () { let candidates = Array.from(list(pack)); let quantity = getQuantity(candidates, min, each, multiplier); - // uncomment for debugging: - // console.log(`${icon} ${type}: each ${each} of ${candidates.length}, min ${min} candidates. Got ${quantity}`); + + DEBUG && + console.info(`${icon} ${type}: each ${each} of ${candidates.length}, min ${min} candidates. Got ${quantity}`); while (quantity && candidates.length) { const [cell] = extractAnyElement(candidates); diff --git a/src/scripts/generation/grid/lakes.ts b/src/scripts/generation/grid/lakes.ts index eb548e4f..094ff1b2 100644 --- a/src/scripts/generation/grid/lakes.ts +++ b/src/scripts/generation/grid/lakes.ts @@ -1,4 +1,4 @@ -import {TIME} from "config/logging"; +import {INFO, TIME} from "config/logging"; import {getInputNumber} from "utils/nodeUtils"; import {MAX_HEIGHT, MIN_LAND_HEIGHT} from "config/generation"; @@ -46,7 +46,7 @@ export function addLakesInDeepDepressions(heights: Uint8Array, neighbours: numbe if (inDeepDepression) { currentHeights[cellId] = MIN_LAND_HEIGHT - 1; - console.log(`ⓘ Added lake at deep depression. Cell: ${cellId}`); + INFO && console.info(`ⓘ Added lake at deep depression. Cell: ${cellId}`); } } diff --git a/src/scripts/generation/pack/generateRoutes.ts b/src/scripts/generation/pack/generateRoutes.ts index c10dcc72..81096299 100644 --- a/src/scripts/generation/pack/generateRoutes.ts +++ b/src/scripts/generation/pack/generateRoutes.ts @@ -4,7 +4,6 @@ import FlatQueue from "flatqueue"; import {TIME} from "config/logging"; import {ELEVATION, MIN_LAND_HEIGHT, ROUTES} from "config/generation"; import {dist2} from "utils/functionUtils"; -import {drawLine} from "utils/debugUtils"; export function generateRoutes( burgs: TBurgs, @@ -37,8 +36,6 @@ export function generateRoutes( const points: TPoints = featureCapitals.map(burg => [burg.x, burg.y]); const urquhartEdges = calculateUrquhartEdges(points); urquhartEdges.forEach(([fromId, toId]) => { - drawLine(points[fromId], points[toId], {stroke: "red", strokeWidth: 0.01}); - const start = featureCapitals[fromId].cell; const exit = featureCapitals[toId].cell; @@ -70,8 +67,6 @@ export function generateRoutes( const points: TPoints = featureBurgs.map(burg => [burg.x, burg.y]); const urquhartEdges = calculateUrquhartEdges(points); urquhartEdges.forEach(([fromId, toId]) => { - drawLine(points[fromId], points[toId], {strokeWidth: 0.01}); - const start = featureBurgs[fromId].cell; const exit = featureBurgs[toId].cell; diff --git a/src/utils/debugUtils.ts b/src/utils/debugUtils.ts index 727db4ed..20a3113c 100644 --- a/src/utils/debugUtils.ts +++ b/src/utils/debugUtils.ts @@ -44,3 +44,14 @@ export function drawArrow([x1, y1]: TPoint, [x2, y2]: TPoint, {width = 1, color .attr("stroke", color) .attr("stroke-width", width / 2); } + +export function drawText(text: string | number, [x, y]: TPoint, {size = 6, color = "black"} = {}) { + debug + .append("text") + .attr("x", x) + .attr("y", y) + .attr("font-size", size) + .attr("fill", color) + .attr("stroke", "none") + .text(text); +}