flo-mat 3.0.5 → 3.0.7
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__/cp-node/fs/add-distance-from.spec.ts +7 -0
- package/__tests__/cp-node/fs/check-jsog-eql-calc.spec.ts +30 -0
- package/__tests__/cp-node/fs/clone.spec.ts +7 -0
- package/__tests__/cp-node/fs/cp-nodes-to-boundary-beziers.spec.ts +7 -0
- package/__tests__/cp-node/fs/create-cp-node.spec.ts +7 -0
- package/__tests__/cp-node/fs/enhance-cp-node.spec.ts +7 -0
- package/__tests__/cp-node/fs/find-first.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-all-between.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-all-on-circle.spec.ts +92 -0
- package/__tests__/cp-node/fs/get-all-on-loop.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-all-vertices.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-angle-between-mat-curves.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-avg-speed.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-boundary-bezier-parts-to-next.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-boundary-beziers-between.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-boundary-beziers-to-next.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-boundary-distance-to-next.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-branch-beziers.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-branch.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-children.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-cp-node-ordering.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-distance-between.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-distance-to-next.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-edge-direction.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-first-exit.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-hole-closers.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-implied-boundary-bezier-between.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-mat-curve-between.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-mat-curve-to-next.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-mat-curves-between.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-non-terminating-on-circle.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-prong-count.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-real-prong-count.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-salience.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-smoothed-speed.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-smoothed.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-speed.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-terminating-on-circle.spec.ts +7 -0
- package/__tests__/cp-node/fs/get-vertex-forward-children.spec.ts +7 -0
- package/__tests__/cp-node/fs/insert-cp-node.spec.ts +7 -0
- package/__tests__/cp-node/fs/is-fully-terminating.spec.ts +7 -0
- package/__tests__/cp-node/fs/is-on-same-circle.spec.ts +7 -0
- package/__tests__/cp-node/fs/is-one-prong.spec.ts +7 -0
- package/__tests__/cp-node/fs/is-order-correct.spec.ts +7 -0
- package/__tests__/cp-node/fs/is-sharp.spec.ts +7 -0
- package/__tests__/cp-node/fs/is-single-3-prong.spec.ts +7 -0
- package/__tests__/cp-node/fs/is-special.spec.ts +7 -0
- package/__tests__/cp-node/fs/is-terminating.spec.ts +7 -0
- package/__tests__/cp-node/fs/is-trivial.spec.ts +7 -0
- package/__tests__/cp-node/fs/is-two-prong.spec.ts +7 -0
- package/__tests__/cp-node/fs/is-vertex-special.spec.ts +7 -0
- package/__tests__/cp-node/fs/is-vertex.spec.ts +7 -0
- package/__tests__/cp-node/fs/iterate-all-on-loop.spec.ts +7 -0
- package/__tests__/cp-node/fs/mat-dummys.ts +6716 -0
- package/__tests__/cp-node/fs/remove-cp-node.spec.ts +7 -0
- package/__tests__/cp-node/fs/traverse-all-forward.spec.ts +7 -0
- package/__tests__/cp-node/fs/traverse-cp.spec.ts +7 -0
- package/__tests__/cp-node/fs/traverse-edges.spec.ts +7 -0
- package/__tests__/cp-node/fs/traverse-vertices.spec.ts +7 -0
- package/__tests__/lib-load.spec.ts +9 -10
- package/browser/index.js +247 -189
- package/browser/index.min.js +1 -1
- package/jest.config.cjs +32 -0
- package/node/corner/get-interface-ccw.js +0 -1
- package/node/corner/get-interface-ccw.js.map +1 -1
- package/node/cp-node/cp-node-fs.d.ts +32 -32
- package/node/cp-node/cp-node-fs.js +32 -32
- package/node/cp-node/cp-node.d.ts +13 -21
- package/node/cp-node/fs/clone.d.ts +3 -3
- package/node/cp-node/fs/clone.js +3 -3
- package/node/cp-node/fs/enhance-cp-node.d.ts +1 -5
- package/node/cp-node/fs/enhance-cp-node.js.map +1 -1
- package/node/cp-node/fs/get-all-between.d.ts +3 -3
- package/node/cp-node/fs/get-all-between.js +3 -3
- package/node/cp-node/fs/get-all-between.js.map +1 -1
- package/node/cp-node/fs/get-all-on-circle.d.ts +7 -1
- package/node/cp-node/fs/get-all-on-circle.js +11 -7
- package/node/cp-node/fs/get-all-on-circle.js.map +1 -1
- package/node/cp-node/fs/get-all-on-loop.d.ts +1 -1
- package/node/cp-node/fs/get-all-on-loop.js.map +1 -1
- package/node/cp-node/fs/get-boundary-bezier-parts-to-next.d.ts +12 -3
- package/node/cp-node/fs/get-boundary-bezier-parts-to-next.js +22 -7
- package/node/cp-node/fs/get-boundary-bezier-parts-to-next.js.map +1 -1
- package/node/cp-node/fs/get-boundary-beziers-between.d.ts +1 -1
- package/node/cp-node/fs/get-boundary-beziers-between.js.map +1 -1
- package/node/cp-node/fs/get-boundary-beziers-to-next.js.map +1 -1
- package/node/cp-node/fs/insert-cp-node.d.ts +3 -1
- package/node/cp-node/fs/insert-cp-node.js +12 -2
- package/node/cp-node/fs/insert-cp-node.js.map +1 -1
- package/node/cp-node/fs/is-fully-terminating.d.ts +7 -0
- package/node/cp-node/fs/is-fully-terminating.js +7 -0
- package/node/cp-node/fs/is-fully-terminating.js.map +1 -1
- package/node/cp-node/fs/is-terminating.d.ts +1 -1
- package/node/cp-node/fs/remove-cp-node.d.ts +3 -4
- package/node/cp-node/fs/remove-cp-node.js +3 -1
- package/node/cp-node/fs/remove-cp-node.js.map +1 -1
- package/node/curve/curve.d.ts +18 -11
- package/node/find-2-prong/add-1-prong.js +1 -1
- package/node/find-2-prong/add-1-prong.js.map +1 -1
- package/node/find-2-prong/add-2-prong.js +9 -7
- package/node/find-2-prong/add-2-prong.js.map +1 -1
- package/node/find-2-prong/calc-seperation-tolerance.d.ts +8 -1
- package/node/find-2-prong/calc-seperation-tolerance.js +73 -59
- package/node/find-2-prong/calc-seperation-tolerance.js.map +1 -1
- package/node/find-2-prong/find-2-prong.js +2 -2
- package/node/find-2-prong/find-2-prong.js.map +1 -1
- package/node/find-2-prong/get-initial-bezier-pieces.d.ts +2 -3
- package/node/find-2-prong/get-initial-bezier-pieces.js +4 -1
- package/node/find-2-prong/get-initial-bezier-pieces.js.map +1 -1
- package/node/find-3-prong.ts/find-and-add-3-prong.js +1 -1
- package/node/find-3-prong.ts/find-and-add-3-prong.js.map +1 -1
- package/node/find-3-prong.ts/find-and-add-3-prongs-on-loop.d.ts +2 -2
- package/node/find-3-prong.ts/find-and-add-3-prongs-on-loop.js +8 -3
- package/node/find-3-prong.ts/find-and-add-3-prongs-on-loop.js.map +1 -1
- package/node/find-mat/create-initial-cp-tree.d.ts +7 -3
- package/node/find-mat/create-initial-cp-tree.js +7 -5
- package/node/find-mat/create-initial-cp-tree.js.map +1 -1
- package/node/find-mat/find-mat.d.ts +2 -1
- package/node/find-mat/find-mat.js +10 -4
- package/node/find-mat/find-mat.js.map +1 -1
- package/node/find-mat/get-meta.d.ts +5 -2
- package/node/find-mat/get-meta.js +15 -14
- package/node/find-mat/get-meta.js.map +1 -1
- package/node/index.d.ts +0 -1
- package/node/index.js +1 -1
- package/node/index.js.map +1 -1
- package/node/mat/add-to-cp-tree.d.ts +5 -6
- package/node/mat/add-to-cp-tree.js +5 -2
- package/node/mat/add-to-cp-tree.js.map +1 -1
- package/node/mat/get-branches.d.ts +7 -0
- package/node/mat/get-branches.js +7 -0
- package/node/mat/get-branches.js.map +1 -1
- package/node/mat/mat-meta.d.ts +8 -1
- package/node/mat/mat.d.ts +3 -3
- package/node/mat/simplify-mat.js +1 -1
- package/node/mat/simplify-mat.js.map +1 -1
- package/node/point-on-shape/point-on-shape.d.ts +1 -1
- package/node/vertex/remove-vertex.d.ts +3 -4
- package/node/vertex/remove-vertex.js +3 -2
- package/node/vertex/remove-vertex.js.map +1 -1
- package/package.json +10 -7
- package/src/corner/get-interface-ccw.ts +0 -1
- package/src/cp-node/cp-node-fs.ts +43 -43
- package/src/cp-node/cp-node.ts +27 -39
- package/src/cp-node/fs/clone.ts +3 -3
- package/src/cp-node/fs/enhance-cp-node.ts +0 -1
- package/src/cp-node/fs/get-all-between.ts +31 -28
- package/src/cp-node/fs/get-all-on-circle.ts +13 -8
- package/src/cp-node/fs/get-all-on-loop.ts +12 -10
- package/src/cp-node/fs/get-boundary-bezier-parts-to-next.ts +39 -22
- package/src/cp-node/fs/get-boundary-beziers-between.ts +6 -2
- package/src/cp-node/fs/get-boundary-beziers-to-next.ts +6 -4
- package/src/cp-node/fs/insert-cp-node.ts +13 -2
- package/src/cp-node/fs/is-fully-terminating.ts +7 -0
- package/src/cp-node/fs/is-terminating.ts +1 -1
- package/src/cp-node/fs/remove-cp-node.ts +8 -4
- package/src/curve/curve.ts +19 -13
- package/src/debug/functions/check-ordering.ts +7 -3
- package/src/find-2-prong/add-1-prong.ts +1 -1
- package/src/find-2-prong/add-2-prong.ts +79 -74
- package/src/find-2-prong/calc-seperation-tolerance.ts +88 -78
- package/src/find-2-prong/find-2-prong.ts +2 -2
- package/src/find-2-prong/get-initial-bezier-pieces.ts +5 -1
- package/src/find-3-prong.ts/add-3-prong.ts +73 -70
- package/src/find-3-prong.ts/find-and-add-3-prong.ts +1 -1
- package/src/find-3-prong.ts/find-and-add-3-prongs-on-loop.ts +9 -8
- package/src/find-mat/create-initial-cp-tree.ts +10 -6
- package/src/find-mat/find-mat.ts +12 -5
- package/src/find-mat/get-meta.ts +30 -20
- package/src/get-curve/get-curve-between.ts +2 -2
- package/src/index.ts +1 -1
- package/src/mat/add-to-cp-tree.ts +18 -9
- package/src/mat/get-branches.ts +35 -28
- package/src/mat/mat-meta.ts +6 -1
- package/src/mat/mat.ts +3 -3
- package/src/mat/simplify-mat.ts +1 -1
- package/src/point-on-shape/compare-poss.ts +3 -3
- package/src/point-on-shape/get-osculating-circle.ts +1 -1
- package/src/point-on-shape/is-pos-dull-corner.ts +1 -1
- package/src/point-on-shape/point-on-shape.ts +1 -1
- package/src/point-on-shape/pos-to-human-string.ts +1 -1
- package/src/sat/to-scale-axis.ts +1 -1
- package/src/vertex/remove-vertex.ts +7 -5
- package/.mocharc.cjs +0 -17
- package/src/debug/functions/draw-elem/branch.ts +0 -26
- package/src/find-mat/create-initial-cp-graph.ts +0 -59
package/browser/index.js
CHANGED
|
@@ -566,6 +566,7 @@ function parseNumber(source) {
|
|
|
566
566
|
}
|
|
567
567
|
// Read the decimals.
|
|
568
568
|
if (ci < source._endIndex && source._string[ci] === ".") {
|
|
569
|
+
source._currentIndex += 1;
|
|
569
570
|
ci += 1;
|
|
570
571
|
if (ci >= source._endIndex ||
|
|
571
572
|
source._string[ci] < "0" ||
|
|
@@ -6104,7 +6105,6 @@ function compareCurvaturesAtInterface(psI, psO) {
|
|
|
6104
6105
|
|
|
6105
6106
|
;// ./src/corner/get-interface-ccw.ts
|
|
6106
6107
|
|
|
6107
|
-
// import { dot } from "flo-vector2d";
|
|
6108
6108
|
|
|
6109
6109
|
/**
|
|
6110
6110
|
* Returns a positive value if the second bezier (of order 1, 2 or 3) curves
|
|
@@ -6415,16 +6415,20 @@ const getMatCurveToNext$ = memoize(getMatCurveToNext);
|
|
|
6415
6415
|
|
|
6416
6416
|
|
|
6417
6417
|
;// ./src/cp-node/fs/get-all-on-circle.ts
|
|
6418
|
+
/**
|
|
6419
|
+
* Returns all the `CpNode`s on the same circle.
|
|
6420
|
+
*
|
|
6421
|
+
* @param cpNode
|
|
6422
|
+
* @param exclThis
|
|
6423
|
+
*/
|
|
6418
6424
|
function getAllOnCircle(cpNode, exclThis = false) {
|
|
6419
6425
|
const startCpNode = cpNode;
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6424
|
-
cpNodes.push(cpNode_);
|
|
6425
|
-
}
|
|
6426
|
+
const cpNodes = exclThis ? [] : [cpNode];
|
|
6427
|
+
let cpNode_ = cpNode.nextOnCircle;
|
|
6428
|
+
while (cpNode_ !== startCpNode) {
|
|
6429
|
+
cpNodes.push(cpNode_);
|
|
6426
6430
|
cpNode_ = cpNode_.nextOnCircle;
|
|
6427
|
-
}
|
|
6431
|
+
}
|
|
6428
6432
|
return cpNodes;
|
|
6429
6433
|
}
|
|
6430
6434
|
|
|
@@ -6527,6 +6531,13 @@ function memoizePrimitive(f) {
|
|
|
6527
6531
|
;// ./src/cp-node/fs/is-fully-terminating.ts
|
|
6528
6532
|
|
|
6529
6533
|
|
|
6534
|
+
/**
|
|
6535
|
+
* Returns `true` if this `CpNode` is fully terminating, meaning that all
|
|
6536
|
+
* `CpNode`s (except `CpNode.prevOnCircle`) on the same circle are terminating,
|
|
6537
|
+
* `false` otherwise.
|
|
6538
|
+
*
|
|
6539
|
+
* @param cpNode
|
|
6540
|
+
*/
|
|
6530
6541
|
function isFullyTerminating(cpNode) {
|
|
6531
6542
|
const otherOnCircle = getAllOnCircle(cpNode.prevOnCircle, true);
|
|
6532
6543
|
return otherOnCircle.every(isTerminating);
|
|
@@ -6749,9 +6760,9 @@ function traverseVertices(cpStart, traverseVerticesCallback) {
|
|
|
6749
6760
|
/** @internal */
|
|
6750
6761
|
const EDGES = ['prev', 'next', 'prevOnCircle', 'nextOnCircle'];
|
|
6751
6762
|
/**
|
|
6752
|
-
* Returns a deep clone of this
|
|
6753
|
-
* since cloning a single
|
|
6754
|
-
*
|
|
6763
|
+
* Returns a deep clone of this `CpNode`. Can be used to copy the MAT
|
|
6764
|
+
* since cloning a single `CpNode` necessarily implies cloning all
|
|
6765
|
+
* `CpNode`s on the same MAT tree.
|
|
6755
6766
|
*/
|
|
6756
6767
|
function clone(cpNode) {
|
|
6757
6768
|
// Don't change this function to be recursive, the call stack may
|
|
@@ -6790,6 +6801,15 @@ function cloneWithoutLinks(cpNode) {
|
|
|
6790
6801
|
|
|
6791
6802
|
|
|
6792
6803
|
;// ./src/cp-node/fs/get-boundary-bezier-parts-to-next.ts
|
|
6804
|
+
/**
|
|
6805
|
+
* Returns the boundary beziers pieces between this `CpNode` and the next
|
|
6806
|
+
* one.
|
|
6807
|
+
*
|
|
6808
|
+
* * returns `undefined` if the next `CpNode` is on a different loop,
|
|
6809
|
+
* as this is a hole-closer and there are no boundary beziers between them.
|
|
6810
|
+
*
|
|
6811
|
+
* @param cpNode
|
|
6812
|
+
*/
|
|
6793
6813
|
function getBoundaryBezierPartsToNext(cpNode) {
|
|
6794
6814
|
const cpThis = cpNode;
|
|
6795
6815
|
const cpNext = cpNode.next;
|
|
@@ -6802,28 +6822,34 @@ function getBoundaryBezierPartsToNext(cpNode) {
|
|
|
6802
6822
|
// CpNode.
|
|
6803
6823
|
return undefined;
|
|
6804
6824
|
}
|
|
6805
|
-
const
|
|
6825
|
+
const bezierPieces = [];
|
|
6806
6826
|
if (curveNext === curveThis) {
|
|
6807
|
-
|
|
6827
|
+
bezierPieces.push({
|
|
6828
|
+
ps: posThis.curve.ps,
|
|
6829
|
+
ts: [posThis.t, posNext.t]
|
|
6830
|
+
});
|
|
6808
6831
|
}
|
|
6809
6832
|
else {
|
|
6810
|
-
|
|
6811
|
-
|
|
6833
|
+
bezierPieces.push({
|
|
6834
|
+
ps: posThis.curve.ps,
|
|
6835
|
+
ts: [posThis.t, 1]
|
|
6836
|
+
});
|
|
6837
|
+
addSkippedBeziers(bezierPieces, posThis.curve, posNext.curve, posNext.t);
|
|
6812
6838
|
}
|
|
6813
|
-
return
|
|
6839
|
+
return bezierPieces;
|
|
6814
6840
|
}
|
|
6815
6841
|
/**
|
|
6816
6842
|
* @internal
|
|
6817
6843
|
* Adds pieces of skipped beziers.
|
|
6818
6844
|
*/
|
|
6819
|
-
function addSkippedBeziers(
|
|
6845
|
+
function addSkippedBeziers(bezierPieces, curveStart, curveEnd, t1) {
|
|
6820
6846
|
let curveThis = curveStart;
|
|
6821
6847
|
do {
|
|
6822
6848
|
curveThis = curveThis.next;
|
|
6823
6849
|
const bezierPart = curveThis === curveEnd
|
|
6824
6850
|
? { ps: curveThis.ps, ts: [0, t1] }
|
|
6825
6851
|
: { ps: curveThis.ps, ts: [0, 1] };
|
|
6826
|
-
|
|
6852
|
+
bezierPieces.push(bezierPart);
|
|
6827
6853
|
} while (curveThis !== curveEnd);
|
|
6828
6854
|
}
|
|
6829
6855
|
|
|
@@ -6870,7 +6896,9 @@ function get_boundary_beziers_to_next_addSkippedBeziers(beziers, curveStart, cur
|
|
|
6870
6896
|
|
|
6871
6897
|
|
|
6872
6898
|
;// ./src/cp-node/fs/remove-cp-node.ts
|
|
6873
|
-
function removeCpNode(cpNode,
|
|
6899
|
+
function removeCpNode(cpNode, meta) {
|
|
6900
|
+
// cpTrees: Map<Loop, LlRbTree<CpNode>>): void {
|
|
6901
|
+
const { cpTrees } = meta;
|
|
6874
6902
|
const prev = cpNode.prev;
|
|
6875
6903
|
const next = cpNode.next;
|
|
6876
6904
|
prev.next = next;
|
|
@@ -6884,12 +6912,13 @@ function removeCpNode(cpNode, cpTrees) {
|
|
|
6884
6912
|
|
|
6885
6913
|
|
|
6886
6914
|
|
|
6887
|
-
function removeVertex(cpNode,
|
|
6915
|
+
function removeVertex(cpNode, meta) {
|
|
6916
|
+
// cpTrees: Map<Loop, LlRbTree<CpNode>>): void {
|
|
6888
6917
|
const prongCount = getProngCount(cpNode);
|
|
6889
6918
|
if (prongCount !== 2) {
|
|
6890
6919
|
throw new Error(`Cannot delete \`CpNode\` on ${prongCount}-prong`);
|
|
6891
6920
|
}
|
|
6892
|
-
getAllOnCircle(cpNode).forEach(cpNode => removeCpNode(cpNode,
|
|
6921
|
+
getAllOnCircle(cpNode).forEach(cpNode => removeCpNode(cpNode, meta));
|
|
6893
6922
|
}
|
|
6894
6923
|
|
|
6895
6924
|
|
|
@@ -7019,13 +7048,13 @@ function cpNodesToBoundaryBeziers(cpNodes) {
|
|
|
7019
7048
|
|
|
7020
7049
|
;// ./src/cp-node/fs/get-all-between.ts
|
|
7021
7050
|
/**
|
|
7022
|
-
* Returns all `CpNode`s between the two given ones (
|
|
7051
|
+
* Returns all `CpNode`s between the two given ones (excluding the last one).
|
|
7023
7052
|
*
|
|
7024
7053
|
* * If the second `CpNode` is never encountered all on the loop will be
|
|
7025
7054
|
* returned.
|
|
7026
7055
|
*
|
|
7027
|
-
* @param cpNodeS
|
|
7028
|
-
* @param cpNodeE
|
|
7056
|
+
* @param cpNodeS start `CpNode`
|
|
7057
|
+
* @param cpNodeE end `CpNode`
|
|
7029
7058
|
* @param inclAllIfEqual if `true` and first and last `CpNode`s are equal then
|
|
7030
7059
|
* include all `CpNode`s around the loop, otherwise include none.
|
|
7031
7060
|
*/
|
|
@@ -7186,7 +7215,7 @@ function getAllVertices(cpNode) {
|
|
|
7186
7215
|
const cpNodeComparator = (a, b) => compareCps(a.cp, b.cp);
|
|
7187
7216
|
const CpNodeFs = {
|
|
7188
7217
|
/**
|
|
7189
|
-
* Returns the children of this
|
|
7218
|
+
* Returns the children of this `CpNode` when seen as a MAT edge. Only
|
|
7190
7219
|
* children in a 'forward' direction are returned. These include all edges
|
|
7191
7220
|
* except the 'backward' edge given by [[prevOnCircle]], even terminating
|
|
7192
7221
|
* edges.
|
|
@@ -7194,7 +7223,7 @@ const CpNodeFs = {
|
|
|
7194
7223
|
getChildren: getChildren,
|
|
7195
7224
|
/**
|
|
7196
7225
|
* Similar to [[getChildren]] but returns the child nodes of the tree when
|
|
7197
|
-
*
|
|
7226
|
+
* `CpNode` is seen as a MAT vertex point (as opposed to edge). In this
|
|
7198
7227
|
* way the dual graph of the tree can easily be traversed - see e.g.
|
|
7199
7228
|
* [[traverseVertices]]. Generally, however, traversing the edges is
|
|
7200
7229
|
* preferred as it returns the entire Medial Axis (by utilizing
|
|
@@ -7202,7 +7231,7 @@ const CpNodeFs = {
|
|
|
7202
7231
|
*/
|
|
7203
7232
|
getVertexForwardChildren: getVertexForwardChildren,
|
|
7204
7233
|
/**
|
|
7205
|
-
* Returns all
|
|
7234
|
+
* Returns all `CpNode`s on the MAT that this `CpNode` is part of
|
|
7206
7235
|
* starting from the current one and going anti-clockwise around the shape.
|
|
7207
7236
|
*/
|
|
7208
7237
|
getAllOnLoop: getAllOnLoop,
|
|
@@ -7210,18 +7239,18 @@ const CpNodeFs = {
|
|
|
7210
7239
|
* Return this (except if exclThis is truthy) and the the other CpNodes
|
|
7211
7240
|
* around the maximal disk vertex circle in an anti-clockwise order.
|
|
7212
7241
|
* @param exclThis If true the returned array does not include this
|
|
7213
|
-
*
|
|
7242
|
+
* `CpNode`.
|
|
7214
7243
|
*/
|
|
7215
7244
|
getAllOnCircle: getAllOnCircle,
|
|
7216
7245
|
/**
|
|
7217
|
-
* Returns true if the 2 given
|
|
7246
|
+
* Returns true if the 2 given `CpNode`s are on the same maximal disk
|
|
7218
7247
|
* circle.
|
|
7219
|
-
* @param cpNode1 A
|
|
7220
|
-
* @param cpNode2 Another
|
|
7248
|
+
* @param cpNode1 A `CpNode`.
|
|
7249
|
+
* @param cpNode2 Another `CpNode`
|
|
7221
7250
|
*/
|
|
7222
7251
|
isOnSameCircle: isOnSameCircle,
|
|
7223
7252
|
/**
|
|
7224
|
-
* Returns true if this
|
|
7253
|
+
* Returns true if this `CpNode` is terminating, i.e. implies a leaf MAT
|
|
7225
7254
|
* vertex.
|
|
7226
7255
|
*
|
|
7227
7256
|
* This is always the case for sharp corners and maximal disks with
|
|
@@ -7229,7 +7258,7 @@ const CpNodeFs = {
|
|
|
7229
7258
|
* two contact points stored (sitting 'on top' of each other) for the
|
|
7230
7259
|
* maximal disk. It can be seen as a limiting case of a two-prong where the
|
|
7231
7260
|
* distance between two of the contact points tend to zero. One point
|
|
7232
|
-
* (represented by a
|
|
7261
|
+
* (represented by a `CpNode` of course) will be terminating with the
|
|
7233
7262
|
* other point being its [[next]], whereas the other point will *not* be
|
|
7234
7263
|
* terminating and 'points' back into the shape.
|
|
7235
7264
|
*/
|
|
@@ -7240,30 +7269,30 @@ const CpNodeFs = {
|
|
|
7240
7269
|
*/
|
|
7241
7270
|
isFullyTerminating: isFullyTerminating,
|
|
7242
7271
|
/**
|
|
7243
|
-
* Returns the first
|
|
7272
|
+
* Returns the first `CpNode` (from this one by successively applying
|
|
7244
7273
|
* .nextOnCircle) that exits the circle.
|
|
7245
7274
|
*/
|
|
7246
7275
|
getFirstExit: getFirstExit,
|
|
7247
7276
|
/**
|
|
7248
|
-
* Returns true if this
|
|
7277
|
+
* Returns true if this `CpNode` represents a sharp corner, i.e. the
|
|
7249
7278
|
* limiting case of a two-prong having zero radius.
|
|
7250
7279
|
*
|
|
7251
|
-
* Note that two
|
|
7280
|
+
* Note that two `CpNode`s are stored for each sharp corner, one being
|
|
7252
7281
|
* terminating and one not. See [[isTerminating]] for more details.
|
|
7253
7282
|
*/
|
|
7254
7283
|
isSharp: isSharp,
|
|
7255
7284
|
/**
|
|
7256
|
-
* Returns true if this
|
|
7285
|
+
* Returns true if this `CpNode`'s maximal disk has only one contact point
|
|
7257
7286
|
* on the shape boundary (up to planar coordinates). These includes sharp
|
|
7258
7287
|
* corners.
|
|
7259
7288
|
*
|
|
7260
|
-
* Note, however, that two
|
|
7289
|
+
* Note, however, that two `CpNode`s are stored for each such point to
|
|
7261
7290
|
* preserve symmetry - see [[isTerminating]] for more details.
|
|
7262
7291
|
*/
|
|
7263
7292
|
isOneProng: isOneProng,
|
|
7264
7293
|
/**
|
|
7265
7294
|
* Returns the number of contact points on the maximal disk circle implied
|
|
7266
|
-
* by this
|
|
7295
|
+
* by this `CpNode`.
|
|
7267
7296
|
*
|
|
7268
7297
|
* Note, however, that even one-prongs and sharp corners will return 2 (see
|
|
7269
7298
|
* [[isTerminating]] for more details); if this is not desired use
|
|
@@ -7272,7 +7301,7 @@ const CpNodeFs = {
|
|
|
7272
7301
|
getProngCount: getProngCount,
|
|
7273
7302
|
/**
|
|
7274
7303
|
* Returns the number of contact points (up to planar coordinates) on the
|
|
7275
|
-
* maximal disk circle implied by this
|
|
7304
|
+
* maximal disk circle implied by this `CpNode`.
|
|
7276
7305
|
*
|
|
7277
7306
|
* See also [[getProngCount]].
|
|
7278
7307
|
*/
|
|
@@ -7280,8 +7309,8 @@ const CpNodeFs = {
|
|
|
7280
7309
|
/**
|
|
7281
7310
|
* Primarily for internal use.
|
|
7282
7311
|
*
|
|
7283
|
-
* Compares the order of two
|
|
7284
|
-
* on a
|
|
7312
|
+
* Compares the order of two `CpNode`s. The order is cyclic and depends
|
|
7313
|
+
* on a `CpNode`'s relative position along the shape boundary.
|
|
7285
7314
|
*/
|
|
7286
7315
|
cpNodeComparator,
|
|
7287
7316
|
/**
|
|
@@ -7301,26 +7330,26 @@ const CpNodeFs = {
|
|
|
7301
7330
|
traverseCp: traverseCp,
|
|
7302
7331
|
/**
|
|
7303
7332
|
* Traverses all edges (depth first) of the given MAT tree starting at the given
|
|
7304
|
-
* vertex (represented by a
|
|
7305
|
-
* @param cpNode Any
|
|
7333
|
+
* vertex (represented by a `CpNode`).
|
|
7334
|
+
* @param cpNode Any `CpNode` representing the start vertex.
|
|
7306
7335
|
* @param traverseEdgesCallback A callback function for each CpNode representing the vertex at the
|
|
7307
7336
|
* start of an edge.
|
|
7308
7337
|
*/
|
|
7309
7338
|
traverseEdges: traverseEdges,
|
|
7310
7339
|
/**
|
|
7311
7340
|
* Traverses the MAT tree and calls the given callback function for each vertex
|
|
7312
|
-
* (represented by a
|
|
7341
|
+
* (represented by a `CpNode`) on the MAT.
|
|
7313
7342
|
*
|
|
7314
7343
|
* It is usually preferable to use [[traverseEdges]] as it allows for the
|
|
7315
7344
|
* traversal of all the smooth curves representing the MAT.
|
|
7316
|
-
* @param cpNode Any
|
|
7317
|
-
* @param traverseVerticesCallback A callback function taking a single
|
|
7345
|
+
* @param cpNode Any `CpNode` representing the start vertex.
|
|
7346
|
+
* @param traverseVerticesCallback A callback function taking a single `CpNode` as parameter.
|
|
7318
7347
|
*/
|
|
7319
7348
|
traverseVertices: traverseVertices,
|
|
7320
7349
|
/**
|
|
7321
|
-
* Returns a deep clone of this
|
|
7322
|
-
* since cloning a single
|
|
7323
|
-
*
|
|
7350
|
+
* Returns a deep clone of this `CpNode`. Can be used to copy the MAT
|
|
7351
|
+
* since cloning a single `CpNode` necessarily implies cloning all
|
|
7352
|
+
* `CpNode`s on the same MAT tree.
|
|
7324
7353
|
*/
|
|
7325
7354
|
clone: clone,
|
|
7326
7355
|
/**
|
|
@@ -7337,13 +7366,13 @@ const CpNodeFs = {
|
|
|
7337
7366
|
getBoundaryBeziersToNext: getBoundaryBeziersToNext,
|
|
7338
7367
|
/**
|
|
7339
7368
|
* Removes a cpNode from the MAT.
|
|
7340
|
-
* @param cpTree The tree graph holding the
|
|
7341
|
-
* @param cpNode The
|
|
7369
|
+
* @param cpTree The tree graph holding the `CpNodes` of the MAT.
|
|
7370
|
+
* @param cpNode The `CpNode` to remove.
|
|
7342
7371
|
*/
|
|
7343
7372
|
removeVertex: removeVertex,
|
|
7344
7373
|
/**
|
|
7345
|
-
* Returns the bezier curve from the maximal disk of the given
|
|
7346
|
-
* next
|
|
7374
|
+
* Returns the bezier curve from the maximal disk of the given `CpNode` to the
|
|
7375
|
+
* next `CpNode`'s maximal disk and thus directly represents a piece of the
|
|
7347
7376
|
* medial axis.
|
|
7348
7377
|
* @param cpNode
|
|
7349
7378
|
*/
|
|
@@ -7353,8 +7382,8 @@ const CpNodeFs = {
|
|
|
7353
7382
|
getBranchBeziers: getBranchBeziers,
|
|
7354
7383
|
getSalience: getSalience,
|
|
7355
7384
|
/**
|
|
7356
|
-
* Returns the bezier curve from the maximal disk of one
|
|
7357
|
-
*
|
|
7385
|
+
* Returns the bezier curve from the maximal disk of one `CpNode` to another
|
|
7386
|
+
* `CpNode`'s maximal disk.
|
|
7358
7387
|
* @param cpNodeFrom
|
|
7359
7388
|
* @param cpNodeTo
|
|
7360
7389
|
*/
|
|
@@ -11042,37 +11071,10 @@ function getBoundingBox(ps) {
|
|
|
11042
11071
|
}
|
|
11043
11072
|
|
|
11044
11073
|
//# sourceMappingURL=get-bounding-box.js.map
|
|
11045
|
-
;// ./node_modules/flo-boolean/node_modules/flo-memoize/node/memoize.js
|
|
11046
|
-
/**
|
|
11047
|
-
* Memoize (by reference on the input parameter) the given arity 1 function.
|
|
11048
|
-
*
|
|
11049
|
-
* * the input parameter must be an `object` (so it can be used as a key to
|
|
11050
|
-
* `WeakMap` and thus garbage collected later; this is especially important
|
|
11051
|
-
* in functional programming where a lot of garbage collection takes place;
|
|
11052
|
-
*
|
|
11053
|
-
* * use `memoizePrimitive` instead if it is not important that the keys
|
|
11054
|
-
* will *never* be garbage collected
|
|
11055
|
-
*/
|
|
11056
|
-
function memoize_memoize(f) {
|
|
11057
|
-
const results = new WeakMap();
|
|
11058
|
-
return function (t) {
|
|
11059
|
-
let r = results.get(t);
|
|
11060
|
-
if (r !== undefined) {
|
|
11061
|
-
//console.log('cache hit');
|
|
11062
|
-
return r;
|
|
11063
|
-
}
|
|
11064
|
-
//console.log('cache miss');
|
|
11065
|
-
r = f(t);
|
|
11066
|
-
results.set(t, r);
|
|
11067
|
-
return r;
|
|
11068
|
-
};
|
|
11069
|
-
}
|
|
11070
|
-
|
|
11071
|
-
//# sourceMappingURL=memoize.js.map
|
|
11072
11074
|
;// ./node_modules/flo-boolean/node/get-bounding-box-.js
|
|
11073
11075
|
|
|
11074
11076
|
|
|
11075
|
-
const getBoundingBox$ =
|
|
11077
|
+
const getBoundingBox$ = memoize(getBoundingBox);
|
|
11076
11078
|
|
|
11077
11079
|
//# sourceMappingURL=get-bounding-box-.js.map
|
|
11078
11080
|
;// ./node_modules/flo-bezier3/node/global-properties/bounds/get-bounds.js
|
|
@@ -11146,7 +11148,7 @@ function getBounds(ps) {
|
|
|
11146
11148
|
;// ./node_modules/flo-boolean/node/get-bounds-.js
|
|
11147
11149
|
|
|
11148
11150
|
|
|
11149
|
-
const getBounds$ =
|
|
11151
|
+
const getBounds$ = memoize(getBounds);
|
|
11150
11152
|
|
|
11151
11153
|
//# sourceMappingURL=get-bounds-.js.map
|
|
11152
11154
|
;// ./node_modules/flo-boolean/node/calc-paths/get-shape-bounds.js
|
|
@@ -18797,6 +18799,7 @@ function getInOutsViaSides(container, ioIdx) {
|
|
|
18797
18799
|
//# sourceMappingURL=get-in-outs-via-sides.js.map
|
|
18798
18800
|
;// ./node_modules/flo-boolean/node/containers/get-container-in-outs/get-container-in-outs.js
|
|
18799
18801
|
|
|
18802
|
+
// import { getInOutsViaCrossing } from "./get-in-outs-via-crossing/get-in-outs-via-crossing.js";
|
|
18800
18803
|
/**
|
|
18801
18804
|
* * **warning** ioIdx will be modified by this function
|
|
18802
18805
|
*
|
|
@@ -22503,7 +22506,7 @@ function getExcessiveCurvatures(expMax, loops) {
|
|
|
22503
22506
|
/**
|
|
22504
22507
|
*
|
|
22505
22508
|
*/
|
|
22506
|
-
const get_min_y_getMinY =
|
|
22509
|
+
const get_min_y_getMinY = memoize(function (loop) {
|
|
22507
22510
|
const { curves } = loop;
|
|
22508
22511
|
let bestY = getYBoundsTight(curves[0].ps).minY;
|
|
22509
22512
|
let bestCurve = curves[0];
|
|
@@ -22683,7 +22686,9 @@ function filterContainers(containers) {
|
|
|
22683
22686
|
|
|
22684
22687
|
|
|
22685
22688
|
|
|
22689
|
+
// import { compareInOut } from './get-container-in-outs/get-in-outs-via-sides/compare-in-out.js';
|
|
22686
22690
|
|
|
22691
|
+
// import { orderInOuts } from './order-in-outs.js';
|
|
22687
22692
|
/**
|
|
22688
22693
|
*
|
|
22689
22694
|
* @param containerDim
|
|
@@ -23301,7 +23306,7 @@ function scrambleLoops(loops, maxBitLength, expMax, mult = 0.02) {
|
|
|
23301
23306
|
* Returns the maximum control point coordinate value (x or y) within any loop.
|
|
23302
23307
|
* @param loops The array of loops
|
|
23303
23308
|
*/
|
|
23304
|
-
const getMaxCoordinate =
|
|
23309
|
+
const getMaxCoordinate = memoize((loops) => {
|
|
23305
23310
|
let max = 0;
|
|
23306
23311
|
for (const loop of loops) {
|
|
23307
23312
|
for (const ps of loop) {
|
|
@@ -24736,6 +24741,13 @@ function getNonTerminatingOnCircle(cpNode, exclThis = false) {
|
|
|
24736
24741
|
;// ./src/mat/get-branches.ts
|
|
24737
24742
|
|
|
24738
24743
|
|
|
24744
|
+
/**
|
|
24745
|
+
* Returns all branches associated with the give cpNode.
|
|
24746
|
+
*
|
|
24747
|
+
* * the final `CpNode` of each branch is not returned to improve symmetry
|
|
24748
|
+
*
|
|
24749
|
+
* @param cpNode `CpNode` representing the start vertex.
|
|
24750
|
+
*/
|
|
24739
24751
|
function getBranches(cpNode) {
|
|
24740
24752
|
const branches = [];
|
|
24741
24753
|
const cpNodeStack = [cpNode];
|
|
@@ -25441,7 +25453,7 @@ function simplifyMat(mat, hausdorffTolerance = 2 ** -3, maxIterations = 50) {
|
|
|
25441
25453
|
for (const cpNode of canDeletes) {
|
|
25442
25454
|
if (!isVertex(cpNode => (getProngCount(cpNode) !== 2) &&
|
|
25443
25455
|
!cpNode.isHoleClosing)(cpNode)) {
|
|
25444
|
-
removeVertex(cpNode, mat.meta
|
|
25456
|
+
removeVertex(cpNode, mat.meta);
|
|
25445
25457
|
}
|
|
25446
25458
|
}
|
|
25447
25459
|
return {
|
|
@@ -26880,7 +26892,7 @@ cpTree, cp, next) {
|
|
|
26880
26892
|
|
|
26881
26893
|
;// ./src/cp-node/fs/insert-cp-node.ts
|
|
26882
26894
|
|
|
26883
|
-
function insertCpNode(insertIfOrderWrong, isHoleClosing, isIntersection, cpTree, cp, _prev) {
|
|
26895
|
+
function insertCpNode(insertIfOrderWrong, isHoleClosing, isIntersection, cpTree, cp, _prev, lastInsertId) {
|
|
26884
26896
|
if (_prev !== undefined &&
|
|
26885
26897
|
!isOrderCorrect(cpTree, cp, _prev.next)) {
|
|
26886
26898
|
// console.log(compareCps(cp,_prev!.next.cp))
|
|
@@ -26888,7 +26900,17 @@ function insertCpNode(insertIfOrderWrong, isHoleClosing, isIntersection, cpTree,
|
|
|
26888
26900
|
return undefined;
|
|
26889
26901
|
}
|
|
26890
26902
|
}
|
|
26891
|
-
const cpNode = {
|
|
26903
|
+
const cpNode = {
|
|
26904
|
+
cp,
|
|
26905
|
+
isHoleClosing,
|
|
26906
|
+
isIntersection,
|
|
26907
|
+
id: lastInsertId.id,
|
|
26908
|
+
next: undefined,
|
|
26909
|
+
prev: undefined,
|
|
26910
|
+
nextOnCircle: undefined,
|
|
26911
|
+
prevOnCircle: undefined
|
|
26912
|
+
};
|
|
26913
|
+
lastInsertId.id++;
|
|
26892
26914
|
const prev = _prev === undefined ? cpNode : _prev;
|
|
26893
26915
|
const next = _prev === undefined ? cpNode : prev.next;
|
|
26894
26916
|
next.prev = cpNode;
|
|
@@ -26938,7 +26960,10 @@ function byAngle(circle) {
|
|
|
26938
26960
|
*
|
|
26939
26961
|
* @internal
|
|
26940
26962
|
*/
|
|
26941
|
-
function addToCpTree(insertIfOrderIsWrong, isHoleClosing, circle, orders,
|
|
26963
|
+
function addToCpTree(insertIfOrderIsWrong, isHoleClosing, circle, orders,
|
|
26964
|
+
// cpTrees: Map<Loop,LlRbTree<CpNode>>,
|
|
26965
|
+
meta, poss, neighbors) {
|
|
26966
|
+
const { cpTrees } = meta;
|
|
26942
26967
|
let anyFailed = false;
|
|
26943
26968
|
const cpNodes = poss.map((pos, i) => {
|
|
26944
26969
|
const order = orders[i];
|
|
@@ -26947,7 +26972,7 @@ function addToCpTree(insertIfOrderIsWrong, isHoleClosing, circle, orders, cpTree
|
|
|
26947
26972
|
const pred = neighbors === undefined
|
|
26948
26973
|
? getCpNodeToLeftOrSame(cpTree, pos, order, 0)
|
|
26949
26974
|
: neighbors[i];
|
|
26950
|
-
const cpNode = insertCpNode(insertIfOrderIsWrong, isHoleClosing, false, cpTree, cp, pred);
|
|
26975
|
+
const cpNode = insertCpNode(insertIfOrderIsWrong, isHoleClosing, false, cpTree, cp, pred, meta.lastInsertId);
|
|
26951
26976
|
if (cpNode === undefined) {
|
|
26952
26977
|
anyFailed = true;
|
|
26953
26978
|
}
|
|
@@ -27051,7 +27076,7 @@ function findAndAdd3Prong(meta, visitedCps) {
|
|
|
27051
27076
|
}
|
|
27052
27077
|
}
|
|
27053
27078
|
const cpNodes = closeBysFor3Prong.length === 0
|
|
27054
|
-
? addToCpTree(true, false, circle, orders, meta
|
|
27079
|
+
? addToCpTree(true, false, circle, orders, meta, poss, δ3s.map(v => v[0])).cpNodes
|
|
27055
27080
|
: [];
|
|
27056
27081
|
return { closeBysFor3Prong, cpNodes: cpNodes };
|
|
27057
27082
|
}
|
|
@@ -27109,6 +27134,9 @@ function findAndAdd3Prongs(meta, cpStart) {
|
|
|
27109
27134
|
|
|
27110
27135
|
|
|
27111
27136
|
|
|
27137
|
+
// import { LlRbTree } from 'flo-ll-rb-tree';
|
|
27138
|
+
// import { Loop } from 'flo-boolean';
|
|
27139
|
+
// import { drawFs } from 'flo-draw';
|
|
27112
27140
|
|
|
27113
27141
|
/**
|
|
27114
27142
|
* @internal
|
|
@@ -27136,7 +27164,7 @@ function findAndAdd3ProngsOnLoop(meta, cpStart) {
|
|
|
27136
27164
|
}
|
|
27137
27165
|
else {
|
|
27138
27166
|
reLoop = true;
|
|
27139
|
-
replaceCloseBys(meta
|
|
27167
|
+
replaceCloseBys(meta, closeBysFor3Prong, cpNodeSet, cpNodeGoodSet);
|
|
27140
27168
|
}
|
|
27141
27169
|
addedCpNodes.forEach(cpNodes => cpNodes.forEach(cpNode => cpNodeGoodSet.add(cpNode)));
|
|
27142
27170
|
}
|
|
@@ -27158,13 +27186,15 @@ function getLastItemOfSet(set) {
|
|
|
27158
27186
|
for (item of set) { }
|
|
27159
27187
|
return item;
|
|
27160
27188
|
}
|
|
27161
|
-
function replaceCloseBys(
|
|
27189
|
+
function replaceCloseBys(
|
|
27190
|
+
// cpTrees: Map<Loop,LlRbTree<CpNode>>,
|
|
27191
|
+
meta, closeBysFor3Prong, cpNodeSet, cpNodeGoodSet) {
|
|
27162
27192
|
for (const closeBy of [closeBysFor3Prong[0]]) {
|
|
27163
27193
|
getAllOnCircle(closeBy).forEach(v => {
|
|
27164
27194
|
cpNodeSet.delete(v);
|
|
27165
27195
|
cpNodeGoodSet.delete(v);
|
|
27166
27196
|
});
|
|
27167
|
-
removeVertex(closeBy,
|
|
27197
|
+
removeVertex(closeBy, meta);
|
|
27168
27198
|
}
|
|
27169
27199
|
}
|
|
27170
27200
|
|
|
@@ -27178,12 +27208,14 @@ const { cpNodeComparator: create_initial_cp_tree_cpNodeComparator } = CpNodeFs;
|
|
|
27178
27208
|
* @internal
|
|
27179
27209
|
* Creates the initial ContactPoint loops from the given sharp corners.
|
|
27180
27210
|
*
|
|
27181
|
-
* * modifies `cpTrees`
|
|
27211
|
+
* * modifies `cpTrees` and `lastInsertId` of `meta`
|
|
27182
27212
|
*
|
|
27183
|
-
* @param
|
|
27213
|
+
* @param loops
|
|
27214
|
+
* @param cpTrees
|
|
27184
27215
|
* @param sharpCornerss
|
|
27216
|
+
* @param lastInsertId
|
|
27185
27217
|
*/
|
|
27186
|
-
function createInitialCpTree(loops, cpTrees, sharpCornerss) {
|
|
27218
|
+
function createInitialCpTree(loops, cpTrees, sharpCornerss, lastInsertId) {
|
|
27187
27219
|
let cpNode;
|
|
27188
27220
|
for (let k = 0; k < sharpCornerss.length; k++) {
|
|
27189
27221
|
const sharpCorners = sharpCornerss[k];
|
|
@@ -27194,8 +27226,8 @@ function createInitialCpTree(loops, cpTrees, sharpCornerss) {
|
|
|
27194
27226
|
const circle = { center: pos.p, radius: 0 };
|
|
27195
27227
|
const cp1 = { pointOnShape: pos, circle, order: -1, order2: 0 };
|
|
27196
27228
|
const cp2 = { pointOnShape: pos, circle, order: +1, order2: 0 };
|
|
27197
|
-
cpNode1 = insertCpNode(true, false, false, cpTree, cp1, cpNode2);
|
|
27198
|
-
cpNode2 = insertCpNode(true, false, false, cpTree, cp2, cpNode1);
|
|
27229
|
+
cpNode1 = insertCpNode(true, false, false, cpTree, cp1, cpNode2, lastInsertId);
|
|
27230
|
+
cpNode2 = insertCpNode(true, false, false, cpTree, cp2, cpNode1, lastInsertId);
|
|
27199
27231
|
cpNode1.prevOnCircle = cpNode2;
|
|
27200
27232
|
cpNode2.prevOnCircle = cpNode1;
|
|
27201
27233
|
cpNode1.nextOnCircle = cpNode2;
|
|
@@ -27268,14 +27300,9 @@ const TriMapFs = {
|
|
|
27268
27300
|
|
|
27269
27301
|
let timingStart;
|
|
27270
27302
|
/** @internal */
|
|
27271
|
-
function
|
|
27303
|
+
function getPointToCpNode(loops, cpTrees) {
|
|
27272
27304
|
timingStart = performance.now();
|
|
27273
27305
|
const pointToCpNode = new Map();
|
|
27274
|
-
const looseBoundingBoxes = [];
|
|
27275
|
-
const tightBoundingBoxes = [];
|
|
27276
|
-
const boundingHulls = [];
|
|
27277
|
-
const sharpCorners = [];
|
|
27278
|
-
const dullCorners = [];
|
|
27279
27306
|
for (const loop of loops) {
|
|
27280
27307
|
// Populate `posMap`
|
|
27281
27308
|
const cpTree = cpTrees.get(loop);
|
|
@@ -27284,7 +27311,18 @@ function getMeta(maxCoordinate, squaredDiagonalLength, loops, cpTrees) {
|
|
|
27284
27311
|
const { p, t } = cpNode.cp.pointOnShape;
|
|
27285
27312
|
TriMapFs.set(pointToCpNode, loop, p[0], p[1], cpNode);
|
|
27286
27313
|
}
|
|
27287
|
-
|
|
27314
|
+
}
|
|
27315
|
+
return pointToCpNode;
|
|
27316
|
+
}
|
|
27317
|
+
/** @internal */
|
|
27318
|
+
function getPartialMeta(loops) {
|
|
27319
|
+
const looseBoundingBoxes = [];
|
|
27320
|
+
const tightBoundingBoxes = [];
|
|
27321
|
+
const boundingHulls = [];
|
|
27322
|
+
const sharpCorners = [];
|
|
27323
|
+
const dullCorners = [];
|
|
27324
|
+
for (const loop of loops) {
|
|
27325
|
+
for (const curve of loop.curves) {
|
|
27288
27326
|
const ps = curve.ps;
|
|
27289
27327
|
const hull = getBoundingHull(ps, true);
|
|
27290
27328
|
boundingHulls.push(hull);
|
|
@@ -27302,16 +27340,11 @@ function getMeta(maxCoordinate, squaredDiagonalLength, loops, cpTrees) {
|
|
|
27302
27340
|
}
|
|
27303
27341
|
}
|
|
27304
27342
|
return {
|
|
27305
|
-
maxCoordinate,
|
|
27306
|
-
squaredDiagonalLength,
|
|
27307
27343
|
looseBoundingBoxes,
|
|
27308
27344
|
tightBoundingBoxes,
|
|
27309
27345
|
boundingHulls,
|
|
27310
27346
|
sharpCorners,
|
|
27311
|
-
dullCorners
|
|
27312
|
-
loops,
|
|
27313
|
-
cpTrees,
|
|
27314
|
-
pointToCpNode
|
|
27347
|
+
dullCorners
|
|
27315
27348
|
};
|
|
27316
27349
|
}
|
|
27317
27350
|
/** @internal */
|
|
@@ -27768,7 +27801,10 @@ function findEquidistantPointOnLineDd(x, y, z) {
|
|
|
27768
27801
|
|
|
27769
27802
|
|
|
27770
27803
|
/** @internal */
|
|
27771
|
-
function getInitialBezierPieces(angle, isHoleClosing, loop, loops,
|
|
27804
|
+
function getInitialBezierPieces(angle, isHoleClosing, loop, loops,
|
|
27805
|
+
// cpTrees: Map<Loop,LlRbTree<CpNode>>,
|
|
27806
|
+
meta, y, circle) {
|
|
27807
|
+
const { cpTrees } = meta;
|
|
27772
27808
|
if (isHoleClosing) {
|
|
27773
27809
|
return loops
|
|
27774
27810
|
.filter(_loop => _loop !== loop)
|
|
@@ -27941,7 +27977,7 @@ function add1Prong(meta, radius, center, pos) {
|
|
|
27941
27977
|
if (getCloseByCpIfExist(meta, pos, circle, order, 0, 1)) {
|
|
27942
27978
|
return;
|
|
27943
27979
|
}
|
|
27944
|
-
const { anyFailed, cpNodes } = addToCpTree(false, false, circle, [-0.5, +0.5], meta
|
|
27980
|
+
const { anyFailed, cpNodes } = addToCpTree(false, false, circle, [-0.5, +0.5], meta, [pos, pos]);
|
|
27945
27981
|
// if (typeof _debug_ !== 'undefined') {
|
|
27946
27982
|
// _debug_.generated.elems.oneProng.push(cpNodes);
|
|
27947
27983
|
// }
|
|
@@ -27968,75 +28004,89 @@ const { asin, acos, cos, sqrt: calc_seperation_tolerance_sqrt, PI: π } = Math;
|
|
|
27968
28004
|
* @param r radius of the MAT circle
|
|
27969
28005
|
* @param θ angle between point...
|
|
27970
28006
|
*/
|
|
27971
|
-
function calcSeperationTolerance2(R, r, δ) {
|
|
27972
|
-
const a = r + δ;
|
|
27973
|
-
if (a >= R) {
|
|
27974
|
-
return Number.POSITIVE_INFINITY;
|
|
27975
|
-
}
|
|
27976
|
-
const b = R - r; //?
|
|
27977
|
-
const c = R; //?
|
|
27978
|
-
const N = c * c - a * a - b * b; //?
|
|
27979
|
-
const N_ = calc_seperation_tolerance_qdq(calc_seperation_tolerance_qdq(calc_seperation_tolerance_tp(c, c), calc_seperation_tolerance_tp(a, a)), calc_seperation_tolerance_tp(b, b));
|
|
27980
|
-
const D = 2 * a * b; //?
|
|
27981
|
-
const D_ = calc_seperation_tolerance_tp(-2 * a, b);
|
|
27982
|
-
const Q = ddDivDd(N_, D_)[1]; //?
|
|
27983
|
-
const cosC = -N / D; //?
|
|
27984
|
-
const C = acos(cosC);
|
|
27985
|
-
const CC = acos(Q);
|
|
27986
|
-
const θ = π - CC; //?
|
|
27987
|
-
return θ;
|
|
27988
|
-
// return r*θ; // approximate arc with line
|
|
27989
|
-
}
|
|
27990
|
-
|
|
27991
|
-
function calc_seperation_tolerance_degToRad(degrees) {
|
|
27992
|
-
return degrees / 360 * 2 * Math.PI;
|
|
27993
|
-
}
|
|
27994
|
-
function radToDeg(rad) {
|
|
27995
|
-
return rad * 360 / 2 / Math.PI;
|
|
27996
|
-
}
|
|
27997
|
-
const R = 699;
|
|
27998
|
-
const r = 698;
|
|
27999
|
-
const δ = 1000 * 2 ** -46; //?
|
|
28000
|
-
calcSeperationTolerance(R, r, δ); //?
|
|
28001
|
-
calcSeperationTolerance2(R, r, δ); //?
|
|
28002
|
-
calcSeperationTolerance3(R, r, δ); //?
|
|
28003
28007
|
function calcSeperationTolerance(R, r, δ) {
|
|
28004
28008
|
const a = r + δ;
|
|
28005
28009
|
if (a >= R) {
|
|
28006
28010
|
return Number.POSITIVE_INFINITY;
|
|
28007
28011
|
}
|
|
28008
|
-
const R_r_ = twoDiff(R, r);
|
|
28009
|
-
const A_ = calc_seperation_tolerance_qmd(r, R_r_);
|
|
28010
|
-
const N_ = calc_seperation_tolerance_qdq(calc_seperation_tolerance_qdq(A_, calc_seperation_tolerance_tp(r, δ)), calc_seperation_tolerance_tp(δ, δ / 2));
|
|
28011
|
-
const D_ = calc_seperation_tolerance_qaq(A_, calc_seperation_tolerance_qmd(δ, R_r_));
|
|
28012
|
-
const R_r = R - r;
|
|
28013
|
-
const A = r * R_r;
|
|
28014
|
-
const N = A - r * δ - (δ * δ) / 2;
|
|
28015
|
-
const D = A + R_r * δ;
|
|
28016
|
-
const cosC = N / D;
|
|
28017
|
-
const Q = ddDivDd(N_, D_)[1];
|
|
28018
|
-
// const Q = N_[1]/D_[1]
|
|
28012
|
+
const R_r_ = twoDiff(R, r);
|
|
28013
|
+
const A_ = calc_seperation_tolerance_qmd(r, R_r_);
|
|
28014
|
+
const N_ = calc_seperation_tolerance_qdq(calc_seperation_tolerance_qdq(A_, calc_seperation_tolerance_tp(r, δ)), calc_seperation_tolerance_tp(δ, δ / 2));
|
|
28015
|
+
const D_ = calc_seperation_tolerance_qaq(A_, calc_seperation_tolerance_qmd(δ, R_r_));
|
|
28016
|
+
const R_r = R - r;
|
|
28017
|
+
const A = r * R_r;
|
|
28018
|
+
const N = A - r * δ - (δ * δ) / 2;
|
|
28019
|
+
const D = A + R_r * δ;
|
|
28020
|
+
const cosC = N / D;
|
|
28021
|
+
const Q = ddDivDd(N_, D_)[1];
|
|
28022
|
+
// const Q = N_[1]/D_[1];
|
|
28019
28023
|
const C = acos(cosC);
|
|
28020
28024
|
const CC = acos(Q);
|
|
28021
|
-
const θ = CC;
|
|
28025
|
+
const θ = CC;
|
|
28022
28026
|
// return r*θ;
|
|
28023
28027
|
return r * θ;
|
|
28024
28028
|
}
|
|
28025
|
-
|
|
28026
|
-
|
|
28027
|
-
|
|
28028
|
-
|
|
28029
|
-
|
|
28030
|
-
|
|
28031
|
-
|
|
28032
|
-
|
|
28033
|
-
|
|
28034
|
-
|
|
28035
|
-
|
|
28036
|
-
|
|
28037
|
-
|
|
28038
|
-
|
|
28039
|
-
|
|
28029
|
+
|
|
28030
|
+
// Quokka tests
|
|
28031
|
+
// /**
|
|
28032
|
+
// * Calculates and returns an appropriate seperation tolerance between `CpNode`s.
|
|
28033
|
+
// *
|
|
28034
|
+
// * @param R radius of the circle implied by the curvature at the boundary
|
|
28035
|
+
// * @param r radius of the MAT circle
|
|
28036
|
+
// * @param θ angle between point...
|
|
28037
|
+
// */
|
|
28038
|
+
// function calcSeperationTolerance2(
|
|
28039
|
+
// R: number,
|
|
28040
|
+
// r: number,
|
|
28041
|
+
// δ: number) {
|
|
28042
|
+
// const a = r + δ;
|
|
28043
|
+
// if (a >= R) {
|
|
28044
|
+
// return Number.POSITIVE_INFINITY;
|
|
28045
|
+
// }
|
|
28046
|
+
// const b = R - r;
|
|
28047
|
+
// const c = R;
|
|
28048
|
+
// const N = c*c - a*a - b*b;
|
|
28049
|
+
// const N_ = qdq(qdq(tp(c,c), tp(a,a)), tp(b,b));
|
|
28050
|
+
// const D = 2*a*b;
|
|
28051
|
+
// const D_ = tp(-2*a,b);
|
|
28052
|
+
// const Q = ddDivDd(N_,D_)[1];
|
|
28053
|
+
// const cosC = -N/D;
|
|
28054
|
+
// const C = acos(cosC);
|
|
28055
|
+
// const CC = acos(Q);
|
|
28056
|
+
// const θ = π - CC;
|
|
28057
|
+
// return θ;
|
|
28058
|
+
// // return r*θ; // approximate arc with line
|
|
28059
|
+
// }
|
|
28060
|
+
// function degToRad(degrees: number) {
|
|
28061
|
+
// return degrees/360*2*Math.PI;
|
|
28062
|
+
// }
|
|
28063
|
+
// function radToDeg(rad: number) {
|
|
28064
|
+
// return rad*360/2/Math.PI;
|
|
28065
|
+
// }
|
|
28066
|
+
// const R = 699;
|
|
28067
|
+
// const r = 698;
|
|
28068
|
+
// const δ = 1000*2**-46;
|
|
28069
|
+
// calcSeperationTolerance(R,r,δ);
|
|
28070
|
+
// calcSeperationTolerance2(R,r,δ);
|
|
28071
|
+
// calcSeperationTolerance3(R,r,δ);
|
|
28072
|
+
// // * see https://en.wikipedia.org/wiki/Law_of_cosines, Version suited to small angles
|
|
28073
|
+
// function calcSeperationTolerance3(
|
|
28074
|
+
// R: number,
|
|
28075
|
+
// r: number,
|
|
28076
|
+
// δ: number) {
|
|
28077
|
+
// const a = r + δ;
|
|
28078
|
+
// const c = R - r;
|
|
28079
|
+
// const b = R;
|
|
28080
|
+
// // c² = (a - b)² + 4ab*sin²(θ/2) OR
|
|
28081
|
+
// // (c² - (a - b)²)/4ab = sin²(θ/2)
|
|
28082
|
+
// const cc = c*c;
|
|
28083
|
+
// const abc = a*a + b*b - 2*a*b;
|
|
28084
|
+
// const A = cc - abc;
|
|
28085
|
+
// const B = sqrt(A/(4*a*b));
|
|
28086
|
+
// const θ = 2*asin(B);
|
|
28087
|
+
// return θ;
|
|
28088
|
+
// // return r*θ; // approximate arc with line
|
|
28089
|
+
// }
|
|
28040
28090
|
|
|
28041
28091
|
;// ./src/find-2-prong/find-2-prong.ts
|
|
28042
28092
|
|
|
@@ -28075,7 +28125,7 @@ const { ceil: find_2_prong_ceil, log2: find_2_prong_log2, max: find_2_prong_max,
|
|
|
28075
28125
|
* @param loopIdx The loop array index
|
|
28076
28126
|
*/
|
|
28077
28127
|
function find2Prong(meta, isHoleClosing, for1Prong, angle, y) {
|
|
28078
|
-
const { loops, maxCoordinate, squaredDiagonalLength
|
|
28128
|
+
const { loops, maxCoordinate, squaredDiagonalLength } = meta;
|
|
28079
28129
|
const loop = y.curve.loop;
|
|
28080
28130
|
const MAX_ITERATIONS = 25;
|
|
28081
28131
|
const minSquaredSeperationTolerance = ((2 ** -21) * maxCoordinate) ** 2;
|
|
@@ -28088,7 +28138,7 @@ function find2Prong(meta, isHoleClosing, for1Prong, angle, y) {
|
|
|
28088
28138
|
const p = y.p;
|
|
28089
28139
|
// The boundary piece that should contain the other point of
|
|
28090
28140
|
// the 2-prong circle. (Defined by start and end points).
|
|
28091
|
-
let bezierPieces = getInitialBezierPieces(angle, isHoleClosing, loop, loops,
|
|
28141
|
+
let bezierPieces = getInitialBezierPieces(angle, isHoleClosing, loop, loops, meta, y, { center: xO, radius: rO });
|
|
28092
28142
|
// console.log(bezierPieces.length);
|
|
28093
28143
|
/** The center of the two-prong (successively refined) */
|
|
28094
28144
|
let x = xO;
|
|
@@ -28214,7 +28264,6 @@ function getO(angle, isHoleClosing, maxOsculatingCircleRadius, minCurvature, y)
|
|
|
28214
28264
|
* tolerances.
|
|
28215
28265
|
*/
|
|
28216
28266
|
function add2Prong(meta, circle, poss, isHoleClosing) {
|
|
28217
|
-
const { cpTrees } = meta;
|
|
28218
28267
|
poss[0] = poss[0].t === 0
|
|
28219
28268
|
? createPos(poss[0].curve.prev, 1, true)
|
|
28220
28269
|
: poss[0];
|
|
@@ -28226,11 +28275,11 @@ function add2Prong(meta, circle, poss, isHoleClosing) {
|
|
|
28226
28275
|
return undefined;
|
|
28227
28276
|
}
|
|
28228
28277
|
}
|
|
28229
|
-
const { anyFailed, cpNodes } = addToCpTree(isHoleClosing, isHoleClosing, circle, orders,
|
|
28278
|
+
const { anyFailed, cpNodes } = addToCpTree(isHoleClosing, isHoleClosing, circle, orders, meta, poss);
|
|
28230
28279
|
if (anyFailed) {
|
|
28231
28280
|
cpNodes.forEach(cpNode => {
|
|
28232
28281
|
if (cpNode !== undefined) {
|
|
28233
|
-
removeCpNode(cpNode,
|
|
28282
|
+
removeCpNode(cpNode, meta);
|
|
28234
28283
|
}
|
|
28235
28284
|
});
|
|
28236
28285
|
return undefined;
|
|
@@ -28238,17 +28287,20 @@ function add2Prong(meta, circle, poss, isHoleClosing) {
|
|
|
28238
28287
|
// Get points ordered according to their angle with the x-axis
|
|
28239
28288
|
// joinSpokes(circle, cpNodes);
|
|
28240
28289
|
if (isHoleClosing) {
|
|
28241
|
-
closeHole(
|
|
28290
|
+
closeHole(meta, cpNodes);
|
|
28242
28291
|
}
|
|
28243
28292
|
return cpNodes[0]; // return the source `CpNode`
|
|
28244
28293
|
}
|
|
28245
|
-
function closeHole(
|
|
28294
|
+
function closeHole(meta,
|
|
28295
|
+
// cpTrees: Map<Loop, LlRbTree<CpNode>>,
|
|
28296
|
+
cpNodes) {
|
|
28297
|
+
const { cpTrees } = meta;
|
|
28246
28298
|
const [cpNodeA, cpNodeB] = cpNodes;
|
|
28247
28299
|
// Duplicate ContactPoints
|
|
28248
28300
|
// const antipodeCpNode = cpNodeB[0];
|
|
28249
28301
|
const cpAntipode = cpNodeB.cp;
|
|
28250
|
-
const cpNodeB2 = insertCpNode(true, true, false, cpTrees.get(cpAntipode.pointOnShape.curve.loop), { ...cpAntipode, order2: +1 }, cpNodeB);
|
|
28251
|
-
const cpNodeB1 = insertCpNode(true, true, false, cpTrees.get(cpNodeA.cp.pointOnShape.curve.loop), { ...cpNodeA.cp, order2: -1 }, cpNodeA.prev);
|
|
28302
|
+
const cpNodeB2 = insertCpNode(true, true, false, cpTrees.get(cpAntipode.pointOnShape.curve.loop), { ...cpAntipode, order2: +1 }, cpNodeB, meta.lastInsertId);
|
|
28303
|
+
const cpNodeB1 = insertCpNode(true, true, false, cpTrees.get(cpNodeA.cp.pointOnShape.curve.loop), { ...cpNodeA.cp, order2: -1 }, cpNodeA.prev, meta.lastInsertId);
|
|
28252
28304
|
// Connect graph
|
|
28253
28305
|
cpNodeB1.prevOnCircle = cpNodeB2;
|
|
28254
28306
|
cpNodeB1.nextOnCircle = cpNodeB2;
|
|
@@ -28991,12 +29043,18 @@ function findMat(loops, maxCoordinate, options) {
|
|
|
28991
29043
|
const getFor2ProngsOnLoop_ = getFor2ProngsOnLoop(minBezLength, maxCurviness, maxLength);
|
|
28992
29044
|
const getFor1ProngsOnLoop_ = getFor1ProngsOnLoop(minBezLength);
|
|
28993
29045
|
const sharpCornersPerLoop = loops.map(getSharpCornersOnLoop_);
|
|
28994
|
-
const cpTrees = new Map();
|
|
28995
|
-
createInitialCpTree(loops, cpTrees, sharpCornersPerLoop);
|
|
28996
29046
|
const bounds = get_shape_bounds_getShapeBounds(loops);
|
|
28997
29047
|
const squaredDiagonalLength = (bounds.maxX.p[0] - bounds.minX.p[0]) ** 2 +
|
|
28998
29048
|
(bounds.maxY.p[1] - bounds.minY.p[1]) ** 2;
|
|
28999
|
-
const
|
|
29049
|
+
const cpTrees = new Map();
|
|
29050
|
+
const lastInsertId = { id: 0 };
|
|
29051
|
+
createInitialCpTree(loops, cpTrees, sharpCornersPerLoop, lastInsertId);
|
|
29052
|
+
const _meta = getPartialMeta(loops);
|
|
29053
|
+
const pointToCpNode = getPointToCpNode(loops, cpTrees);
|
|
29054
|
+
const meta = {
|
|
29055
|
+
maxCoordinate, squaredDiagonalLength, loops, cpTrees, pointToCpNode,
|
|
29056
|
+
lastInsertId, ..._meta
|
|
29057
|
+
};
|
|
29000
29058
|
let cpNode;
|
|
29001
29059
|
cpNode = findAndAddHoleClosing2Prongs(meta);
|
|
29002
29060
|
if (typeof _debug_ !== 'undefined') {
|
|
@@ -30672,7 +30730,7 @@ function holeCloserNext(pairs, holeCloser) {
|
|
|
30672
30730
|
|
|
30673
30731
|
|
|
30674
30732
|
|
|
30733
|
+
// export { getMeta } from './find-mat/get-meta.js';
|
|
30675
30734
|
|
|
30676
30735
|
|
|
30677
|
-
|
|
30678
|
-
export { CpNodeFs, beziersToSvgPathStr, connectHoleClosers, createInitialCpTree, createPos, debugElemNames, drawBeziersAsSinglePath, drawBranch, drawElemFs, drawElemFsDetailed, drawMat, emptyDebugElems, enableDebugForMat, find2Prong, findAndAdd2Prong, findAndAddHoleClosing2Prongs, findMats, floydWarshall, getBoundaryBeziersToNext, getBoundaryPieceBeziers, getBranches, getCloseBoundaryPointsCertified, getClosestSquareDistanceToRect, getFor2ProngsOnLoop, getGraph, getImpliedBoundaryBezierBetween, getMeta, getPathsFromStr, getPotentialClosestPointsOnCurveCertified, getSatCulls, get_shape_bounds_getShapeBounds as getShapeBounds, getSharpCornersOnLoop, isVertexSpecial, loopFromBeziers, simplifyMat, sweep_line_sweepLine as sweepLine, toScaleAxis, trimMat };
|
|
30736
|
+
export { CpNodeFs, beziersToSvgPathStr, connectHoleClosers, createInitialCpTree, createPos, debugElemNames, drawBeziersAsSinglePath, drawBranch, drawElemFs, drawElemFsDetailed, drawMat, emptyDebugElems, enableDebugForMat, find2Prong, findAndAdd2Prong, findAndAddHoleClosing2Prongs, findMats, floydWarshall, getBoundaryBeziersToNext, getBoundaryPieceBeziers, getBranches, getCloseBoundaryPointsCertified, getClosestSquareDistanceToRect, getFor2ProngsOnLoop, getGraph, getImpliedBoundaryBezierBetween, getPathsFromStr, getPotentialClosestPointsOnCurveCertified, getSatCulls, get_shape_bounds_getShapeBounds as getShapeBounds, getSharpCornersOnLoop, isVertexSpecial, loopFromBeziers, simplifyMat, sweep_line_sweepLine as sweepLine, toScaleAxis, trimMat };
|