@davepagurek/flo-mat
Version:
Medial / Scale Axis Transform (MAT/SAT) Library.
91 lines (72 loc) • 2.7 kB
text/typescript
import { CpNode } from '../cp-node/cp-node.js';
import { Curve } from '../curve/curve.js';
import { BezierPiece } from './bezier-piece.js';
import { isPosQuiteSharpCorner } from '../point-on-shape/is-pos-quite-sharp-corner.js';
import { compareCps } from '../contact-point/contact-point.js';
/**
* @internal
* Returns the ordered cubic bezier pieces (i.e a bezier with a t range)
* from the given boundary piece.
* @param cpNodes - An ordered pair that represents the start and end points of
* the boundary piece
*/
function getBoundaryPieceBeziers(cpNodes: CpNode[]): BezierPiece[] {
let cpThis = cpNodes[0];
const cpEnd = cpNodes[1];
const bezierPieces: BezierPiece[] = [];
// As opposed to going around the circle and taking the last exit
let goStraight = true;
do {
if (!goStraight) {
goStraight = true;
cpThis = cpThis.prevOnCircle; // take last exit
continue;
}
goStraight = false;
const posThis = cpThis .cp.pointOnShape;
const posNext = cpThis.next.cp.pointOnShape;
if (posNext.curve === posThis.curve &&
//PointOnShape.isQuiteSharpCorner(posThis) &&
//PointOnShape.isQuiteSharpCorner(posNext)) {
isPosQuiteSharpCorner(posThis) &&
isPosQuiteSharpCorner(posNext)) {
// Do nothing
} else if (posNext.curve === posThis.curve &&
compareCps(cpThis.next.cp, cpThis.cp) > 0) {
bezierPieces.push(
{ curve: posThis.curve, ts: [posThis.t, posNext.t] }
);
} else {
bezierPieces.push(
{ curve: posThis.curve, ts: [posThis.t, 1] }
);
if (cpThis.cp.pointOnShape.curve.loop === cpThis.next.cp.pointOnShape.curve.loop) {
addSkippedBeziers(
bezierPieces,
posThis.curve,
posNext.curve,
posNext.t
);
}
}
cpThis = cpThis.next;
} while (cpThis !== cpEnd);
return bezierPieces;
}
/**
* @internal
* Adds pieces of skipped beziers
*/
function addSkippedBeziers(
bezierPieces : BezierPiece[],
curveStart : Curve,
curveEnd : Curve,
t1 : number) {
let curveThis = curveStart;
do {
curveThis = curveThis.next;
const tEnd = curveThis === curveEnd ? t1 : 1;
bezierPieces.push({ curve: curveThis, ts: [0, tEnd] });
} while (curveThis !== curveEnd);
}
export { getBoundaryPieceBeziers }