@thi.ng/geom
Version:
Functional, polymorphic API for 2D geometry types & SVG generation
92 lines (91 loc) • 2.55 kB
JavaScript
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
};