mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-18 02:01:22 +01:00
chore: unify drawFillWithGap
This commit is contained in:
parent
6b3df6c4d8
commit
39516ce782
3 changed files with 17 additions and 101 deletions
|
|
@ -212,11 +212,6 @@ t,
|
|||
mask: url(#land);
|
||||
}
|
||||
|
||||
#statesBody,
|
||||
#provincesBody {
|
||||
stroke-width: 3;
|
||||
}
|
||||
|
||||
#borders {
|
||||
stroke-linejoin: round;
|
||||
fill: none;
|
||||
|
|
|
|||
|
|
@ -878,96 +878,17 @@ function toggleReligions(event) {
|
|||
function drawReligions() {
|
||||
TIME && console.time("drawReligions");
|
||||
|
||||
relig.selectAll("path").remove();
|
||||
const {cells, vertices, religions} = pack;
|
||||
const n = cells.i.length;
|
||||
const {cells, religions} = pack;
|
||||
|
||||
const used = new Uint8Array(cells.i.length);
|
||||
const vArray = new Array(religions.length); // store vertices array
|
||||
const body = new Array(religions.length).fill(""); // store path around each religion
|
||||
const gap = new Array(religions.length).fill(""); // store path along water for each religion to fill the gaps
|
||||
|
||||
for (const i of cells.i) {
|
||||
if (!cells.religion[i]) continue;
|
||||
if (used[i]) continue;
|
||||
used[i] = 1;
|
||||
const r = cells.religion[i];
|
||||
const onborder = cells.c[i].filter(n => cells.religion[n] !== r);
|
||||
if (!onborder.length) continue;
|
||||
const borderWith = cells.c[i].map(c => cells.religion[c]).find(n => n !== r);
|
||||
const vertex = cells.v[i].find(v => vertices.c[v].some(i => cells.religion[i] === borderWith));
|
||||
const chain = connectVertices(vertex, r, borderWith);
|
||||
if (chain.length < 3) continue;
|
||||
const points = chain.map(v => vertices.p[v[0]]);
|
||||
if (!vArray[r]) vArray[r] = [];
|
||||
vArray[r].push(points);
|
||||
body[r] += "M" + points.join("L") + "Z";
|
||||
gap[r] +=
|
||||
"M" +
|
||||
vertices.p[chain[0][0]] +
|
||||
chain.reduce(
|
||||
(r2, v, i, d) =>
|
||||
!i ? r2 : !v[2] ? r2 + "L" + vertices.p[v[0]] : d[i + 1] && !d[i + 1][2] ? r2 + "M" + vertices.p[v[0]] : r2,
|
||||
""
|
||||
);
|
||||
const bodyPaths = new Array(religions.length - 1);
|
||||
const isolines = getIsolines(cellId => cells.religion[cellId], {fill: true, waterGap: true});
|
||||
for (const [index, {fill, waterGap}] of isolines) {
|
||||
const color = religions[index].color;
|
||||
bodyPaths.push(drawFillWithGap("religion", fill, waterGap, color, index));
|
||||
}
|
||||
|
||||
const bodyData = body.map((p, i) => [p.length > 10 ? p : null, i, religions[i].color]).filter(d => d[0]);
|
||||
relig
|
||||
.selectAll("path")
|
||||
.data(bodyData)
|
||||
.enter()
|
||||
.append("path")
|
||||
.attr("d", d => d[0])
|
||||
.attr("fill", d => d[2])
|
||||
.attr("id", d => "religion" + d[1]);
|
||||
const gapData = gap.map((p, i) => [p.length > 10 ? p : null, i, religions[i].color]).filter(d => d[0]);
|
||||
relig
|
||||
.selectAll(".path")
|
||||
.data(gapData)
|
||||
.enter()
|
||||
.append("path")
|
||||
.attr("d", d => d[0])
|
||||
.attr("fill", "none")
|
||||
.attr("stroke", d => d[2])
|
||||
.attr("id", d => "religion-gap" + d[1])
|
||||
.attr("stroke-width", "10px");
|
||||
byId("relig").innerHTML = bodyPaths.join("");
|
||||
|
||||
// connect vertices to chain
|
||||
function connectVertices(start, t, religion) {
|
||||
const chain = []; // vertices chain to form a path
|
||||
let land = vertices.c[start].some(c => cells.h[c] >= 20 && cells.religion[c] !== t);
|
||||
function check(i) {
|
||||
religion = cells.religion[i];
|
||||
land = cells.h[i] >= 20;
|
||||
}
|
||||
|
||||
for (let i = 0, current = start; i === 0 || (current !== start && i < 20000); i++) {
|
||||
const prev = chain[chain.length - 1] ? chain[chain.length - 1][0] : -1; // previous vertex in chain
|
||||
chain.push([current, religion, land]); // add current vertex to sequence
|
||||
const c = vertices.c[current]; // cells adjacent to vertex
|
||||
c.filter(c => cells.religion[c] === t).forEach(c => (used[c] = 1));
|
||||
const c0 = c[0] >= n || cells.religion[c[0]] !== t;
|
||||
const c1 = c[1] >= n || cells.religion[c[1]] !== t;
|
||||
const c2 = c[2] >= n || cells.religion[c[2]] !== t;
|
||||
const v = vertices.v[current]; // neighboring vertices
|
||||
if (v[0] !== prev && c0 !== c1) {
|
||||
current = v[0];
|
||||
check(c0 ? c[0] : c[1]);
|
||||
} else if (v[1] !== prev && c1 !== c2) {
|
||||
current = v[1];
|
||||
check(c1 ? c[1] : c[2]);
|
||||
} else if (v[2] !== prev && c0 !== c2) {
|
||||
current = v[2];
|
||||
check(c2 ? c[2] : c[0]);
|
||||
}
|
||||
if (current === chain[chain.length - 1][0]) {
|
||||
ERROR && console.error("Next vertex is not found");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return chain;
|
||||
}
|
||||
TIME && console.timeEnd("drawReligions");
|
||||
}
|
||||
|
||||
|
|
@ -1000,11 +921,7 @@ function drawStates() {
|
|||
const isolines = getIsolines(cellId => cells.state[cellId], {fill: true, waterGap: true, halo: renderHalo});
|
||||
for (const [index, {fill, waterGap, halo}] of isolines) {
|
||||
const color = states[index].color;
|
||||
|
||||
bodyPaths.push(
|
||||
/* html */ `<path d="${waterGap}" fill="none" stroke="${color}" id="state-gap${index}" />`,
|
||||
/* html */ `<path d="${fill}" fill="${color}" stroke="none" id="state${index}" />`
|
||||
);
|
||||
bodyPaths.push(drawFillWithGap("state", fill, waterGap, color, index));
|
||||
|
||||
if (renderHalo) {
|
||||
const haloColor = d3.color(color)?.darker().hex() || "#666666";
|
||||
|
|
@ -1165,10 +1082,7 @@ function drawProvinces() {
|
|||
const isolines = getIsolines(cellId => cells.province[cellId], {fill: true, waterGap: true});
|
||||
for (const [index, {fill, waterGap}] of isolines) {
|
||||
const color = provinces[index].color;
|
||||
bodyPaths.push(
|
||||
/* html */ `<path d="${waterGap}" fill="none" stroke="${color}" id="province-gap${index}" />`,
|
||||
/* html */ `<path d="${fill}" fill="${color}" stroke="none" id="province${index}" />`
|
||||
);
|
||||
bodyPaths.push(drawFillWithGap("province", fill, waterGap, color, index));
|
||||
}
|
||||
|
||||
const labels = provinces
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ function getVertexPoint(vertexId) {
|
|||
function getFillPath(vertexChain) {
|
||||
const points = vertexChain.map(getVertexPoint);
|
||||
const firstPoint = points.shift();
|
||||
return `M${firstPoint} L${points.join(" ")}`;
|
||||
return `M${firstPoint} L${points.join(" ")} Z`;
|
||||
}
|
||||
|
||||
// get single path for an non-continuous array of cells
|
||||
|
|
@ -172,3 +172,10 @@ function connectVertices({startingVertex, ofSameType, addToChecked, closeRing})
|
|||
if (closeRing) chain.push(startingVertex);
|
||||
return chain;
|
||||
}
|
||||
|
||||
function drawFillWithGap(elementName, fill, waterGap, color, index) {
|
||||
return /* html */ `
|
||||
<path d="${fill}" fill="${color}" id="${elementName}${index}" />
|
||||
<path d="${waterGap}" fill="none" stroke="${color}" stroke-width="5" id="${elementName}-gap${index}" />
|
||||
`;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue