flo-mat 4.1.5 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__tests__/closest-boundary-point/get-endpoint-info.spec.ts +140 -0
- package/__tests__/closest-boundary-point/root-interval-to-distance-squared-interval.spec.ts +87 -0
- package/__tests__/cp-node/fs/get-all-on-loop-by-loop.spec.ts +55 -0
- package/__tests__/cp-node/fs/get-angle-between-mat-curves.spec.ts +39 -3
- package/__tests__/cp-node/fs/get-boundary-bezier-parts-to-next.spec.ts +87 -3
- package/__tests__/cp-node/fs/get-boundary-beziers-between.spec.ts +68 -3
- package/__tests__/cp-node/fs/get-boundary-beziers-to-next.spec.ts +41 -3
- package/__tests__/cp-node/fs/get-boundary-distance-to-next.spec.ts +20 -3
- package/__tests__/cp-node/fs/get-branch-beziers.spec.ts +42 -3
- package/__tests__/cp-node/fs/get-branch.spec.ts +60 -3
- package/__tests__/cp-node/fs/get-cp-node-ordering.spec.ts +19 -3
- package/__tests__/cp-node/fs/get-distance-to-next.spec.ts +37 -4
- package/__tests__/cp-node/fs/get-edge-direction.spec.ts +50 -3
- package/__tests__/cp-node/fs/get-first-exit.spec.ts +78 -3
- package/__tests__/cp-node/fs/get-hole-closers.spec.ts +32 -3
- package/__tests__/cp-node/fs/get-implied-boundary-bezier-between.spec.ts +48 -3
- package/__tests__/cp-node/fs/get-mat-curve-between.spec.ts +77 -3
- package/__tests__/cp-node/fs/get-mat-curve-to-next.spec.ts +17 -4
- package/__tests__/cp-node/fs/get-mat-curves-between.spec.ts +38 -3
- package/__tests__/cp-node/fs/get-salience.spec.ts +68 -3
- package/__tests__/cp-node/fs/get-vertex-forward-children.spec.ts +40 -3
- package/__tests__/cp-node/fs/insert-cp-node.spec.ts +87 -3
- package/__tests__/cp-node/fs/is-special.spec.ts +1 -1
- package/__tests__/cp-node/fs/remove-cp-node.spec.ts +42 -3
- package/__tests__/find-2-prong/calc-seperation-tolerance.spec.ts +46 -0
- package/__tests__/find-2-prong/get-medial/get-closest-points.spec.ts +1 -1
- package/__tests__/floyd-warshall/get-graph.spec.ts +100 -0
- package/__tests__/get-mats-with-hole.ts +28 -0
- package/__tests__/get-mats1.spec.ts +61 -0
- package/__tests__/get-mats1.ts +75 -67
- package/__tests__/helpers/cp-node-by-id.ts +27 -0
- package/__tests__/helpers/expect-point-close.ts +42 -0
- package/__tests__/mat/hausdorff-distance-one-sided-exceeds.spec.ts +129 -0
- package/__tests__/mat/simplify-mat.spec.ts +85 -0
- package/__tests__/reconstruct-from-mat/reconstruct-from-mat.spec.ts +39 -0
- package/__tests__/specific-cases/test-svgs/achispado.svg +14 -0
- package/__tests__/utils/get-beziers-from-tangents.spec.ts +142 -0
- package/browser/index.js +12985 -9965
- package/browser/index.min.js +1 -1
- package/node/closest-boundary-point/cull-curve-pieces.d.ts +21 -0
- package/node/closest-boundary-point/cull-curve-pieces.js +40 -0
- package/node/closest-boundary-point/cull-curve-pieces.js.map +1 -0
- package/node/closest-boundary-point/get-close-boundary-points-certified.js +5 -2
- package/node/closest-boundary-point/get-close-boundary-points-certified.js.map +1 -1
- package/node/closest-boundary-point/get-endpoint-info.d.ts +39 -0
- package/node/closest-boundary-point/get-endpoint-info.js +78 -0
- package/node/closest-boundary-point/get-endpoint-info.js.map +1 -0
- package/node/closest-boundary-point/get-potential-closest-points-on-curve-certified.js +5 -19
- package/node/closest-boundary-point/get-potential-closest-points-on-curve-certified.js.map +1 -1
- package/node/closest-boundary-point/root-interval-to-distance-squared-interval.d.ts +17 -5
- package/node/closest-boundary-point/root-interval-to-distance-squared-interval.js +37 -50
- package/node/closest-boundary-point/root-interval-to-distance-squared-interval.js.map +1 -1
- package/node/corner/get-corner.d.ts +18 -1
- package/node/corner/get-corner.js +8 -1
- package/node/corner/get-corner.js.map +1 -1
- package/node/corner/get-interface-ccw.js.map +1 -1
- package/node/cp-node/cp-node.d.ts +4 -3
- package/node/cp-node/fs/get-all-on-loop-by-loop.js +0 -4
- package/node/cp-node/fs/get-all-on-loop-by-loop.js.map +1 -1
- package/node/cp-node/fs/get-angle-between-mat-curves.js +6 -4
- package/node/cp-node/fs/get-angle-between-mat-curves.js.map +1 -1
- package/node/cp-node/fs/get-boundary-beziers-between.d.ts +6 -4
- package/node/cp-node/fs/get-boundary-beziers-between.js +6 -4
- package/node/cp-node/fs/get-boundary-beziers-between.js.map +1 -1
- package/node/cp-node/fs/get-branch-beziers.d.ts +2 -1
- package/node/cp-node/fs/get-branch-beziers.js +3 -2
- package/node/cp-node/fs/get-branch-beziers.js.map +1 -1
- package/node/cp-node/fs/get-branch.js +1 -2
- package/node/cp-node/fs/get-branch.js.map +1 -1
- package/node/cp-node/fs/get-distance-to-next.js +4 -2
- package/node/cp-node/fs/get-distance-to-next.js.map +1 -1
- package/node/cp-node/fs/get-first-exit.d.ts +7 -3
- package/node/cp-node/fs/get-first-exit.js +13 -11
- package/node/cp-node/fs/get-first-exit.js.map +1 -1
- package/node/cp-node/fs/get-implied-boundary-bezier-between.d.ts +9 -1
- package/node/cp-node/fs/get-implied-boundary-bezier-between.js +11 -55
- package/node/cp-node/fs/get-implied-boundary-bezier-between.js.map +1 -1
- package/node/cp-node/fs/get-mat-curve-between.d.ts +4 -3
- package/node/cp-node/fs/get-mat-curve-between.js +5 -49
- package/node/cp-node/fs/get-mat-curve-between.js.map +1 -1
- package/node/cp-node/fs/get-mat-curve-to-next.d.ts +1 -1
- package/node/cp-node/fs/get-mat-curves-between.d.ts +8 -0
- package/node/cp-node/fs/get-mat-curves-between.js +9 -2
- package/node/cp-node/fs/get-mat-curves-between.js.map +1 -1
- package/node/cp-node/fs/get-real-prong-count.d.ts +2 -1
- package/node/cp-node/fs/get-real-prong-count.js +11 -5
- package/node/cp-node/fs/get-real-prong-count.js.map +1 -1
- package/node/cp-node/fs/get-salience.d.ts +10 -0
- package/node/cp-node/fs/get-salience.js +17 -1
- package/node/cp-node/fs/get-salience.js.map +1 -1
- package/node/cp-node/fs/is-fully-terminating.d.ts +4 -2
- package/node/cp-node/fs/is-fully-terminating.js +6 -15
- package/node/cp-node/fs/is-fully-terminating.js.map +1 -1
- package/node/cp-node/fs/is-on-same-loop.d.ts +1 -1
- package/node/cp-node/fs/is-special.d.ts +7 -0
- package/node/cp-node/fs/is-special.js +9 -2
- package/node/cp-node/fs/is-special.js.map +1 -1
- package/node/cp-node/fs/is-vertex.d.ts +1 -1
- package/node/cp-node/fs/traverse-edges.d.ts +7 -3
- package/node/cp-node/fs/traverse-edges.js +7 -3
- package/node/cp-node/fs/traverse-edges.js.map +1 -1
- package/node/cp-node/stringification/from-stringifyable.d.ts +2 -2
- package/node/cp-node/stringification/from-stringifyable.js +1 -1
- package/node/cp-node/stringification/from-stringifyable.js.map +1 -1
- package/node/cp-node/stringification/to-stringifyable.d.ts +3 -3
- package/node/cp-node/stringification/to-stringifyable.js +3 -3
- package/node/debug/debug.d.ts +26 -3
- package/node/debug/debug.js +16 -5
- package/node/debug/debug.js.map +1 -1
- package/node/find-2-prong/add-2-prong.js +1 -7
- package/node/find-2-prong/add-2-prong.js.map +1 -1
- package/node/find-2-prong/calc-seperation-tolerance.d.ts +28 -5
- package/node/find-2-prong/calc-seperation-tolerance.js +32 -89
- package/node/find-2-prong/calc-seperation-tolerance.js.map +1 -1
- package/node/find-2-prong/find-2-prong.js +8 -10
- package/node/find-2-prong/find-2-prong.js.map +1 -1
- package/node/find-2-prong/find-and-add-2-prongs.js +2 -2
- package/node/find-2-prong/find-and-add-2-prongs.js.map +1 -1
- package/node/find-2-prong/get-medial/get-antipodal-points.d.ts +1 -2
- package/node/find-2-prong/get-medial/get-antipodal-points.js +2 -3
- package/node/find-2-prong/get-medial/get-antipodal-points.js.map +1 -1
- package/node/find-2-prong/get-medial/get-closest-points.d.ts +1 -8
- package/node/find-2-prong/get-medial/get-closest-points.js +4 -40
- package/node/find-2-prong/get-medial/get-closest-points.js.map +1 -1
- package/node/find-2-prong/reduce-radius.d.ts +1 -1
- package/node/find-2-prong/reduce-radius.js +6 -3
- package/node/find-2-prong/reduce-radius.js.map +1 -1
- package/node/find-3-prong/calc-better-x.js +1 -1
- package/node/find-3-prong/calc-better-x.js.map +1 -1
- package/node/find-3-prong/find-3-prong-for-delta3s.d.ts +3 -2
- package/node/find-3-prong/find-3-prong-for-delta3s.js +35 -41
- package/node/find-3-prong/find-3-prong-for-delta3s.js.map +1 -1
- package/node/find-3-prong/find-3-prong.js +3 -1
- package/node/find-3-prong/find-3-prong.js.map +1 -1
- package/node/find-3-prong/find-and-add-3-prongs.js +16 -0
- package/node/find-3-prong/find-and-add-3-prongs.js.map +1 -1
- package/node/find-mat/create-initial-cp-tree.js +2 -2
- package/node/find-mat/create-initial-cp-tree.js.map +1 -1
- package/node/find-mat/find-mat.js +3 -4
- package/node/find-mat/find-mat.js.map +1 -1
- package/node/find-mat/find-mats.d.ts +6 -12
- package/node/find-mat/find-mats.js +10 -27
- package/node/find-mat/find-mats.js.map +1 -1
- package/node/find-mat/get-dull-corners-on-loop.js +2 -2
- package/node/find-mat/get-dull-corners-on-loop.js.map +1 -1
- package/node/find-mat/get-for-1-prongs-on-loop.js +36 -8
- package/node/find-mat/get-for-1-prongs-on-loop.js.map +1 -1
- package/node/find-mat/get-meta.d.ts +14 -4
- package/node/find-mat/get-meta.js +30 -24
- package/node/find-mat/get-meta.js.map +1 -1
- package/node/find-mat/get-sharp-corners.js +2 -2
- package/node/find-mat/get-sharp-corners.js.map +1 -1
- package/node/find-mat/mat-options.d.ts +2 -2
- package/node/floyd-warshall/get-graph.d.ts +12 -1
- package/node/floyd-warshall/get-graph.js +41 -38
- package/node/floyd-warshall/get-graph.js.map +1 -1
- package/node/geometry/get-bounding-box-.d.ts +16 -2
- package/node/geometry/get-bounding-box-.js +5 -2
- package/node/geometry/get-bounding-box-.js.map +1 -1
- package/node/geometry/get-closest-square-distance-to-rect.d.ts +3 -0
- package/node/geometry/get-closest-square-distance-to-rect.js +7 -5
- package/node/geometry/get-closest-square-distance-to-rect.js.map +1 -1
- package/node/geometry/get-closest-squared-distance-to-rotated-rect.d.ts +4 -0
- package/node/geometry/get-closest-squared-distance-to-rotated-rect.js +11 -5
- package/node/geometry/get-closest-squared-distance-to-rotated-rect.js.map +1 -1
- package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.js +1 -2
- package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.js.map +1 -1
- package/node/index.d.ts +3 -2
- package/node/index.js +2 -1
- package/node/index.js.map +1 -1
- package/node/mat/clone-mat.d.ts +9 -0
- package/node/mat/clone-mat.js +17 -0
- package/node/mat/clone-mat.js.map +1 -0
- package/node/mat/clone-meta.d.ts +12 -0
- package/node/mat/clone-meta.js +24 -0
- package/node/mat/clone-meta.js.map +1 -0
- package/node/mat/get-boundary-piece-beziers.d.ts +5 -0
- package/node/mat/get-boundary-piece-beziers.js +7 -93
- package/node/mat/get-boundary-piece-beziers.js.map +1 -1
- package/node/mat/get-largest-3-prong.d.ts +6 -0
- package/node/mat/get-largest-3-prong.js +8 -5
- package/node/mat/get-largest-3-prong.js.map +1 -1
- package/node/mat/get-largest-vertex.d.ts +15 -1
- package/node/mat/get-largest-vertex.js +20 -7
- package/node/mat/get-largest-vertex.js.map +1 -1
- package/node/mat/hausdorff-distance-one-sided-exceeds.d.ts +79 -0
- package/node/mat/hausdorff-distance-one-sided-exceeds.js +251 -0
- package/node/mat/hausdorff-distance-one-sided-exceeds.js.map +1 -0
- package/node/mat/mat-meta.d.ts +0 -6
- package/node/mat/simplify-mat.d.ts +25 -8
- package/node/mat/simplify-mat.js +182 -53
- package/node/mat/simplify-mat.js.map +1 -1
- package/node/mat/trim-mat.d.ts +4 -2
- package/node/mat/trim-mat.js +3 -1
- package/node/mat/trim-mat.js.map +1 -1
- package/node/point-on-shape/get-boundary-tangent-line.d.ts +19 -0
- package/node/point-on-shape/get-boundary-tangent-line.js +33 -0
- package/node/point-on-shape/get-boundary-tangent-line.js.map +1 -0
- package/node/point-on-shape/get-osculating-circle.d.ts +6 -4
- package/node/point-on-shape/get-osculating-circle.js +6 -4
- package/node/point-on-shape/get-osculating-circle.js.map +1 -1
- package/node/point-on-shape/get-pos-corner.js +2 -2
- package/node/point-on-shape/get-pos-corner.js.map +1 -1
- package/node/reconstruct-from-mat/reconstruct-from-mat.js +20 -80
- package/node/reconstruct-from-mat/reconstruct-from-mat.js.map +1 -1
- package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.d.ts +4 -0
- package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js +4 -0
- package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js.map +1 -1
- package/node/sat/cull.d.ts +7 -6
- package/node/sat/cull.js +13 -16
- package/node/sat/cull.js.map +1 -1
- package/node/sat/get-sat-culls.d.ts +12 -2
- package/node/sat/get-sat-culls.js +21 -16
- package/node/sat/get-sat-culls.js.map +1 -1
- package/node/svg/get-shape-bounds.d.ts +1 -12
- package/node/svg/get-shape-bounds.js +2 -3
- package/node/svg/get-shape-bounds.js.map +1 -1
- package/node/sweep-line/sweep-line.js.map +1 -1
- package/node/utils/get-beziers-from-tangents.d.ts +28 -0
- package/node/utils/get-beziers-from-tangents.js +92 -0
- package/node/utils/get-beziers-from-tangents.js.map +1 -0
- package/node/vertex/remove-vertex.d.ts +5 -3
- package/node/vertex/remove-vertex.js +5 -3
- package/node/vertex/remove-vertex.js.map +1 -1
- package/package.json +9 -9
- package/qv-infinite-loop.md +120 -0
- package/src/closest-boundary-point/cull-curve-pieces.ts +49 -0
- package/src/closest-boundary-point/get-close-boundary-points-certified.ts +5 -2
- package/src/closest-boundary-point/get-endpoint-info.ts +96 -0
- package/src/closest-boundary-point/get-potential-closest-points-on-curve-certified.ts +5 -23
- package/src/closest-boundary-point/root-interval-to-distance-squared-interval.ts +42 -60
- package/src/corner/get-corner.ts +10 -1
- package/src/corner/get-interface-ccw.ts +2 -2
- package/src/cp-node/cp-node.ts +4 -3
- package/src/cp-node/fs/get-all-on-loop-by-loop.ts +0 -4
- package/src/cp-node/fs/get-angle-between-mat-curves.ts +6 -4
- package/src/cp-node/fs/get-boundary-beziers-between.ts +10 -8
- package/src/cp-node/fs/get-branch-beziers.ts +3 -2
- package/src/cp-node/fs/get-branch.ts +1 -2
- package/src/cp-node/fs/get-distance-to-next.ts +4 -2
- package/src/cp-node/fs/get-first-exit.ts +15 -14
- package/src/cp-node/fs/get-implied-boundary-bezier-between.ts +17 -69
- package/src/cp-node/fs/get-mat-curve-between.ts +9 -67
- package/src/cp-node/fs/get-mat-curves-between.ts +9 -2
- package/src/cp-node/fs/get-real-prong-count.ts +11 -7
- package/src/cp-node/fs/get-salience.ts +15 -2
- package/src/cp-node/fs/is-fully-terminating.ts +6 -18
- package/src/cp-node/fs/is-on-same-loop.ts +2 -2
- package/src/cp-node/fs/is-special.ts +11 -6
- package/src/cp-node/fs/is-vertex.ts +1 -1
- package/src/cp-node/fs/traverse-edges.ts +8 -4
- package/src/cp-node/stringification/from-stringifyable.ts +75 -75
- package/src/cp-node/stringification/to-stringifyable.ts +3 -3
- package/src/debug/debug.ts +44 -8
- package/src/find-2-prong/add-2-prong.ts +2 -9
- package/src/find-2-prong/calc-seperation-tolerance.ts +34 -115
- package/src/find-2-prong/find-2-prong.ts +9 -11
- package/src/find-2-prong/find-and-add-2-prongs.ts +2 -2
- package/src/find-2-prong/get-medial/get-antipodal-points.ts +1 -3
- package/src/find-2-prong/get-medial/get-closest-points.ts +6 -51
- package/src/find-2-prong/reduce-radius.ts +6 -4
- package/src/find-3-prong/calc-better-x.ts +2 -2
- package/src/find-3-prong/find-3-prong-for-delta3s.ts +197 -214
- package/src/find-3-prong/find-3-prong.ts +54 -51
- package/src/find-3-prong/find-and-add-3-prongs.ts +20 -1
- package/src/find-mat/create-initial-cp-tree.ts +2 -2
- package/src/find-mat/find-mat.ts +4 -6
- package/src/find-mat/find-mats.ts +83 -105
- package/src/find-mat/get-dull-corners-on-loop.ts +2 -2
- package/src/find-mat/get-for-1-prongs-on-loop.ts +40 -8
- package/src/find-mat/get-meta.ts +34 -39
- package/src/find-mat/get-sharp-corners.ts +2 -2
- package/src/find-mat/mat-options.ts +2 -2
- package/src/floyd-warshall/get-graph.ts +46 -47
- package/src/geometry/get-bounding-box-.ts +5 -2
- package/src/geometry/get-closest-square-distance-to-rect.ts +7 -7
- package/src/geometry/get-closest-squared-distance-to-rotated-rect.ts +12 -10
- package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.ts +1 -2
- package/src/index.ts +3 -2
- package/src/mat/clone-mat.ts +9 -3
- package/src/mat/clone-meta.ts +8 -0
- package/src/mat/get-boundary-piece-beziers.ts +16 -117
- package/src/mat/get-largest-3-prong.ts +9 -6
- package/src/mat/get-largest-vertex.ts +25 -9
- package/src/mat/hausdorff-distance-one-sided-exceeds.ts +314 -0
- package/src/mat/mat-meta.ts +0 -9
- package/src/mat/simplify-mat.ts +254 -116
- package/src/mat/trim-mat.ts +6 -4
- package/src/point-on-shape/get-boundary-tangent-line.ts +36 -0
- package/src/point-on-shape/get-osculating-circle.ts +7 -5
- package/src/point-on-shape/get-pos-corner.ts +2 -2
- package/src/reconstruct-from-mat/reconstruct-from-mat.ts +22 -111
- package/src/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.ts +4 -0
- package/src/sat/cull.ts +16 -20
- package/src/sat/get-sat-culls.ts +28 -23
- package/src/svg/get-shape-bounds.ts +2 -3
- package/src/sweep-line/sweep-line.ts +1 -1
- package/src/utils/get-beziers-from-tangents.ts +110 -0
- package/src/utils/map-map.ts +1 -1
- package/src/vertex/remove-vertex.ts +5 -3
- package/__tests__/cp-node/fs/get-distance-between.spec.ts +0 -7
- package/__tests__/cp-node/fs/get-terminating-on-circle.spec.ts +0 -24
- package/__tests__/cp-node/fs/is-single-3-prong.spec.ts +0 -17
- package/__tests__/cp-node/fs/iterate-all-on-loop.spec.ts +0 -17
- package/__tests__/cp-node/fs/traverse-all-forward.spec.ts +0 -14
- package/node/closest-boundary-point/cull-bezier-pieces-1.d.ts +0 -9
- package/node/closest-boundary-point/cull-bezier-pieces-1.js +0 -17
- package/node/closest-boundary-point/cull-bezier-pieces-1.js.map +0 -1
- package/node/closest-boundary-point/cull-by-loose-bounding-box.d.ts +0 -13
- package/node/closest-boundary-point/cull-by-loose-bounding-box.js +0 -27
- package/node/closest-boundary-point/cull-by-loose-bounding-box.js.map +0 -1
- package/node/closest-boundary-point/cull-by-tight-boundary-box.d.ts +0 -11
- package/node/closest-boundary-point/cull-by-tight-boundary-box.js +0 -27
- package/node/closest-boundary-point/cull-by-tight-boundary-box.js.map +0 -1
- package/node/cp-node/fs/find-first.d.ts +0 -10
- package/node/cp-node/fs/find-first.js +0 -19
- package/node/cp-node/fs/find-first.js.map +0 -1
- package/node/debug/functions/check-ordering.d.ts +0 -4
- package/node/debug/functions/check-ordering.js +0 -43
- package/node/debug/functions/check-ordering.js.map +0 -1
- package/node/find-2-prong/cull-bezier-pieces.d.ts +0 -13
- package/node/find-2-prong/cull-bezier-pieces.js +0 -43
- package/node/find-2-prong/cull-bezier-pieces.js.map +0 -1
- package/node/floyd-warshall/get-hole-closer-pairs.d.ts +0 -8
- package/node/floyd-warshall/get-hole-closer-pairs.js +0 -27
- package/node/floyd-warshall/get-hole-closer-pairs.js.map +0 -1
- package/node/utils/dual-set.d.ts +0 -27
- package/node/utils/dual-set.js +0 -55
- package/node/utils/dual-set.js.map +0 -1
- package/node/utils/tri-map.d.ts +0 -27
- package/node/utils/tri-map.js +0 -49
- package/node/utils/tri-map.js.map +0 -1
- package/src/closest-boundary-point/cull-bezier-pieces-1.ts +0 -36
- package/src/closest-boundary-point/cull-by-loose-bounding-box.ts +0 -42
- package/src/closest-boundary-point/cull-by-tight-boundary-box.ts +0 -43
- package/src/closest-boundary-point/get-p-from-box.ts +0 -14
- package/src/cp-node/fs/add-distance-from.ts +0 -49
- package/src/cp-node/fs/get-distance-between.ts +0 -16
- package/src/cp-node/fs/get-terminating-on-circle.ts +0 -24
- package/src/cp-node/fs/is-single-3-prong.ts +0 -15
- package/src/cp-node/fs/iterate-all-on-loop.ts +0 -15
- package/src/cp-node/fs/traverse-all-forward.ts +0 -24
- package/src/debug/functions/draw/draw-beziers-as-single-path.ts +0 -40
- package/src/debug/functions/draw/draw-disk.ts +0 -34
- package/src/debug/functions/draw/xmlns.ts +0 -5
- package/src/find-2-prong/cull-bezier-pieces.ts +0 -61
- package/src/find-2-prong/find-and-add-2-prong.ts +0 -30
- package/src/find-2-prong/get-medial/get-closest-points-d.ts +0 -213
- package/src/find-2-prong/x-for-debugging.ts +0 -13
- package/src/floyd-warshall/get-hole-closer-pairs.ts +0 -35
- package/src/mat/get-two-prong-type.ts +0 -13
- package/src/point-on-shape/is-pos-dull-corner.ts +0 -18
- package/src/point-on-shape/is-pos-quite-dull-corner.ts +0 -18
- package/src/point-on-shape/is-pos-quite-sharp-corner.ts +0 -18
- package/src/point-on-shape/pos-to-human-string.ts +0 -18
- package/src/sweep-line/are-boxes-intersecting.ts +0 -37
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
import { CpNode } from "../cp-node.js";
|
|
1
|
+
import type { CpNode } from "../cp-node.js";
|
|
2
|
+
import { isTerminating } from "./is-terminating.js";
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
* Returns the first `CpNode`
|
|
6
|
-
*
|
|
6
|
+
* Returns the first `CpNode` *after* the given one (by successively applying
|
|
7
|
+
* `.nextOnCircle`) that exits the circle, i.e. the first one that is not
|
|
8
|
+
* terminating - the given `CpNode` itself is never returned.
|
|
9
|
+
*
|
|
10
|
+
* * returns `undefined` if no other `CpNode` on the circle exits (e.g. the
|
|
11
|
+
* other `CpNode` of a 1-prong, or the MAT is a single point)
|
|
7
12
|
*/
|
|
8
|
-
function getFirstExit(cpNode: CpNode) {
|
|
9
|
-
|
|
10
|
-
const startNode = cpNode;
|
|
11
|
-
let cpNode_ = startNode;
|
|
13
|
+
function getFirstExit(cpNode: CpNode): CpNode | undefined {
|
|
14
|
+
let cpNode_ = cpNode.nextOnCircle;
|
|
12
15
|
|
|
13
|
-
while (cpNode_
|
|
14
|
-
cpNode_
|
|
15
|
-
|
|
16
|
-
if (cpNode_ === startNode) {
|
|
17
|
-
// The very special case the MAT is a single point.
|
|
18
|
-
return undefined;
|
|
16
|
+
while (cpNode_ !== cpNode) {
|
|
17
|
+
if (!isTerminating(cpNode_)) {
|
|
18
|
+
return cpNode_;
|
|
19
19
|
}
|
|
20
|
+
cpNode_ = cpNode_.nextOnCircle;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
return
|
|
23
|
+
return undefined;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
|
|
@@ -1,76 +1,24 @@
|
|
|
1
1
|
import type { CpNode } from '../cp-node.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
import { getBoundaryTangentLine } from '../../point-on-shape/get-boundary-tangent-line.js';
|
|
3
|
+
import { getBeziersFromTangents } from '../../utils/get-beziers-from-tangents.js';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Returns the bezier curves (an array of 1 or 2 lines or quadratics joined
|
|
8
|
+
* smoothly) approximating the shape boundary between the contact points of
|
|
9
|
+
* two `CpNode`s.
|
|
10
|
+
*
|
|
11
|
+
* @param cpNodeA
|
|
12
|
+
* @param cpNodeB
|
|
13
|
+
*/
|
|
14
14
|
function getImpliedBoundaryBezierBetween(
|
|
15
15
|
cpNodeA: CpNode,
|
|
16
|
-
cpNodeB: CpNode): number[][]
|
|
17
|
-
|
|
18
|
-
const posA = cpNodeA.pointOnShape;
|
|
19
|
-
const posB = cpNodeB.pointOnShape;
|
|
20
|
-
|
|
21
|
-
let { curve: curveA, p: pA, t: tA } = posA;
|
|
22
|
-
let { curve: curveB, p: pB, t: tB } = posB;
|
|
23
|
-
|
|
24
|
-
if (pA[0] === pB[0] && pA[1] === pB[1]) {
|
|
25
|
-
return [pA];
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (tA === 1) { tA = 0; curveA = curveA.next; }
|
|
29
|
-
if (tB === 0) { tB = 1; curveB = curveB.prev; }
|
|
30
|
-
|
|
31
|
-
const { ps: psA } = curveA;
|
|
32
|
-
const { ps: psB } = curveB;
|
|
33
|
-
|
|
34
|
-
const lA = [pA,translate(pA)(toUnitVector(tangent(psA, tA)))];
|
|
35
|
-
const lB = [pB,translate(pB)(toUnitVector(tangent(psB, tB)))];
|
|
36
|
-
|
|
37
|
-
const mid = lineLineIntersection(lA, lB);
|
|
38
|
-
|
|
39
|
-
const c = fromTo(pA,pB);
|
|
40
|
-
|
|
41
|
-
let twisted: boolean;
|
|
42
|
-
if (!mid) {
|
|
43
|
-
twisted = true;
|
|
44
|
-
} else {
|
|
45
|
-
const a = fromTo(pA, mid);
|
|
46
|
-
const b = fromTo(pB, mid);
|
|
47
|
-
|
|
48
|
-
twisted = dot(a,c) < 0 || dot(b,c) > 0;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (!twisted) {
|
|
52
|
-
// drawFs.bezier(g, [pA, mid!, pB], 'thin10 pink nofill', 0)
|
|
53
|
-
return [pA, mid!, pB];
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const w1 = fromTo(lA[0], lA[1]); // This is a unit vector
|
|
57
|
-
const w2 = fromTo(lB[0], lB[1]); // This is a unit vector
|
|
58
|
-
|
|
59
|
-
const d1 = abs(cross(c, w1)) / (3*3);
|
|
60
|
-
const d2 = abs(cross(c, w2)) / (3*3);
|
|
61
|
-
|
|
62
|
-
if (d1 > TOLERANCE_ADD_2PRONG || d2 > TOLERANCE_ADD_2PRONG) {
|
|
63
|
-
// not within tolerance
|
|
64
|
-
return undefined;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (d1 > TOLERANCE_USE_LINE || d2 > TOLERANCE_USE_LINE) {
|
|
68
|
-
// approximate with cubic bezier?
|
|
69
|
-
return undefined; // add 2-prong
|
|
70
|
-
}
|
|
16
|
+
cpNodeB: CpNode): number[][][] {
|
|
71
17
|
|
|
72
|
-
|
|
73
|
-
|
|
18
|
+
return getBeziersFromTangents(
|
|
19
|
+
getBoundaryTangentLine(cpNodeA.pointOnShape, true),
|
|
20
|
+
getBoundaryTangentLine(cpNodeB.pointOnShape, false)
|
|
21
|
+
);
|
|
74
22
|
}
|
|
75
23
|
|
|
76
24
|
|
|
@@ -1,82 +1,24 @@
|
|
|
1
1
|
import type { CpNode } from '../cp-node.js';
|
|
2
|
-
import {
|
|
3
|
-
fromTo as fromToVec, dot, cross, rotate90Degrees, interpolate, translate,
|
|
4
|
-
lineLineIntersection
|
|
5
|
-
} from 'flo-vector2d';
|
|
6
2
|
import { getEdgeDirection } from './get-edge-direction.js';
|
|
7
|
-
|
|
8
|
-
const { abs } = Math;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
/** @internal */
|
|
12
|
-
const TOLERANCE_ADD_2PRONG = 0.01;
|
|
13
|
-
/** @internal */
|
|
14
|
-
const TOLERANCE_USE_LINE = 0.0001; // else cubic
|
|
3
|
+
import { getBeziersFromTangents } from '../../utils/get-beziers-from-tangents.js';
|
|
15
4
|
|
|
16
5
|
|
|
17
6
|
/**
|
|
18
|
-
* Returns the bezier
|
|
19
|
-
* `CpNode`'s
|
|
7
|
+
* Returns the bezier curves (an array of 1 or 2 lines or quadratics joined
|
|
8
|
+
* smoothly) from the maximal disk of one `CpNode` to another `CpNode`'s
|
|
9
|
+
* maximal disk.
|
|
20
10
|
*
|
|
21
11
|
* @param cpNodeFrom
|
|
22
12
|
* @param cpNodeTo
|
|
23
13
|
*/
|
|
24
14
|
function getMatCurveBetween(
|
|
25
15
|
cpNodeFrom: CpNode,
|
|
26
|
-
cpNodeTo: CpNode): number[][] {
|
|
27
|
-
|
|
28
|
-
const fromCc = cpNodeFrom.pointOnShape.circle.center;
|
|
29
|
-
const fromL = getEdgeDirection(cpNodeFrom);
|
|
30
|
-
|
|
31
|
-
const toCc = cpNodeTo.pointOnShape.circle.center;
|
|
32
|
-
const toL = getEdgeDirection(cpNodeTo.prevOnCircle);
|
|
33
|
-
|
|
34
|
-
const mid = lineLineIntersection(fromL, toL);
|
|
35
|
-
|
|
36
|
-
const c = fromToVec(fromCc,toCc);
|
|
37
|
-
|
|
38
|
-
let twisted: boolean;
|
|
39
|
-
if (!mid) {
|
|
40
|
-
twisted = true;
|
|
41
|
-
} else {
|
|
42
|
-
const a = fromToVec(fromCc, mid);
|
|
43
|
-
const b = fromToVec(toCc, mid);
|
|
44
|
-
|
|
45
|
-
twisted = dot(a,c) < 0 || dot(b,c) > 0;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (!twisted) {
|
|
49
|
-
return [fromCc, mid!, toCc];
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const r = rotate90Degrees(c);
|
|
53
|
-
const w1 = fromToVec(fromL[0], fromL[1]); // This is a unit vector
|
|
54
|
-
const w2 = fromToVec(toL[0], toL[1]); // This is a unit vector
|
|
55
|
-
|
|
56
|
-
const d1 = abs(cross(c, w1)) / (3*3);
|
|
57
|
-
const d2 = abs(cross(c, w2)) / (3*3);
|
|
58
|
-
|
|
59
|
-
if (d1 > TOLERANCE_ADD_2PRONG || d2 > TOLERANCE_ADD_2PRONG) {
|
|
60
|
-
// FUTURE - not within tolerance - must add additional 2-prong
|
|
61
|
-
return [fromCc, toCc];
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (d1 > TOLERANCE_USE_LINE || d2 > TOLERANCE_USE_LINE) {
|
|
65
|
-
// approximate with cubic bezier
|
|
66
|
-
const m1 = interpolate(fromCc,toCc,1/3);
|
|
67
|
-
const m2 = interpolate(fromCc,toCc,2/3);
|
|
68
|
-
const v1 = translate(r, m1);
|
|
69
|
-
const v2 = translate(r, m2);
|
|
70
|
-
const l1 = [m1,v1];
|
|
71
|
-
const l2 = [m2,v2];
|
|
72
|
-
const mid1 = lineLineIntersection(fromL, l1)!;
|
|
73
|
-
const mid2 = lineLineIntersection(toL, l2)!;
|
|
74
|
-
|
|
75
|
-
return [fromCc, mid1, mid2, toCc];
|
|
76
|
-
}
|
|
16
|
+
cpNodeTo: CpNode): number[][][] {
|
|
77
17
|
|
|
78
|
-
|
|
79
|
-
|
|
18
|
+
return getBeziersFromTangents(
|
|
19
|
+
getEdgeDirection(cpNodeFrom),
|
|
20
|
+
getEdgeDirection(cpNodeTo.prevOnCircle)
|
|
21
|
+
);
|
|
80
22
|
}
|
|
81
23
|
|
|
82
24
|
|
|
@@ -2,6 +2,14 @@ import { CpNode } from '../cp-node.js';
|
|
|
2
2
|
import { getMatCurveBetween } from './get-mat-curve-between.js';
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Returns the (flattened) array of bezier curves (lines or quadratics)
|
|
7
|
+
* representing the medial axis from one `CpNode` to another by following
|
|
8
|
+
* `next` repeatedly.
|
|
9
|
+
*
|
|
10
|
+
* @param cpNodeS
|
|
11
|
+
* @param cpNodeE
|
|
12
|
+
*/
|
|
5
13
|
function getMatCurvesBetween(
|
|
6
14
|
cpNodeS: CpNode,
|
|
7
15
|
cpNodeE: CpNode) {
|
|
@@ -9,8 +17,7 @@ function getMatCurvesBetween(
|
|
|
9
17
|
let cpNode = cpNodeS;
|
|
10
18
|
const pss: number[][][] = [];
|
|
11
19
|
while (cpNode !== cpNodeE) {
|
|
12
|
-
|
|
13
|
-
pss.push(ps);
|
|
20
|
+
pss.push(...getMatCurveBetween(cpNode, cpNode.next));
|
|
14
21
|
|
|
15
22
|
cpNode = cpNode.next;
|
|
16
23
|
}
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import { CpNode } from "../cp-node.js";
|
|
2
|
-
import { getAllOnCircle } from "./get-all-on-circle.js";
|
|
3
2
|
import { isTerminating } from "./is-terminating.js";
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
|
-
* Returns the number of contact points (up to planar coordinates) on the
|
|
8
|
-
* maximal disk circle implied by this `CpNode
|
|
9
|
-
*
|
|
6
|
+
* Returns the number of contact points (up to planar coordinates) on the
|
|
7
|
+
* maximal disk circle implied by this `CpNode`, i.e. the number of
|
|
8
|
+
* non-terminating `CpNode`s on its circle.
|
|
9
|
+
*
|
|
10
10
|
* See also `getProngCount`.
|
|
11
11
|
*/
|
|
12
12
|
function getRealProngCount(cpNode: CpNode) {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
let count = 0;
|
|
14
|
+
let cpNode_ = cpNode;
|
|
15
|
+
do {
|
|
16
|
+
if (!isTerminating(cpNode_)) { count++; }
|
|
17
|
+
cpNode_ = cpNode_.nextOnCircle;
|
|
18
|
+
} while (cpNode_ !== cpNode);
|
|
15
19
|
|
|
16
|
-
return
|
|
20
|
+
return count;
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
|
|
@@ -6,8 +6,18 @@ import { sum } from '../../utils/sum.js';
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
+
* Returns the salience of the given `CpNode`: the ratio of the boundary length
|
|
10
|
+
* from its contact point forward to the next contact point on its circle to
|
|
11
|
+
* the straight distance between those two points.
|
|
12
|
+
*
|
|
13
|
+
* * `Infinity` if that stretch of boundary passes a hole closer
|
|
14
|
+
* * `0` if the two contact points coincide with no boundary in between (the
|
|
15
|
+
* terminating `CpNode` of a 1-prong) - the other `CpNode` of a 1-prong,
|
|
16
|
+
* whose stretch is the entire boundary, gives `Infinity`
|
|
17
|
+
*
|
|
9
18
|
* See https://research.gold.ac.uk/id/eprint/31944/
|
|
10
|
-
*
|
|
19
|
+
*
|
|
20
|
+
* @param cpNode
|
|
11
21
|
*/
|
|
12
22
|
function getSalience(cpNode: CpNode) {
|
|
13
23
|
const cpNode1 = cpNode;
|
|
@@ -21,7 +31,10 @@ function getSalience(cpNode: CpNode) {
|
|
|
21
31
|
|
|
22
32
|
const s = sum(pss.map(ps => totalLength(ps)));
|
|
23
33
|
|
|
24
|
-
|
|
34
|
+
if (hasHoleCloser) { return Infinity; }
|
|
35
|
+
if (s === 0) { return 0; } // (avoids `0/0` for the 1-prong case)
|
|
36
|
+
|
|
37
|
+
return s/d;
|
|
25
38
|
}
|
|
26
39
|
|
|
27
40
|
|
|
@@ -1,28 +1,16 @@
|
|
|
1
1
|
import type { CpNode } from "../cp-node.js";
|
|
2
|
-
import {
|
|
2
|
+
import { getRealProngCount } from "./get-real-prong-count.js";
|
|
3
3
|
import { isTerminating } from "./is-terminating.js";
|
|
4
|
-
import { isTrivial } from "./is-trivial.js";
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
|
-
* Like `isTerminating` but only returns true if all `CpNode`s on the circle
|
|
9
|
-
* (except this.prevOnCircle)
|
|
7
|
+
* Like `isTerminating` but only returns `true` if all `CpNode`s on the circle
|
|
8
|
+
* (except possibly the one leading back, i.e. `this.prevOnCircle`) are
|
|
9
|
+
* terminating - i.e. the `CpNode` is terminating and its vertex has at most
|
|
10
|
+
* one real prong.
|
|
10
11
|
*/
|
|
11
12
|
function isFullyTerminating(cpNode: CpNode) {
|
|
12
|
-
|
|
13
|
-
return false;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (isTrivial(cpNode)) {
|
|
17
|
-
return true;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
while (cpNode.prev === cpNode.prevOnCircle) {
|
|
21
|
-
cpNode = cpNode.prev;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return getAllOnCircle(cpNode.prevOnCircle, true)
|
|
25
|
-
.every(isTerminating);
|
|
13
|
+
return isTerminating(cpNode) && getRealProngCount(cpNode) <= 1;
|
|
26
14
|
}
|
|
27
15
|
|
|
28
16
|
|
|
@@ -2,13 +2,18 @@ import type { CpNode } from "../cp-node.js";
|
|
|
2
2
|
import { getRealProngCount } from "./get-real-prong-count.js";
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Returns `true` if the given `CpNode` is on a 'special' MAT vertex, i.e. one
|
|
7
|
+
* that is not a plain 2-prong: a leaf, a 3-prong (or higher) or a hole-closer.
|
|
8
|
+
*
|
|
9
|
+
* * these are the vertices that must be kept when simplifying the MAT and
|
|
10
|
+
* the vertices of the MAT seen as a graph
|
|
11
|
+
*/
|
|
12
|
+
function isSpecial(cpNode: CpNode) {
|
|
8
13
|
return (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
)
|
|
14
|
+
getRealProngCount(cpNode) !== 2 ||
|
|
15
|
+
cpNode.isHoleClosing
|
|
16
|
+
);
|
|
12
17
|
}
|
|
13
18
|
|
|
14
19
|
|
|
@@ -4,10 +4,14 @@ import { getAllOnLoop } from './get-all-on-loop.js';
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Traverses all edges
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* Traverses all edges of the given MAT tree exactly once each, calling the
|
|
8
|
+
* callback for one of the two `CpNode`s representing each edge.
|
|
9
|
+
*
|
|
10
|
+
* * the edges are visited in boundary order starting from the given `CpNode`
|
|
11
|
+
* (not depth first)
|
|
12
|
+
*
|
|
13
|
+
* @param cpNode Any `CpNode` on the MAT.
|
|
14
|
+
* @param traverseEdgesCallback A callback function for each CpNode representing the vertex at the
|
|
11
15
|
* start of an edge.
|
|
12
16
|
*/
|
|
13
17
|
function traverseEdges(
|
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
import type { PointOnShape } from "../../point-on-shape/point-on-shape.js";
|
|
2
|
-
import type { CpNode } from "../cp-node";
|
|
3
|
-
import type { CpNodeStringifyable } from "./cp-node-stringifyable";
|
|
4
|
-
import type { Mutable } from "../../utils/mutable.js";
|
|
5
|
-
import { EDGES } from "./cp-node-stringifyable";
|
|
6
|
-
import { getAllOnCircle } from "../fs/get-all-on-circle.js";
|
|
7
|
-
import { loopFromStringifyable } from './loop-from-stringifyable.js';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
function fromStringifyable(
|
|
11
|
-
cpNodesStringifyable: CpNodeStringifyable) {
|
|
12
|
-
|
|
13
|
-
const { cpNodes: _cpNodes, loops: _loops } = cpNodesStringifyable;
|
|
14
|
-
const loops = _loops.map(loopFromStringifyable);
|
|
15
|
-
const loopsByIdx = new Map(loops.map(loop => [loop.idx, loop]));
|
|
16
|
-
|
|
17
|
-
//--------------------------------------------------------------------------
|
|
18
|
-
// First pass: build all CpNode objects with proper `cp`.
|
|
19
|
-
// Edges still hold number ids at this point.
|
|
20
|
-
//--------------------------------------------------------------------------
|
|
21
|
-
const cpNodes: CpNode[] = _cpNodes.map(cpNode_ => {
|
|
22
|
-
const { id, pointOnShape, isHoleClosing, isIntersection } = cpNode_;
|
|
23
|
-
const { circle, order, order2 } = pointOnShape;
|
|
24
|
-
const { curveIdx, loopIdx, p, pDd, t, isSource } = pointOnShape;
|
|
25
|
-
|
|
26
|
-
const curve = loopsByIdx.get(loopIdx)!.curves[curveIdx];
|
|
27
|
-
|
|
28
|
-
const pointOnShape_: PointOnShape = {
|
|
29
|
-
circle,
|
|
30
|
-
curve, p, pDd, t, isSource,
|
|
31
|
-
order, order2
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
return {
|
|
35
|
-
...cpNode_,
|
|
36
|
-
id, isHoleClosing, isIntersection,
|
|
37
|
-
pointOnShape: pointOnShape_
|
|
38
|
-
} as CpNode;
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
//--------------------------------------------------------------------------
|
|
42
|
-
// Second pass: replace number id edges with real CpNode references.
|
|
43
|
-
//--------------------------------------------------------------------------
|
|
44
|
-
const nodeMap = new Map<number, CpNode>(cpNodes.map(n => [n.id, n]));
|
|
45
|
-
|
|
46
|
-
for (const cpNode of cpNodes) {
|
|
47
|
-
for (const edge of EDGES) {
|
|
48
|
-
const id = cpNode[edge] as unknown as number | undefined;
|
|
49
|
-
if (id === undefined) { continue; }
|
|
50
|
-
|
|
51
|
-
// @ts-ignore
|
|
52
|
-
cpNode[edge] = nodeMap.get(id)!;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
//--------------------------------------------------------------------------
|
|
57
|
-
// Third pass: one shared `Circle` object per on-circle ring, as when the
|
|
58
|
-
// MAT was built (the JSON gave every contact point its own copy).
|
|
59
|
-
//--------------------------------------------------------------------------
|
|
60
|
-
const done = new Set<CpNode>();
|
|
61
|
-
for (const cpNode of cpNodes) {
|
|
62
|
-
if (done.has(cpNode)) { continue; }
|
|
63
|
-
|
|
64
|
-
const { circle } = cpNode.pointOnShape;
|
|
65
|
-
for (const cp of getAllOnCircle(cpNode)) {
|
|
66
|
-
done.add(cp);
|
|
67
|
-
(cp.pointOnShape as Mutable<PointOnShape>).circle = circle;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return cpNodes[0];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
export { fromStringifyable }
|
|
1
|
+
import type { PointOnShape } from "../../point-on-shape/point-on-shape.js";
|
|
2
|
+
import type { CpNode } from "../cp-node.js";
|
|
3
|
+
import type { CpNodeStringifyable } from "./cp-node-stringifyable.js";
|
|
4
|
+
import type { Mutable } from "../../utils/mutable.js";
|
|
5
|
+
import { EDGES } from "./cp-node-stringifyable.js";
|
|
6
|
+
import { getAllOnCircle } from "../fs/get-all-on-circle.js";
|
|
7
|
+
import { loopFromStringifyable } from './loop-from-stringifyable.js';
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
function fromStringifyable(
|
|
11
|
+
cpNodesStringifyable: CpNodeStringifyable) {
|
|
12
|
+
|
|
13
|
+
const { cpNodes: _cpNodes, loops: _loops } = cpNodesStringifyable;
|
|
14
|
+
const loops = _loops.map(loopFromStringifyable);
|
|
15
|
+
const loopsByIdx = new Map(loops.map(loop => [loop.idx, loop]));
|
|
16
|
+
|
|
17
|
+
//--------------------------------------------------------------------------
|
|
18
|
+
// First pass: build all CpNode objects with proper `cp`.
|
|
19
|
+
// Edges still hold number ids at this point.
|
|
20
|
+
//--------------------------------------------------------------------------
|
|
21
|
+
const cpNodes: CpNode[] = _cpNodes.map(cpNode_ => {
|
|
22
|
+
const { id, pointOnShape, isHoleClosing, isIntersection } = cpNode_;
|
|
23
|
+
const { circle, order, order2 } = pointOnShape;
|
|
24
|
+
const { curveIdx, loopIdx, p, pDd, t, isSource } = pointOnShape;
|
|
25
|
+
|
|
26
|
+
const curve = loopsByIdx.get(loopIdx)!.curves[curveIdx];
|
|
27
|
+
|
|
28
|
+
const pointOnShape_: PointOnShape = {
|
|
29
|
+
circle,
|
|
30
|
+
curve, p, pDd, t, isSource,
|
|
31
|
+
order, order2
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
...cpNode_,
|
|
36
|
+
id, isHoleClosing, isIntersection,
|
|
37
|
+
pointOnShape: pointOnShape_
|
|
38
|
+
} as CpNode;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
//--------------------------------------------------------------------------
|
|
42
|
+
// Second pass: replace number id edges with real CpNode references.
|
|
43
|
+
//--------------------------------------------------------------------------
|
|
44
|
+
const nodeMap = new Map<number, CpNode>(cpNodes.map(n => [n.id, n]));
|
|
45
|
+
|
|
46
|
+
for (const cpNode of cpNodes) {
|
|
47
|
+
for (const edge of EDGES) {
|
|
48
|
+
const id = cpNode[edge] as unknown as number | undefined;
|
|
49
|
+
if (id === undefined) { continue; }
|
|
50
|
+
|
|
51
|
+
// @ts-ignore
|
|
52
|
+
cpNode[edge] = nodeMap.get(id)!;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//--------------------------------------------------------------------------
|
|
57
|
+
// Third pass: one shared `Circle` object per on-circle ring, as when the
|
|
58
|
+
// MAT was built (the JSON gave every contact point its own copy).
|
|
59
|
+
//--------------------------------------------------------------------------
|
|
60
|
+
const done = new Set<CpNode>();
|
|
61
|
+
for (const cpNode of cpNodes) {
|
|
62
|
+
if (done.has(cpNode)) { continue; }
|
|
63
|
+
|
|
64
|
+
const { circle } = cpNode.pointOnShape;
|
|
65
|
+
for (const cp of getAllOnCircle(cpNode)) {
|
|
66
|
+
done.add(cp);
|
|
67
|
+
(cp.pointOnShape as Mutable<PointOnShape>).circle = circle;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return cpNodes[0];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
export { fromStringifyable }
|
|
@@ -5,9 +5,9 @@ import { loopToStringifyable } from "./loop-to-stringifyable.js";
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Returns a
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Returns a plain, acyclic representation of the entire MAT the given `CpNode`
|
|
9
|
+
* is part of (the `CpNode` edges replaced by ids and the boundary loops
|
|
10
|
+
* included) suitable for `JSON.stringify`; `fromStringifyable` reverses it.
|
|
11
11
|
*/
|
|
12
12
|
function toStringifyable(
|
|
13
13
|
cpNode: CpNode): CpNodeStringifyable {
|
package/src/debug/debug.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import type { Curve } from 'flo-boolean';
|
|
2
|
+
|
|
1
3
|
|
|
2
4
|
/** @internal */
|
|
3
5
|
interface Debug {
|
|
4
6
|
/** Generated by debug object for later inspection */
|
|
5
|
-
elems:
|
|
7
|
+
elems: Elems;
|
|
6
8
|
timing: Timing;
|
|
7
9
|
|
|
8
10
|
/**
|
|
@@ -14,6 +16,28 @@ interface Debug {
|
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Elements generated during `findMats` for later inspection (only available
|
|
21
|
+
* if debug has been enabled via `enableDebugForMat(true)`).
|
|
22
|
+
*
|
|
23
|
+
* The arrays are reset at the start of each `findMats` call and accumulate
|
|
24
|
+
* over all MATs found in that call, one entry per boundary bezier curve in the
|
|
25
|
+
* order the curves are encountered.
|
|
26
|
+
*/
|
|
27
|
+
interface Elems {
|
|
28
|
+
/** The loose (axis-aligned) bounding box of each boundary bezier curve */
|
|
29
|
+
readonly looseBoundingBoxes: number[][][];
|
|
30
|
+
/** The tight (rotated) bounding box of each boundary bezier curve */
|
|
31
|
+
readonly tightBoundingBoxes: number[][][];
|
|
32
|
+
/** The bounding hull of each boundary bezier curve */
|
|
33
|
+
readonly boundingHulls: number[][][];
|
|
34
|
+
/** The curves whose end point forms a quite sharp corner with the next curve */
|
|
35
|
+
readonly sharpCorners: Curve[];
|
|
36
|
+
/** The curves whose end point forms a quite dull corner with the next curve */
|
|
37
|
+
readonly dullCorners: Curve[];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
17
41
|
/** @internal */
|
|
18
42
|
interface Timing {
|
|
19
43
|
holeClosers: number;
|
|
@@ -35,18 +59,31 @@ interface Directives {
|
|
|
35
59
|
}
|
|
36
60
|
|
|
37
61
|
|
|
62
|
+
/** Returns a fresh (empty) set of debug `Elems`. */
|
|
63
|
+
function createEmptyElems(): Elems {
|
|
64
|
+
return {
|
|
65
|
+
looseBoundingBoxes: [],
|
|
66
|
+
tightBoundingBoxes: [],
|
|
67
|
+
boundingHulls: [],
|
|
68
|
+
sharpCorners: [],
|
|
69
|
+
dullCorners: []
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
38
74
|
function enableDebugForMat(debugOn: boolean) {
|
|
39
75
|
if (!debugOn) {
|
|
40
|
-
(
|
|
76
|
+
(globalThis as any)._debug_ = undefined;
|
|
41
77
|
return;
|
|
42
78
|
}
|
|
43
79
|
|
|
44
|
-
let debug: Debug = (
|
|
80
|
+
let debug: Debug = (globalThis as any)._debug_;
|
|
45
81
|
|
|
46
82
|
debug = {
|
|
47
83
|
...debug,
|
|
48
84
|
elems: {
|
|
49
|
-
...debug?.elems
|
|
85
|
+
...debug?.elems,
|
|
86
|
+
...createEmptyElems()
|
|
50
87
|
},
|
|
51
88
|
timing: {
|
|
52
89
|
...debug?.timing,
|
|
@@ -71,10 +108,9 @@ function enableDebugForMat(debugOn: boolean) {
|
|
|
71
108
|
}
|
|
72
109
|
};
|
|
73
110
|
|
|
74
|
-
(
|
|
111
|
+
(globalThis as any)._debug_ = debug;
|
|
75
112
|
}
|
|
76
113
|
|
|
77
114
|
|
|
78
|
-
export type { Debug, Timing, Directives }
|
|
79
|
-
export { enableDebugForMat }
|
|
80
|
-
|
|
115
|
+
export type { Debug, Elems, Timing, Directives }
|
|
116
|
+
export { enableDebugForMat, createEmptyElems }
|