UNPKG

@thi.ng/geom

Version:

Functional, polymorphic API for 2D geometry types & SVG generation

104 lines (103 loc) 3.71 kB
import { defmulti } from "@thi.ng/defmulti/defmulti"; import { bounds as arcBounds } from "@thi.ng/geom-arc/bounds"; import { bounds2, bounds3 } from "@thi.ng/geom-poly-utils/bounds"; import { cubicBounds } from "@thi.ng/geom-splines/cubic-bounds"; import { quadraticBounds } from "@thi.ng/geom-splines/quadratic-bounds"; import { comp } from "@thi.ng/transducers/comp"; import { filter } from "@thi.ng/transducers/filter"; import { iterator1 } from "@thi.ng/transducers/iterator"; import { map } from "@thi.ng/transducers/map"; import { mapcat } from "@thi.ng/transducers/mapcat"; import { addN2 } from "@thi.ng/vectors/addn"; import { max2 } from "@thi.ng/vectors/max"; import { min2 } from "@thi.ng/vectors/min"; import { mul2 } from "@thi.ng/vectors/mul"; import { mulN2 } from "@thi.ng/vectors/muln"; import { sub2 } from "@thi.ng/vectors/sub"; import { subN2 } from "@thi.ng/vectors/subn"; import { aabbFromMinMaxWithMargin } from "./aabb.js"; import { Rect } from "./api/rect.js"; import { __collBounds } from "./internal/bounds.js"; import { __dispatch } from "./internal/dispatch.js"; import { rectFromMinMaxWithMargin } from "./rect.js"; const bounds = defmulti( __dispatch, { aabb: "rect", bpatch: "points", poly: "points", polyline: "points", quad: "points", tri: "points" }, { arc: ($, margin = 0) => rectFromMinMaxWithMargin( ...arcBounds($.pos, $.r, $.axis, $.start, $.end), margin ), bpatch: ({ points }, margin = 0) => rectFromMinMaxWithMargin( ...bounds2([ ...mapcat( (pts) => cubicBounds(...pts), [ [points[0], points[1], points[2], points[3]], [points[3], points[7], points[11], points[15]], [points[12], points[13], points[14], points[15]], [points[0], points[4], points[8], points[12]] ] ) ]), margin ), circle: ($, margin = 0) => new Rect( subN2([], $.pos, $.r + margin), mulN2(null, [2, 2], $.r + margin) ), complexpoly: ($, margin = 0) => { const res = __collBounds([$.boundary, ...$.children], bounds); return res ? new Rect(...res).offset(margin) : void 0; }, cubic: ({ points }, margin = 0) => rectFromMinMaxWithMargin( ...cubicBounds(points[0], points[1], points[2], points[3]), margin ), ellipse: ($, margin = 0) => { const r = addN2([], $.r, margin); return new Rect(sub2([], $.pos, r), mul2(null, [2, 2], r)); }, extra: () => void 0, group: ($, margin = 0) => { const res = __collBounds($.children, bounds); return res ? new Rect(...res).offset(margin) : void 0; }, line: ({ points: [a, b] }, margin = 0) => rectFromMinMaxWithMargin(min2([], a, b), max2([], a, b), margin), path: (path, margin = 0) => { const $segmentGeo = (segments) => iterator1( comp( map((s) => s.geo), filter((s) => !!s) ), segments ); const b = __collBounds( [ ...$segmentGeo(path.segments), ...mapcat($segmentGeo, path.subPaths) ], bounds ); return b ? new Rect(...b).offset(margin) : void 0; }, points: ($, margin = 0) => rectFromMinMaxWithMargin(...bounds2($.points), margin), points3: ($, margin = 0) => aabbFromMinMaxWithMargin(...bounds3($.points), margin), quadratic: ({ points }, margin = 0) => rectFromMinMaxWithMargin( ...quadraticBounds(points[0], points[1], points[2]), margin ), rect: ($, margin = 0) => margin === 0 ? $.copy() : $.copy().offset(margin), text: ($, margin = 0) => new Rect(subN2([], $.pos, margin), margin * 2) } ); export { bounds };