UNPKG

@davepagurek/flo-mat

Version:

Medial / Scale Axis Transform (MAT/SAT) Library.

54 lines (42 loc) 1.84 kB
import { LlRbTree } from 'flo-ll-rb-tree'; import { Loop } from 'flo-boolean'; import { CpNode } from '../cp-node/cp-node.js'; import { getShapeBounds } from '../svg/get-shape-bounds.js'; import { getMinYPos } from '../svg/get-min-y-pos.js'; import { find2Prong } from './find-2-prong.js'; import { add2Prong } from './add-2-prong.js'; /** * @internal * Find and add two-prongs that remove any holes in the shape. * @param loops The loops (that as a precondition must be ordered from * highest (i.e. smallest y-value) topmost point loops to lowest) * @param cpTrees * @param extreme The maximum coordinate value used to calculate floating point * tolerances. */ function findAndAddHoleClosing2Prongs( loops: Loop[], cpTrees: Map<Loop,LlRbTree<CpNode>>, extreme: number) { const bounds = getShapeBounds(loops); const squaredDiagonalLength = (bounds.maxX.p[0] - bounds.minX.p[0])**2 + (bounds.maxY.p[1] - bounds.minY.p[1])**2; // Find the topmost points on each loop. const minYs = loops.map(getMinYPos); // We start at 1 since 0 is the outer (root) loop for (let k=1; k<minYs.length; k++) { const posSource = minYs[k]; const holeClosingTwoProng = find2Prong( 0, loops, extreme, squaredDiagonalLength, cpTrees, posSource, true, k, false ); if (!holeClosingTwoProng) { throw new Error(`Unable to find hole-closing 2-prong`); } // TODO important - handle case of n-prong, i.e. more than one antipode // - currently we only handle case of single antipode (the general case) const { circle, zs: posAntipodes } = holeClosingTwoProng; add2Prong(cpTrees, circle, posSource, [posAntipodes[0]], true, extreme); } } export { findAndAddHoleClosing2Prongs }