UNPKG

@thi.ng/geom

Version:

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

92 lines (91 loc) 2.55 kB
import { minNonZero2, minNonZero3 } from "@thi.ng/math/interval"; import { safeDiv } from "@thi.ng/math/safe-div"; import { concat } from "@thi.ng/matrices/concat"; import { scale23, scale44 } from "@thi.ng/matrices/scale"; import { translation23, translation44 } from "@thi.ng/matrices/translation"; import { mulN2, mulN3 } from "@thi.ng/vectors/muln"; import { Rect } from "./api/rect.js"; import { bounds } from "./bounds.js"; import { center } from "./center.js"; import { centroid } from "./centroid.js"; import { __collBounds } from "./internal/bounds.js"; import { mapPoint } from "./map-point.js"; import { transform } from "./transform.js"; import { unmapPoint } from "./unmap-point.js"; const __translateScale = (tmat, smat, shape, preTrans, postTrans, scale) => transform( shape, concat([], tmat([], postTrans), smat([], scale), tmat([], preTrans)) ); function fitIntoBounds2(shape, dest) { const src = bounds(shape); if (!src) return; const c = centroid(src); if (!c) return; return __translateScale( translation23, scale23, shape, mulN2(null, c, -1), centroid(dest), minNonZero2( safeDiv(dest.size[0], src.size[0]), safeDiv(dest.size[1], src.size[1]) ) ); } const fitIntoBounds3 = (shape, dest) => { const src = bounds(shape); if (!src) return; const c = centroid(src); if (!c) return; return __translateScale( translation44, scale44, shape, mulN3(null, c, -1), centroid(dest), minNonZero3( safeDiv(dest.size[0], src.size[0]), safeDiv(dest.size[1], src.size[1]), safeDiv(dest.size[2], src.size[2]) ) ); }; const fitAllIntoBounds2 = (shapes, dest) => { const sbraw = __collBounds(shapes, bounds); if (!sbraw) return; const src = new Rect(...sbraw); const sx = safeDiv(dest.size[0], src.size[0]); const sy = safeDiv(dest.size[1], src.size[1]); const scale = sx > 0 ? sy > 0 ? Math.min(sx, sy) : sx : sy; const smat = scale23([], scale); const b = center(transform(src, smat), centroid(dest)); const c1 = []; const c2 = []; const res = []; for (let i = shapes.length; i-- > 0; ) { const s = shapes[i]; const sc = centroid(s, c1); if (sc) { unmapPoint(b, mapPoint(src, sc), c2); res.push( __translateScale( translation23, scale23, s, mulN2(null, c1, -1), c2, smat ) ); } else { res.push(s); } } return res; }; export { fitAllIntoBounds2, fitIntoBounds2, fitIntoBounds3 };