@davepagurek/flo-mat
Version:
Medial / Scale Axis Transform (MAT/SAT) Library.
70 lines (57 loc) • 1.89 kB
text/typescript
import { BezierPiece } from '../mat/bezier-piece.js';
import { getPotentialClosestPointsOnCurveCertified } from './get-potential-closest-points-on-curve-certified.js';
import { cullBezierPieces1 } from './cull-bezier-pieces.js';
import { Curve } from '../curve/curve.js';
import { FootAndEndpointInfo } from './foot-and-endpoint-info.js';
import { PointOnShape } from '../point-on-shape/point-on-shape.js';
import { createPos } from '../point-on-shape/create-pos.js';
/**
* @internal
* Returns the closest boundary point to the given point, limited to the given
* bezier pieces, including the beziers actually checked after culling.
* @param bezierPieces
* @param x
* @param touchedCurve
* @param t
* @param extreme
*/
function getCloseBoundaryPointsCertified(
bezierPieces: BezierPiece[],
x: number[],
touchedCurve: Curve | undefined = undefined,
t: number | undefined = undefined,
for1Prong = false,
angle = 0): PointOnShape[] {
bezierPieces = cullBezierPieces1(bezierPieces, x);
const pInfoss: FootAndEndpointInfo[] = [];
for (let i=0; i<bezierPieces.length; i++) {
const bezierPiece = bezierPieces[i];
const pInfos = getPotentialClosestPointsOnCurveCertified(
bezierPiece.curve,
x,
bezierPiece.ts,
touchedCurve,
t,
for1Prong,
angle
);
pInfoss.push(...pInfos);
}
/** the minimum max interval value */
let minMax = Number.POSITIVE_INFINITY;
for (let i=0; i<pInfoss.length; i++) {
const diMax = pInfoss[i].dSquaredI[1];
if (diMax < minMax) {
minMax = diMax;
}
}
const closestPointInfos: FootAndEndpointInfo[] = [];
for (let i=0; i<pInfoss.length; i++) {
const info = pInfoss[i];
if (info.dSquaredI[0] <= minMax) {
closestPointInfos.push(info);
}
}
return closestPointInfos.map(info => createPos(info.curve, info.t, false));
}
export { getCloseBoundaryPointsCertified };