@thi.ng/poisson
Version:
nD Stratified grid and Poisson-disc sampling w/ support for spatial density functions and custom PRNGs
63 lines (62 loc) • 2.26 kB
JavaScript
import { isNumber } from "@thi.ng/checks/is-number";
import { SYSTEM } from "@thi.ng/random/system";
import { add2, add3 } from "@thi.ng/vectors/add";
import { distSq2, distSq3 } from "@thi.ng/vectors/distsq";
import { mul2, mul3 } from "@thi.ng/vectors/mul";
import { random2, random3 } from "@thi.ng/vectors/random";
function* stratifiedGrid2(opts) {
let { rnd = SYSTEM, separation: sep = Math.SQRT1_2 } = opts;
sep *= sep;
const scale = opts.scale !== void 0 ? isNumber(opts.scale) ? [opts.scale, opts.scale] : opts.scale : void 0;
const [sx, sy] = opts.dim;
const sx1 = sx - 1;
const tmp = [0, 0];
let prevY = [];
let currY = [];
let q;
for (let y = 0; y < sy; y++) {
for (let x = 0; x < sx; x++) {
do {
q = add2(null, [x, y], random2(tmp, 0, 1, rnd));
} while (x > 0 && distSq2(currY[x - 1], q) < sep || y > 0 && (distSq2(prevY[x], q) < sep || x > 0 && distSq2(prevY[x - 1], q) < sep || x < sx1 && distSq2(prevY[x + 1], q) < sep));
currY.push(q);
yield scale ? mul2([], q, scale) : q;
}
prevY = currY;
currY = [];
}
}
function* stratifiedGrid3(opts) {
let { rnd = SYSTEM, separation: sep = Math.SQRT1_2 } = opts;
sep *= sep;
const scale = opts.scale !== void 0 ? isNumber(opts.scale) ? [opts.scale, opts.scale] : opts.scale : void 0;
const [sx, sy, sz] = opts.dim;
const sx1 = sx - 1;
const tmp = [0, 0, 0];
let prevY = [];
let prevZ = [];
let currY = [];
let currZ = [];
let q;
for (let z = 0; z < sz; z++) {
for (let y = 0; y < sy; y++) {
for (let x = 0; x < sx; x++) {
do {
q = add3(null, [x, y, z], random3(tmp, 0, 1, rnd));
} while (x > 0 && distSq3(currY[x - 1], q) < sep || y > 0 && __inRange3(q, prevY, x, sx1, sep) || z > 0 && (__inRange3(q, prevZ[y], x, sx1, sep) || y > 0 && __inRange3(q, prevZ[y - 1], x, sx1, sep)));
currY.push(q);
yield scale ? mul3([], q, scale) : q;
}
currZ.push(currY);
prevY = currY;
currY = [];
}
prevZ = currZ;
currZ = [];
}
}
const __inRange3 = (q, prev, x, maxX, sep) => distSq3(prev[x], q) < sep || x > 0 && distSq3(prev[x - 1], q) < sep || x < maxX && distSq3(prev[x + 1], q) < sep;
export {
stratifiedGrid2,
stratifiedGrid3
};