UNPKG

@rickosborne/hexgrid

Version:

Rick Osborne's collection of hexagonal grid-related code.

81 lines (80 loc) 3.35 kB
var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); import { BetterMap } from "@rickosborne/foundation"; const hexContainsChecker = /* @__PURE__ */ __name((corners) => { const { maxX, maxY, minX, minY, xs } = corners.slice(1).reduce((p, { x: rx, y: ry }) => { if (rx < p.minX) p.minX = rx; if (rx > p.maxX) p.maxX = rx; if (ry < p.minY) p.minY = ry; if (ry > p.maxY) p.maxY = ry; p.xs.upsert(rx, (e) => rx + (e ?? 0)); return p; }, { minX: corners[0].x, maxX: corners[0].x, minY: corners[0].y, maxY: corners[0].y, xs: BetterMap.empty() }); const isFlat = xs.get(minX) === 1; let rectMinX = isFlat ? Infinity : minX; let rectMaxX = isFlat ? -Infinity : maxX; let rectMinY = isFlat ? minY : Infinity; let rectMaxY = isFlat ? maxY : -Infinity; const triangleCheckers = []; for (const corner of corners) { const { x: cx, y: cy } = corner; if (isFlat && (cy === minY || cy === maxY)) { if (cx < rectMinX) rectMinX = cx; if (cx > rectMaxX) rectMaxX = cx; } else if (!isFlat && (cx === minX || cx === maxX)) { if (cy < rectMinY) rectMinY = cy; if (cy > rectMaxY) rectMaxY = cy; } else if (cx < rectMinX) { triangleCheckers.push(triangleContainsChecker([corner, { x: rectMinX, y: maxY }, { x: rectMinX, y: minY }])); } else if (cx > rectMaxX) { triangleCheckers.push(triangleContainsChecker([corner, { x: rectMaxX, y: maxY }, { x: rectMaxX, y: minY }])); } else if (cy < rectMinY) { triangleCheckers.push(triangleContainsChecker([corner, { x: rectMinX, y: rectMinY }, { x: rectMaxX, y: rectMinY }])); } else if (cy > rectMaxY) { triangleCheckers.push(triangleContainsChecker([corner, { x: rectMinX, y: rectMaxY }, { x: rectMaxX, y: rectMaxY }])); } else { throw new Error("Odd hex corners?"); } } return (xy) => { const { x, y } = xy; if (x < minX || x > maxX || y < minY || y > maxY) { return false; } if (x >= rectMinX && x <= rectMaxX && y >= rectMinY && y <= rectMaxY) { return true; } return triangleCheckers.some((checkTriangle) => checkTriangle(xy)); }; }, "hexContainsChecker"); const hexCornersContainPoint = /* @__PURE__ */ __name((corners, xy) => { return hexContainsChecker(corners)(xy); }, "hexCornersContainPoint"); const triangleContainsChecker = /* @__PURE__ */ __name((triangle) => { const [{ x: x1, y: y1 }, { x: x2, y: y2 }, { x: x3, y: y3 }] = triangle; const x1x3 = x1 - x3; const x3x2 = x3 - x2; const y2y3 = y2 - y3; const y3y1 = y3 - y1; const d = y2y3 * x1x3 + x3x2 * (y1 - y3); const y2y3d = y2y3 / d; const x3x2d = x3x2 / d; const y3y1d = y3y1 / d; const x1x3d = x1x3 / d; return ({ x: px, y: py }) => { const a = y2y3d * (px - x3) + x3x2d * (py - y3); const b = y3y1d * (px - x3) + x1x3d * (py - y3); const c = 1 - a - b; return a >= 0 && a <= 1 && b >= 0 && b <= 1 && c >= 0 && c <= 1; }; }, "triangleContainsChecker"); const triangleContainsPoint = /* @__PURE__ */ __name((triangle, point) => { return triangleContainsChecker(triangle)(point); }, "triangleContainsPoint"); export { hexContainsChecker, hexCornersContainPoint, triangleContainsChecker, triangleContainsPoint }; //# sourceMappingURL=hex-contains-point.mjs.map