import { range, max } from "d3-array";
const d3 = Object.assign({}, { range, max });
/**
* @function grid/triangle
* @description The `grid.triangle` function allows to create a triangle geoJSON grid in SVG coordinates.
* @see {@link https://observablehq.com/@neocartocnrs/regular-grids}
* @property {number} [step = 50] - step of the grid
* @property {number} [width = 1000] - width of the grid
* @property {number} [height = 500] - height of the grid
* @example
* geoviz.grid.triangle({step: 30})
*/
export function triangle({ step = 50, width = 1000, height = 500 } = {}) {
let triangletop = (p, size) => {
let h = (Math.sqrt(3) / 2) * size;
let p1 = [p[0] + size / 2, p[1]];
let p2 = [p[0], p[1] - h];
let p3 = [p[0] - size / 2, p[1]];
return [p1, p2, p3, p1];
};
let trianglebottom = (p, size) => {
let h = (Math.sqrt(3) / 2) * size;
let p1 = [p[0] + size / 2, p[1]];
let p2 = [p[0], p[1] + h];
let p3 = [p[0] - size / 2, p[1]];
return [p1, p2, p3, p1];
};
let size = step / Math.sqrt(3);
let h = (Math.sqrt(3) / 2) * step;
// build grid
let y = d3.range(0, height + size, h).reverse();
if (y.length % 2) {
y.unshift(d3.max(y) + h);
}
let x = d3.range(0, width + size, step);
let grid = x.map((x, i) => y.map((y) => [x, y])).flat();
grid = grid.map((d, i) => {
return i % 2 == 1 ? [d[0] + step / 2, d[1]] : d;
});
let nb = grid.length;
grid = grid.concat(grid);
// build object
let result = grid.map((d, i) => {
return {
type: "Feature",
geometry: {
type: "Polygon",
coordinates:
i < nb ? [triangletop(d, step)] : [trianglebottom(d, step)],
},
properties: {
index: i,
},
};
});
return {
type: "FeatureCollection",
grid: "triangle",
coords: "svg",
features: result,
};
}