mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 17:51:24 +01:00
feat: alternative point samplers WIP
This commit is contained in:
parent
df4d80bb86
commit
62fa8d517b
7 changed files with 200 additions and 79 deletions
101
modules/points-generator.js
Normal file
101
modules/points-generator.js
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
"use strict";
|
||||
|
||||
const pointsGenerators = {
|
||||
jittered: generateJitteredPoints,
|
||||
hexFlat: generateHexFlatPoints,
|
||||
hexPointy: generateHexPointyPoints,
|
||||
square: generateSquarePoints
|
||||
};
|
||||
|
||||
function generatePoints() {
|
||||
TIME && console.time("placePoints");
|
||||
const cellsDesired = +byId("pointsInput").dataset.cells;
|
||||
const spacing = Math.sqrt((graphWidth * graphHeight) / cellsDesired); // spacing between points
|
||||
const boundary = getBoundaryPoints(graphWidth, graphHeight, spacing);
|
||||
|
||||
const type = byId("gridType").value;
|
||||
const {points, cellsX, cellsY} = pointsGenerators[type](graphWidth, graphHeight, spacing);
|
||||
TIME && console.timeEnd("placePoints");
|
||||
|
||||
return {spacing, cellsDesired, type, boundary, points, cellsX, cellsY};
|
||||
}
|
||||
|
||||
function generateJitteredPoints(width, height, spacing) {
|
||||
return generateSquareJitteredPoints(0.9, width, height, spacing);
|
||||
}
|
||||
|
||||
function generateSquarePoints(width, height, spacing) {
|
||||
return generateSquareJitteredPoints(0, width, height, spacing);
|
||||
}
|
||||
|
||||
function generateSquareJitteredPoints(jittering, width, height, spacing) {
|
||||
const radius = spacing / 2;
|
||||
const maxDeviation = radius * jittering;
|
||||
const jitter = () => (jittering ? Math.random() * maxDeviation * 2 - maxDeviation : 0);
|
||||
|
||||
let points = [];
|
||||
for (let y = radius; y < height; y += spacing) {
|
||||
for (let x = radius; x < width; x += spacing) {
|
||||
const xj = Math.min(rn(x + jitter(), 2), width);
|
||||
const yj = Math.min(rn(y + jitter(), 2), height);
|
||||
points.push([xj, yj]);
|
||||
}
|
||||
}
|
||||
|
||||
const cellsX = Math.floor((width + 0.5 * spacing - 1e-10) / spacing);
|
||||
const cellsY = Math.floor((height + 0.5 * spacing - 1e-10) / spacing);
|
||||
return {points, cellsX, cellsY};
|
||||
}
|
||||
|
||||
function generateHexFlatPoints(width, height, spacing) {
|
||||
return generateHexPoints(false, width, height, spacing);
|
||||
}
|
||||
|
||||
function generateHexPointyPoints(width, height, spacing) {
|
||||
return generateHexPoints(true, width, height, spacing);
|
||||
}
|
||||
|
||||
function generateHexPoints(isPointy, width, height, spacing) {
|
||||
const hexRatio = Math.sqrt(3) / 2;
|
||||
const spacingX = isPointy ? spacing / hexRatio : spacing * 2;
|
||||
const spacingY = isPointy ? spacing : spacing / hexRatio / 2;
|
||||
const maxWidth = width + spacingX / 2;
|
||||
const maxHeight = height + spacingY / 2;
|
||||
const indentionX = spacingX / 2;
|
||||
|
||||
let points = [];
|
||||
for (let y = 0, row = 0; y < maxHeight; y += spacingY, row++) {
|
||||
for (let x = row % 2 ? 0 : indentionX; x < maxWidth; x += spacingX) {
|
||||
if (x > width) x = width;
|
||||
if (y > height) y = height;
|
||||
points.push([rn(x, 2), rn(y, 2)]);
|
||||
}
|
||||
}
|
||||
|
||||
const cellsX = Math.ceil(width / spacingX);
|
||||
const cellsY = Math.ceil(height / spacingY);
|
||||
return {points, cellsX, cellsY};
|
||||
}
|
||||
|
||||
// add points along map edge to pseudo-clip voronoi cells
|
||||
function getBoundaryPoints(width, height, spacing) {
|
||||
const offset = rn(-1 * spacing);
|
||||
const bSpacing = spacing * 2;
|
||||
const w = width - offset * 2;
|
||||
const h = height - offset * 2;
|
||||
const numberX = Math.ceil(w / bSpacing) - 1;
|
||||
const numberY = Math.ceil(h / bSpacing) - 1;
|
||||
const points = [];
|
||||
|
||||
for (let i = 0.5; i < numberX; i++) {
|
||||
let x = Math.ceil((w * i) / numberX + offset);
|
||||
points.push([x, offset], [x, h + offset]);
|
||||
}
|
||||
|
||||
for (let i = 0.5; i < numberY; i++) {
|
||||
let y = Math.ceil((h * i) / numberY + offset);
|
||||
points.push([offset, y], [w + offset, y]);
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue