flo-mat 3.0.6 → 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 +239 -158
- 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 +9 -6
- 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/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
|
@@ -6105,7 +6105,6 @@ function compareCurvaturesAtInterface(psI, psO) {
|
|
|
6105
6105
|
|
|
6106
6106
|
;// ./src/corner/get-interface-ccw.ts
|
|
6107
6107
|
|
|
6108
|
-
// import { dot } from "flo-vector2d";
|
|
6109
6108
|
|
|
6110
6109
|
/**
|
|
6111
6110
|
* Returns a positive value if the second bezier (of order 1, 2 or 3) curves
|
|
@@ -6416,16 +6415,20 @@ const getMatCurveToNext$ = memoize(getMatCurveToNext);
|
|
|
6416
6415
|
|
|
6417
6416
|
|
|
6418
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
|
+
*/
|
|
6419
6424
|
function getAllOnCircle(cpNode, exclThis = false) {
|
|
6420
6425
|
const startCpNode = cpNode;
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
cpNodes.push(cpNode_);
|
|
6426
|
-
}
|
|
6426
|
+
const cpNodes = exclThis ? [] : [cpNode];
|
|
6427
|
+
let cpNode_ = cpNode.nextOnCircle;
|
|
6428
|
+
while (cpNode_ !== startCpNode) {
|
|
6429
|
+
cpNodes.push(cpNode_);
|
|
6427
6430
|
cpNode_ = cpNode_.nextOnCircle;
|
|
6428
|
-
}
|
|
6431
|
+
}
|
|
6429
6432
|
return cpNodes;
|
|
6430
6433
|
}
|
|
6431
6434
|
|
|
@@ -6528,6 +6531,13 @@ function memoizePrimitive(f) {
|
|
|
6528
6531
|
;// ./src/cp-node/fs/is-fully-terminating.ts
|
|
6529
6532
|
|
|
6530
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
|
+
*/
|
|
6531
6541
|
function isFullyTerminating(cpNode) {
|
|
6532
6542
|
const otherOnCircle = getAllOnCircle(cpNode.prevOnCircle, true);
|
|
6533
6543
|
return otherOnCircle.every(isTerminating);
|
|
@@ -6750,9 +6760,9 @@ function traverseVertices(cpStart, traverseVerticesCallback) {
|
|
|
6750
6760
|
/** @internal */
|
|
6751
6761
|
const EDGES = ['prev', 'next', 'prevOnCircle', 'nextOnCircle'];
|
|
6752
6762
|
/**
|
|
6753
|
-
* Returns a deep clone of this
|
|
6754
|
-
* since cloning a single
|
|
6755
|
-
*
|
|
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.
|
|
6756
6766
|
*/
|
|
6757
6767
|
function clone(cpNode) {
|
|
6758
6768
|
// Don't change this function to be recursive, the call stack may
|
|
@@ -6791,6 +6801,15 @@ function cloneWithoutLinks(cpNode) {
|
|
|
6791
6801
|
|
|
6792
6802
|
|
|
6793
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
|
+
*/
|
|
6794
6813
|
function getBoundaryBezierPartsToNext(cpNode) {
|
|
6795
6814
|
const cpThis = cpNode;
|
|
6796
6815
|
const cpNext = cpNode.next;
|
|
@@ -6803,28 +6822,34 @@ function getBoundaryBezierPartsToNext(cpNode) {
|
|
|
6803
6822
|
// CpNode.
|
|
6804
6823
|
return undefined;
|
|
6805
6824
|
}
|
|
6806
|
-
const
|
|
6825
|
+
const bezierPieces = [];
|
|
6807
6826
|
if (curveNext === curveThis) {
|
|
6808
|
-
|
|
6827
|
+
bezierPieces.push({
|
|
6828
|
+
ps: posThis.curve.ps,
|
|
6829
|
+
ts: [posThis.t, posNext.t]
|
|
6830
|
+
});
|
|
6809
6831
|
}
|
|
6810
6832
|
else {
|
|
6811
|
-
|
|
6812
|
-
|
|
6833
|
+
bezierPieces.push({
|
|
6834
|
+
ps: posThis.curve.ps,
|
|
6835
|
+
ts: [posThis.t, 1]
|
|
6836
|
+
});
|
|
6837
|
+
addSkippedBeziers(bezierPieces, posThis.curve, posNext.curve, posNext.t);
|
|
6813
6838
|
}
|
|
6814
|
-
return
|
|
6839
|
+
return bezierPieces;
|
|
6815
6840
|
}
|
|
6816
6841
|
/**
|
|
6817
6842
|
* @internal
|
|
6818
6843
|
* Adds pieces of skipped beziers.
|
|
6819
6844
|
*/
|
|
6820
|
-
function addSkippedBeziers(
|
|
6845
|
+
function addSkippedBeziers(bezierPieces, curveStart, curveEnd, t1) {
|
|
6821
6846
|
let curveThis = curveStart;
|
|
6822
6847
|
do {
|
|
6823
6848
|
curveThis = curveThis.next;
|
|
6824
6849
|
const bezierPart = curveThis === curveEnd
|
|
6825
6850
|
? { ps: curveThis.ps, ts: [0, t1] }
|
|
6826
6851
|
: { ps: curveThis.ps, ts: [0, 1] };
|
|
6827
|
-
|
|
6852
|
+
bezierPieces.push(bezierPart);
|
|
6828
6853
|
} while (curveThis !== curveEnd);
|
|
6829
6854
|
}
|
|
6830
6855
|
|
|
@@ -6871,7 +6896,9 @@ function get_boundary_beziers_to_next_addSkippedBeziers(beziers, curveStart, cur
|
|
|
6871
6896
|
|
|
6872
6897
|
|
|
6873
6898
|
;// ./src/cp-node/fs/remove-cp-node.ts
|
|
6874
|
-
function removeCpNode(cpNode,
|
|
6899
|
+
function removeCpNode(cpNode, meta) {
|
|
6900
|
+
// cpTrees: Map<Loop, LlRbTree<CpNode>>): void {
|
|
6901
|
+
const { cpTrees } = meta;
|
|
6875
6902
|
const prev = cpNode.prev;
|
|
6876
6903
|
const next = cpNode.next;
|
|
6877
6904
|
prev.next = next;
|
|
@@ -6885,12 +6912,13 @@ function removeCpNode(cpNode, cpTrees) {
|
|
|
6885
6912
|
|
|
6886
6913
|
|
|
6887
6914
|
|
|
6888
|
-
function removeVertex(cpNode,
|
|
6915
|
+
function removeVertex(cpNode, meta) {
|
|
6916
|
+
// cpTrees: Map<Loop, LlRbTree<CpNode>>): void {
|
|
6889
6917
|
const prongCount = getProngCount(cpNode);
|
|
6890
6918
|
if (prongCount !== 2) {
|
|
6891
6919
|
throw new Error(`Cannot delete \`CpNode\` on ${prongCount}-prong`);
|
|
6892
6920
|
}
|
|
6893
|
-
getAllOnCircle(cpNode).forEach(cpNode => removeCpNode(cpNode,
|
|
6921
|
+
getAllOnCircle(cpNode).forEach(cpNode => removeCpNode(cpNode, meta));
|
|
6894
6922
|
}
|
|
6895
6923
|
|
|
6896
6924
|
|
|
@@ -7020,13 +7048,13 @@ function cpNodesToBoundaryBeziers(cpNodes) {
|
|
|
7020
7048
|
|
|
7021
7049
|
;// ./src/cp-node/fs/get-all-between.ts
|
|
7022
7050
|
/**
|
|
7023
|
-
* Returns all `CpNode`s between the two given ones (
|
|
7051
|
+
* Returns all `CpNode`s between the two given ones (excluding the last one).
|
|
7024
7052
|
*
|
|
7025
7053
|
* * If the second `CpNode` is never encountered all on the loop will be
|
|
7026
7054
|
* returned.
|
|
7027
7055
|
*
|
|
7028
|
-
* @param cpNodeS
|
|
7029
|
-
* @param cpNodeE
|
|
7056
|
+
* @param cpNodeS start `CpNode`
|
|
7057
|
+
* @param cpNodeE end `CpNode`
|
|
7030
7058
|
* @param inclAllIfEqual if `true` and first and last `CpNode`s are equal then
|
|
7031
7059
|
* include all `CpNode`s around the loop, otherwise include none.
|
|
7032
7060
|
*/
|
|
@@ -7187,7 +7215,7 @@ function getAllVertices(cpNode) {
|
|
|
7187
7215
|
const cpNodeComparator = (a, b) => compareCps(a.cp, b.cp);
|
|
7188
7216
|
const CpNodeFs = {
|
|
7189
7217
|
/**
|
|
7190
|
-
* Returns the children of this
|
|
7218
|
+
* Returns the children of this `CpNode` when seen as a MAT edge. Only
|
|
7191
7219
|
* children in a 'forward' direction are returned. These include all edges
|
|
7192
7220
|
* except the 'backward' edge given by [[prevOnCircle]], even terminating
|
|
7193
7221
|
* edges.
|
|
@@ -7195,7 +7223,7 @@ const CpNodeFs = {
|
|
|
7195
7223
|
getChildren: getChildren,
|
|
7196
7224
|
/**
|
|
7197
7225
|
* Similar to [[getChildren]] but returns the child nodes of the tree when
|
|
7198
|
-
*
|
|
7226
|
+
* `CpNode` is seen as a MAT vertex point (as opposed to edge). In this
|
|
7199
7227
|
* way the dual graph of the tree can easily be traversed - see e.g.
|
|
7200
7228
|
* [[traverseVertices]]. Generally, however, traversing the edges is
|
|
7201
7229
|
* preferred as it returns the entire Medial Axis (by utilizing
|
|
@@ -7203,7 +7231,7 @@ const CpNodeFs = {
|
|
|
7203
7231
|
*/
|
|
7204
7232
|
getVertexForwardChildren: getVertexForwardChildren,
|
|
7205
7233
|
/**
|
|
7206
|
-
* Returns all
|
|
7234
|
+
* Returns all `CpNode`s on the MAT that this `CpNode` is part of
|
|
7207
7235
|
* starting from the current one and going anti-clockwise around the shape.
|
|
7208
7236
|
*/
|
|
7209
7237
|
getAllOnLoop: getAllOnLoop,
|
|
@@ -7211,18 +7239,18 @@ const CpNodeFs = {
|
|
|
7211
7239
|
* Return this (except if exclThis is truthy) and the the other CpNodes
|
|
7212
7240
|
* around the maximal disk vertex circle in an anti-clockwise order.
|
|
7213
7241
|
* @param exclThis If true the returned array does not include this
|
|
7214
|
-
*
|
|
7242
|
+
* `CpNode`.
|
|
7215
7243
|
*/
|
|
7216
7244
|
getAllOnCircle: getAllOnCircle,
|
|
7217
7245
|
/**
|
|
7218
|
-
* Returns true if the 2 given
|
|
7246
|
+
* Returns true if the 2 given `CpNode`s are on the same maximal disk
|
|
7219
7247
|
* circle.
|
|
7220
|
-
* @param cpNode1 A
|
|
7221
|
-
* @param cpNode2 Another
|
|
7248
|
+
* @param cpNode1 A `CpNode`.
|
|
7249
|
+
* @param cpNode2 Another `CpNode`
|
|
7222
7250
|
*/
|
|
7223
7251
|
isOnSameCircle: isOnSameCircle,
|
|
7224
7252
|
/**
|
|
7225
|
-
* Returns true if this
|
|
7253
|
+
* Returns true if this `CpNode` is terminating, i.e. implies a leaf MAT
|
|
7226
7254
|
* vertex.
|
|
7227
7255
|
*
|
|
7228
7256
|
* This is always the case for sharp corners and maximal disks with
|
|
@@ -7230,7 +7258,7 @@ const CpNodeFs = {
|
|
|
7230
7258
|
* two contact points stored (sitting 'on top' of each other) for the
|
|
7231
7259
|
* maximal disk. It can be seen as a limiting case of a two-prong where the
|
|
7232
7260
|
* distance between two of the contact points tend to zero. One point
|
|
7233
|
-
* (represented by a
|
|
7261
|
+
* (represented by a `CpNode` of course) will be terminating with the
|
|
7234
7262
|
* other point being its [[next]], whereas the other point will *not* be
|
|
7235
7263
|
* terminating and 'points' back into the shape.
|
|
7236
7264
|
*/
|
|
@@ -7241,30 +7269,30 @@ const CpNodeFs = {
|
|
|
7241
7269
|
*/
|
|
7242
7270
|
isFullyTerminating: isFullyTerminating,
|
|
7243
7271
|
/**
|
|
7244
|
-
* Returns the first
|
|
7272
|
+
* Returns the first `CpNode` (from this one by successively applying
|
|
7245
7273
|
* .nextOnCircle) that exits the circle.
|
|
7246
7274
|
*/
|
|
7247
7275
|
getFirstExit: getFirstExit,
|
|
7248
7276
|
/**
|
|
7249
|
-
* Returns true if this
|
|
7277
|
+
* Returns true if this `CpNode` represents a sharp corner, i.e. the
|
|
7250
7278
|
* limiting case of a two-prong having zero radius.
|
|
7251
7279
|
*
|
|
7252
|
-
* Note that two
|
|
7280
|
+
* Note that two `CpNode`s are stored for each sharp corner, one being
|
|
7253
7281
|
* terminating and one not. See [[isTerminating]] for more details.
|
|
7254
7282
|
*/
|
|
7255
7283
|
isSharp: isSharp,
|
|
7256
7284
|
/**
|
|
7257
|
-
* Returns true if this
|
|
7285
|
+
* Returns true if this `CpNode`'s maximal disk has only one contact point
|
|
7258
7286
|
* on the shape boundary (up to planar coordinates). These includes sharp
|
|
7259
7287
|
* corners.
|
|
7260
7288
|
*
|
|
7261
|
-
* Note, however, that two
|
|
7289
|
+
* Note, however, that two `CpNode`s are stored for each such point to
|
|
7262
7290
|
* preserve symmetry - see [[isTerminating]] for more details.
|
|
7263
7291
|
*/
|
|
7264
7292
|
isOneProng: isOneProng,
|
|
7265
7293
|
/**
|
|
7266
7294
|
* Returns the number of contact points on the maximal disk circle implied
|
|
7267
|
-
* by this
|
|
7295
|
+
* by this `CpNode`.
|
|
7268
7296
|
*
|
|
7269
7297
|
* Note, however, that even one-prongs and sharp corners will return 2 (see
|
|
7270
7298
|
* [[isTerminating]] for more details); if this is not desired use
|
|
@@ -7273,7 +7301,7 @@ const CpNodeFs = {
|
|
|
7273
7301
|
getProngCount: getProngCount,
|
|
7274
7302
|
/**
|
|
7275
7303
|
* Returns the number of contact points (up to planar coordinates) on the
|
|
7276
|
-
* maximal disk circle implied by this
|
|
7304
|
+
* maximal disk circle implied by this `CpNode`.
|
|
7277
7305
|
*
|
|
7278
7306
|
* See also [[getProngCount]].
|
|
7279
7307
|
*/
|
|
@@ -7281,8 +7309,8 @@ const CpNodeFs = {
|
|
|
7281
7309
|
/**
|
|
7282
7310
|
* Primarily for internal use.
|
|
7283
7311
|
*
|
|
7284
|
-
* Compares the order of two
|
|
7285
|
-
* 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.
|
|
7286
7314
|
*/
|
|
7287
7315
|
cpNodeComparator,
|
|
7288
7316
|
/**
|
|
@@ -7302,26 +7330,26 @@ const CpNodeFs = {
|
|
|
7302
7330
|
traverseCp: traverseCp,
|
|
7303
7331
|
/**
|
|
7304
7332
|
* Traverses all edges (depth first) of the given MAT tree starting at the given
|
|
7305
|
-
* vertex (represented by a
|
|
7306
|
-
* @param cpNode Any
|
|
7333
|
+
* vertex (represented by a `CpNode`).
|
|
7334
|
+
* @param cpNode Any `CpNode` representing the start vertex.
|
|
7307
7335
|
* @param traverseEdgesCallback A callback function for each CpNode representing the vertex at the
|
|
7308
7336
|
* start of an edge.
|
|
7309
7337
|
*/
|
|
7310
7338
|
traverseEdges: traverseEdges,
|
|
7311
7339
|
/**
|
|
7312
7340
|
* Traverses the MAT tree and calls the given callback function for each vertex
|
|
7313
|
-
* (represented by a
|
|
7341
|
+
* (represented by a `CpNode`) on the MAT.
|
|
7314
7342
|
*
|
|
7315
7343
|
* It is usually preferable to use [[traverseEdges]] as it allows for the
|
|
7316
7344
|
* traversal of all the smooth curves representing the MAT.
|
|
7317
|
-
* @param cpNode Any
|
|
7318
|
-
* @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.
|
|
7319
7347
|
*/
|
|
7320
7348
|
traverseVertices: traverseVertices,
|
|
7321
7349
|
/**
|
|
7322
|
-
* Returns a deep clone of this
|
|
7323
|
-
* since cloning a single
|
|
7324
|
-
*
|
|
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.
|
|
7325
7353
|
*/
|
|
7326
7354
|
clone: clone,
|
|
7327
7355
|
/**
|
|
@@ -7338,13 +7366,13 @@ const CpNodeFs = {
|
|
|
7338
7366
|
getBoundaryBeziersToNext: getBoundaryBeziersToNext,
|
|
7339
7367
|
/**
|
|
7340
7368
|
* Removes a cpNode from the MAT.
|
|
7341
|
-
* @param cpTree The tree graph holding the
|
|
7342
|
-
* @param cpNode The
|
|
7369
|
+
* @param cpTree The tree graph holding the `CpNodes` of the MAT.
|
|
7370
|
+
* @param cpNode The `CpNode` to remove.
|
|
7343
7371
|
*/
|
|
7344
7372
|
removeVertex: removeVertex,
|
|
7345
7373
|
/**
|
|
7346
|
-
* Returns the bezier curve from the maximal disk of the given
|
|
7347
|
-
* 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
|
|
7348
7376
|
* medial axis.
|
|
7349
7377
|
* @param cpNode
|
|
7350
7378
|
*/
|
|
@@ -7354,8 +7382,8 @@ const CpNodeFs = {
|
|
|
7354
7382
|
getBranchBeziers: getBranchBeziers,
|
|
7355
7383
|
getSalience: getSalience,
|
|
7356
7384
|
/**
|
|
7357
|
-
* Returns the bezier curve from the maximal disk of one
|
|
7358
|
-
*
|
|
7385
|
+
* Returns the bezier curve from the maximal disk of one `CpNode` to another
|
|
7386
|
+
* `CpNode`'s maximal disk.
|
|
7359
7387
|
* @param cpNodeFrom
|
|
7360
7388
|
* @param cpNodeTo
|
|
7361
7389
|
*/
|
|
@@ -24713,6 +24741,13 @@ function getNonTerminatingOnCircle(cpNode, exclThis = false) {
|
|
|
24713
24741
|
;// ./src/mat/get-branches.ts
|
|
24714
24742
|
|
|
24715
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
|
+
*/
|
|
24716
24751
|
function getBranches(cpNode) {
|
|
24717
24752
|
const branches = [];
|
|
24718
24753
|
const cpNodeStack = [cpNode];
|
|
@@ -25418,7 +25453,7 @@ function simplifyMat(mat, hausdorffTolerance = 2 ** -3, maxIterations = 50) {
|
|
|
25418
25453
|
for (const cpNode of canDeletes) {
|
|
25419
25454
|
if (!isVertex(cpNode => (getProngCount(cpNode) !== 2) &&
|
|
25420
25455
|
!cpNode.isHoleClosing)(cpNode)) {
|
|
25421
|
-
removeVertex(cpNode, mat.meta
|
|
25456
|
+
removeVertex(cpNode, mat.meta);
|
|
25422
25457
|
}
|
|
25423
25458
|
}
|
|
25424
25459
|
return {
|
|
@@ -26857,7 +26892,7 @@ cpTree, cp, next) {
|
|
|
26857
26892
|
|
|
26858
26893
|
;// ./src/cp-node/fs/insert-cp-node.ts
|
|
26859
26894
|
|
|
26860
|
-
function insertCpNode(insertIfOrderWrong, isHoleClosing, isIntersection, cpTree, cp, _prev) {
|
|
26895
|
+
function insertCpNode(insertIfOrderWrong, isHoleClosing, isIntersection, cpTree, cp, _prev, lastInsertId) {
|
|
26861
26896
|
if (_prev !== undefined &&
|
|
26862
26897
|
!isOrderCorrect(cpTree, cp, _prev.next)) {
|
|
26863
26898
|
// console.log(compareCps(cp,_prev!.next.cp))
|
|
@@ -26865,7 +26900,17 @@ function insertCpNode(insertIfOrderWrong, isHoleClosing, isIntersection, cpTree,
|
|
|
26865
26900
|
return undefined;
|
|
26866
26901
|
}
|
|
26867
26902
|
}
|
|
26868
|
-
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++;
|
|
26869
26914
|
const prev = _prev === undefined ? cpNode : _prev;
|
|
26870
26915
|
const next = _prev === undefined ? cpNode : prev.next;
|
|
26871
26916
|
next.prev = cpNode;
|
|
@@ -26915,7 +26960,10 @@ function byAngle(circle) {
|
|
|
26915
26960
|
*
|
|
26916
26961
|
* @internal
|
|
26917
26962
|
*/
|
|
26918
|
-
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;
|
|
26919
26967
|
let anyFailed = false;
|
|
26920
26968
|
const cpNodes = poss.map((pos, i) => {
|
|
26921
26969
|
const order = orders[i];
|
|
@@ -26924,7 +26972,7 @@ function addToCpTree(insertIfOrderIsWrong, isHoleClosing, circle, orders, cpTree
|
|
|
26924
26972
|
const pred = neighbors === undefined
|
|
26925
26973
|
? getCpNodeToLeftOrSame(cpTree, pos, order, 0)
|
|
26926
26974
|
: neighbors[i];
|
|
26927
|
-
const cpNode = insertCpNode(insertIfOrderIsWrong, isHoleClosing, false, cpTree, cp, pred);
|
|
26975
|
+
const cpNode = insertCpNode(insertIfOrderIsWrong, isHoleClosing, false, cpTree, cp, pred, meta.lastInsertId);
|
|
26928
26976
|
if (cpNode === undefined) {
|
|
26929
26977
|
anyFailed = true;
|
|
26930
26978
|
}
|
|
@@ -27028,7 +27076,7 @@ function findAndAdd3Prong(meta, visitedCps) {
|
|
|
27028
27076
|
}
|
|
27029
27077
|
}
|
|
27030
27078
|
const cpNodes = closeBysFor3Prong.length === 0
|
|
27031
|
-
? addToCpTree(true, false, circle, orders, meta
|
|
27079
|
+
? addToCpTree(true, false, circle, orders, meta, poss, δ3s.map(v => v[0])).cpNodes
|
|
27032
27080
|
: [];
|
|
27033
27081
|
return { closeBysFor3Prong, cpNodes: cpNodes };
|
|
27034
27082
|
}
|
|
@@ -27086,6 +27134,9 @@ function findAndAdd3Prongs(meta, cpStart) {
|
|
|
27086
27134
|
|
|
27087
27135
|
|
|
27088
27136
|
|
|
27137
|
+
// import { LlRbTree } from 'flo-ll-rb-tree';
|
|
27138
|
+
// import { Loop } from 'flo-boolean';
|
|
27139
|
+
// import { drawFs } from 'flo-draw';
|
|
27089
27140
|
|
|
27090
27141
|
/**
|
|
27091
27142
|
* @internal
|
|
@@ -27113,7 +27164,7 @@ function findAndAdd3ProngsOnLoop(meta, cpStart) {
|
|
|
27113
27164
|
}
|
|
27114
27165
|
else {
|
|
27115
27166
|
reLoop = true;
|
|
27116
|
-
replaceCloseBys(meta
|
|
27167
|
+
replaceCloseBys(meta, closeBysFor3Prong, cpNodeSet, cpNodeGoodSet);
|
|
27117
27168
|
}
|
|
27118
27169
|
addedCpNodes.forEach(cpNodes => cpNodes.forEach(cpNode => cpNodeGoodSet.add(cpNode)));
|
|
27119
27170
|
}
|
|
@@ -27135,13 +27186,15 @@ function getLastItemOfSet(set) {
|
|
|
27135
27186
|
for (item of set) { }
|
|
27136
27187
|
return item;
|
|
27137
27188
|
}
|
|
27138
|
-
function replaceCloseBys(
|
|
27189
|
+
function replaceCloseBys(
|
|
27190
|
+
// cpTrees: Map<Loop,LlRbTree<CpNode>>,
|
|
27191
|
+
meta, closeBysFor3Prong, cpNodeSet, cpNodeGoodSet) {
|
|
27139
27192
|
for (const closeBy of [closeBysFor3Prong[0]]) {
|
|
27140
27193
|
getAllOnCircle(closeBy).forEach(v => {
|
|
27141
27194
|
cpNodeSet.delete(v);
|
|
27142
27195
|
cpNodeGoodSet.delete(v);
|
|
27143
27196
|
});
|
|
27144
|
-
removeVertex(closeBy,
|
|
27197
|
+
removeVertex(closeBy, meta);
|
|
27145
27198
|
}
|
|
27146
27199
|
}
|
|
27147
27200
|
|
|
@@ -27155,12 +27208,14 @@ const { cpNodeComparator: create_initial_cp_tree_cpNodeComparator } = CpNodeFs;
|
|
|
27155
27208
|
* @internal
|
|
27156
27209
|
* Creates the initial ContactPoint loops from the given sharp corners.
|
|
27157
27210
|
*
|
|
27158
|
-
* * modifies `cpTrees`
|
|
27211
|
+
* * modifies `cpTrees` and `lastInsertId` of `meta`
|
|
27159
27212
|
*
|
|
27160
|
-
* @param
|
|
27213
|
+
* @param loops
|
|
27214
|
+
* @param cpTrees
|
|
27161
27215
|
* @param sharpCornerss
|
|
27216
|
+
* @param lastInsertId
|
|
27162
27217
|
*/
|
|
27163
|
-
function createInitialCpTree(loops, cpTrees, sharpCornerss) {
|
|
27218
|
+
function createInitialCpTree(loops, cpTrees, sharpCornerss, lastInsertId) {
|
|
27164
27219
|
let cpNode;
|
|
27165
27220
|
for (let k = 0; k < sharpCornerss.length; k++) {
|
|
27166
27221
|
const sharpCorners = sharpCornerss[k];
|
|
@@ -27171,8 +27226,8 @@ function createInitialCpTree(loops, cpTrees, sharpCornerss) {
|
|
|
27171
27226
|
const circle = { center: pos.p, radius: 0 };
|
|
27172
27227
|
const cp1 = { pointOnShape: pos, circle, order: -1, order2: 0 };
|
|
27173
27228
|
const cp2 = { pointOnShape: pos, circle, order: +1, order2: 0 };
|
|
27174
|
-
cpNode1 = insertCpNode(true, false, false, cpTree, cp1, cpNode2);
|
|
27175
|
-
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);
|
|
27176
27231
|
cpNode1.prevOnCircle = cpNode2;
|
|
27177
27232
|
cpNode2.prevOnCircle = cpNode1;
|
|
27178
27233
|
cpNode1.nextOnCircle = cpNode2;
|
|
@@ -27245,14 +27300,9 @@ const TriMapFs = {
|
|
|
27245
27300
|
|
|
27246
27301
|
let timingStart;
|
|
27247
27302
|
/** @internal */
|
|
27248
|
-
function
|
|
27303
|
+
function getPointToCpNode(loops, cpTrees) {
|
|
27249
27304
|
timingStart = performance.now();
|
|
27250
27305
|
const pointToCpNode = new Map();
|
|
27251
|
-
const looseBoundingBoxes = [];
|
|
27252
|
-
const tightBoundingBoxes = [];
|
|
27253
|
-
const boundingHulls = [];
|
|
27254
|
-
const sharpCorners = [];
|
|
27255
|
-
const dullCorners = [];
|
|
27256
27306
|
for (const loop of loops) {
|
|
27257
27307
|
// Populate `posMap`
|
|
27258
27308
|
const cpTree = cpTrees.get(loop);
|
|
@@ -27261,7 +27311,18 @@ function getMeta(maxCoordinate, squaredDiagonalLength, loops, cpTrees) {
|
|
|
27261
27311
|
const { p, t } = cpNode.cp.pointOnShape;
|
|
27262
27312
|
TriMapFs.set(pointToCpNode, loop, p[0], p[1], cpNode);
|
|
27263
27313
|
}
|
|
27264
|
-
|
|
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) {
|
|
27265
27326
|
const ps = curve.ps;
|
|
27266
27327
|
const hull = getBoundingHull(ps, true);
|
|
27267
27328
|
boundingHulls.push(hull);
|
|
@@ -27279,16 +27340,11 @@ function getMeta(maxCoordinate, squaredDiagonalLength, loops, cpTrees) {
|
|
|
27279
27340
|
}
|
|
27280
27341
|
}
|
|
27281
27342
|
return {
|
|
27282
|
-
maxCoordinate,
|
|
27283
|
-
squaredDiagonalLength,
|
|
27284
27343
|
looseBoundingBoxes,
|
|
27285
27344
|
tightBoundingBoxes,
|
|
27286
27345
|
boundingHulls,
|
|
27287
27346
|
sharpCorners,
|
|
27288
|
-
dullCorners
|
|
27289
|
-
loops,
|
|
27290
|
-
cpTrees,
|
|
27291
|
-
pointToCpNode
|
|
27347
|
+
dullCorners
|
|
27292
27348
|
};
|
|
27293
27349
|
}
|
|
27294
27350
|
/** @internal */
|
|
@@ -27745,7 +27801,10 @@ function findEquidistantPointOnLineDd(x, y, z) {
|
|
|
27745
27801
|
|
|
27746
27802
|
|
|
27747
27803
|
/** @internal */
|
|
27748
|
-
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;
|
|
27749
27808
|
if (isHoleClosing) {
|
|
27750
27809
|
return loops
|
|
27751
27810
|
.filter(_loop => _loop !== loop)
|
|
@@ -27918,7 +27977,7 @@ function add1Prong(meta, radius, center, pos) {
|
|
|
27918
27977
|
if (getCloseByCpIfExist(meta, pos, circle, order, 0, 1)) {
|
|
27919
27978
|
return;
|
|
27920
27979
|
}
|
|
27921
|
-
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]);
|
|
27922
27981
|
// if (typeof _debug_ !== 'undefined') {
|
|
27923
27982
|
// _debug_.generated.elems.oneProng.push(cpNodes);
|
|
27924
27983
|
// }
|
|
@@ -27945,75 +28004,89 @@ const { asin, acos, cos, sqrt: calc_seperation_tolerance_sqrt, PI: π } = Math;
|
|
|
27945
28004
|
* @param r radius of the MAT circle
|
|
27946
28005
|
* @param θ angle between point...
|
|
27947
28006
|
*/
|
|
27948
|
-
function calcSeperationTolerance2(R, r, δ) {
|
|
27949
|
-
const a = r + δ;
|
|
27950
|
-
if (a >= R) {
|
|
27951
|
-
return Number.POSITIVE_INFINITY;
|
|
27952
|
-
}
|
|
27953
|
-
const b = R - r; //?
|
|
27954
|
-
const c = R; //?
|
|
27955
|
-
const N = c * c - a * a - b * b; //?
|
|
27956
|
-
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));
|
|
27957
|
-
const D = 2 * a * b; //?
|
|
27958
|
-
const D_ = calc_seperation_tolerance_tp(-2 * a, b);
|
|
27959
|
-
const Q = ddDivDd(N_, D_)[1]; //?
|
|
27960
|
-
const cosC = -N / D; //?
|
|
27961
|
-
const C = acos(cosC);
|
|
27962
|
-
const CC = acos(Q);
|
|
27963
|
-
const θ = π - CC; //?
|
|
27964
|
-
return θ;
|
|
27965
|
-
// return r*θ; // approximate arc with line
|
|
27966
|
-
}
|
|
27967
|
-
|
|
27968
|
-
function calc_seperation_tolerance_degToRad(degrees) {
|
|
27969
|
-
return degrees / 360 * 2 * Math.PI;
|
|
27970
|
-
}
|
|
27971
|
-
function radToDeg(rad) {
|
|
27972
|
-
return rad * 360 / 2 / Math.PI;
|
|
27973
|
-
}
|
|
27974
|
-
const R = 699;
|
|
27975
|
-
const r = 698;
|
|
27976
|
-
const δ = 1000 * 2 ** -46; //?
|
|
27977
|
-
calcSeperationTolerance(R, r, δ); //?
|
|
27978
|
-
calcSeperationTolerance2(R, r, δ); //?
|
|
27979
|
-
calcSeperationTolerance3(R, r, δ); //?
|
|
27980
28007
|
function calcSeperationTolerance(R, r, δ) {
|
|
27981
28008
|
const a = r + δ;
|
|
27982
28009
|
if (a >= R) {
|
|
27983
28010
|
return Number.POSITIVE_INFINITY;
|
|
27984
28011
|
}
|
|
27985
|
-
const R_r_ = twoDiff(R, r);
|
|
27986
|
-
const A_ = calc_seperation_tolerance_qmd(r, R_r_);
|
|
27987
|
-
const N_ = calc_seperation_tolerance_qdq(calc_seperation_tolerance_qdq(A_, calc_seperation_tolerance_tp(r, δ)), calc_seperation_tolerance_tp(δ, δ / 2));
|
|
27988
|
-
const D_ = calc_seperation_tolerance_qaq(A_, calc_seperation_tolerance_qmd(δ, R_r_));
|
|
27989
|
-
const R_r = R - r;
|
|
27990
|
-
const A = r * R_r;
|
|
27991
|
-
const N = A - r * δ - (δ * δ) / 2;
|
|
27992
|
-
const D = A + R_r * δ;
|
|
27993
|
-
const cosC = N / D;
|
|
27994
|
-
const Q = ddDivDd(N_, D_)[1];
|
|
27995
|
-
// 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];
|
|
27996
28023
|
const C = acos(cosC);
|
|
27997
28024
|
const CC = acos(Q);
|
|
27998
|
-
const θ = CC;
|
|
28025
|
+
const θ = CC;
|
|
27999
28026
|
// return r*θ;
|
|
28000
28027
|
return r * θ;
|
|
28001
28028
|
}
|
|
28002
|
-
|
|
28003
|
-
|
|
28004
|
-
|
|
28005
|
-
|
|
28006
|
-
|
|
28007
|
-
|
|
28008
|
-
|
|
28009
|
-
|
|
28010
|
-
|
|
28011
|
-
|
|
28012
|
-
|
|
28013
|
-
|
|
28014
|
-
|
|
28015
|
-
|
|
28016
|
-
|
|
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
|
+
// }
|
|
28017
28090
|
|
|
28018
28091
|
;// ./src/find-2-prong/find-2-prong.ts
|
|
28019
28092
|
|
|
@@ -28052,7 +28125,7 @@ const { ceil: find_2_prong_ceil, log2: find_2_prong_log2, max: find_2_prong_max,
|
|
|
28052
28125
|
* @param loopIdx The loop array index
|
|
28053
28126
|
*/
|
|
28054
28127
|
function find2Prong(meta, isHoleClosing, for1Prong, angle, y) {
|
|
28055
|
-
const { loops, maxCoordinate, squaredDiagonalLength
|
|
28128
|
+
const { loops, maxCoordinate, squaredDiagonalLength } = meta;
|
|
28056
28129
|
const loop = y.curve.loop;
|
|
28057
28130
|
const MAX_ITERATIONS = 25;
|
|
28058
28131
|
const minSquaredSeperationTolerance = ((2 ** -21) * maxCoordinate) ** 2;
|
|
@@ -28065,7 +28138,7 @@ function find2Prong(meta, isHoleClosing, for1Prong, angle, y) {
|
|
|
28065
28138
|
const p = y.p;
|
|
28066
28139
|
// The boundary piece that should contain the other point of
|
|
28067
28140
|
// the 2-prong circle. (Defined by start and end points).
|
|
28068
|
-
let bezierPieces = getInitialBezierPieces(angle, isHoleClosing, loop, loops,
|
|
28141
|
+
let bezierPieces = getInitialBezierPieces(angle, isHoleClosing, loop, loops, meta, y, { center: xO, radius: rO });
|
|
28069
28142
|
// console.log(bezierPieces.length);
|
|
28070
28143
|
/** The center of the two-prong (successively refined) */
|
|
28071
28144
|
let x = xO;
|
|
@@ -28191,7 +28264,6 @@ function getO(angle, isHoleClosing, maxOsculatingCircleRadius, minCurvature, y)
|
|
|
28191
28264
|
* tolerances.
|
|
28192
28265
|
*/
|
|
28193
28266
|
function add2Prong(meta, circle, poss, isHoleClosing) {
|
|
28194
|
-
const { cpTrees } = meta;
|
|
28195
28267
|
poss[0] = poss[0].t === 0
|
|
28196
28268
|
? createPos(poss[0].curve.prev, 1, true)
|
|
28197
28269
|
: poss[0];
|
|
@@ -28203,11 +28275,11 @@ function add2Prong(meta, circle, poss, isHoleClosing) {
|
|
|
28203
28275
|
return undefined;
|
|
28204
28276
|
}
|
|
28205
28277
|
}
|
|
28206
|
-
const { anyFailed, cpNodes } = addToCpTree(isHoleClosing, isHoleClosing, circle, orders,
|
|
28278
|
+
const { anyFailed, cpNodes } = addToCpTree(isHoleClosing, isHoleClosing, circle, orders, meta, poss);
|
|
28207
28279
|
if (anyFailed) {
|
|
28208
28280
|
cpNodes.forEach(cpNode => {
|
|
28209
28281
|
if (cpNode !== undefined) {
|
|
28210
|
-
removeCpNode(cpNode,
|
|
28282
|
+
removeCpNode(cpNode, meta);
|
|
28211
28283
|
}
|
|
28212
28284
|
});
|
|
28213
28285
|
return undefined;
|
|
@@ -28215,17 +28287,20 @@ function add2Prong(meta, circle, poss, isHoleClosing) {
|
|
|
28215
28287
|
// Get points ordered according to their angle with the x-axis
|
|
28216
28288
|
// joinSpokes(circle, cpNodes);
|
|
28217
28289
|
if (isHoleClosing) {
|
|
28218
|
-
closeHole(
|
|
28290
|
+
closeHole(meta, cpNodes);
|
|
28219
28291
|
}
|
|
28220
28292
|
return cpNodes[0]; // return the source `CpNode`
|
|
28221
28293
|
}
|
|
28222
|
-
function closeHole(
|
|
28294
|
+
function closeHole(meta,
|
|
28295
|
+
// cpTrees: Map<Loop, LlRbTree<CpNode>>,
|
|
28296
|
+
cpNodes) {
|
|
28297
|
+
const { cpTrees } = meta;
|
|
28223
28298
|
const [cpNodeA, cpNodeB] = cpNodes;
|
|
28224
28299
|
// Duplicate ContactPoints
|
|
28225
28300
|
// const antipodeCpNode = cpNodeB[0];
|
|
28226
28301
|
const cpAntipode = cpNodeB.cp;
|
|
28227
|
-
const cpNodeB2 = insertCpNode(true, true, false, cpTrees.get(cpAntipode.pointOnShape.curve.loop), { ...cpAntipode, order2: +1 }, cpNodeB);
|
|
28228
|
-
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);
|
|
28229
28304
|
// Connect graph
|
|
28230
28305
|
cpNodeB1.prevOnCircle = cpNodeB2;
|
|
28231
28306
|
cpNodeB1.nextOnCircle = cpNodeB2;
|
|
@@ -28968,12 +29043,18 @@ function findMat(loops, maxCoordinate, options) {
|
|
|
28968
29043
|
const getFor2ProngsOnLoop_ = getFor2ProngsOnLoop(minBezLength, maxCurviness, maxLength);
|
|
28969
29044
|
const getFor1ProngsOnLoop_ = getFor1ProngsOnLoop(minBezLength);
|
|
28970
29045
|
const sharpCornersPerLoop = loops.map(getSharpCornersOnLoop_);
|
|
28971
|
-
const cpTrees = new Map();
|
|
28972
|
-
createInitialCpTree(loops, cpTrees, sharpCornersPerLoop);
|
|
28973
29046
|
const bounds = get_shape_bounds_getShapeBounds(loops);
|
|
28974
29047
|
const squaredDiagonalLength = (bounds.maxX.p[0] - bounds.minX.p[0]) ** 2 +
|
|
28975
29048
|
(bounds.maxY.p[1] - bounds.minY.p[1]) ** 2;
|
|
28976
|
-
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
|
+
};
|
|
28977
29058
|
let cpNode;
|
|
28978
29059
|
cpNode = findAndAddHoleClosing2Prongs(meta);
|
|
28979
29060
|
if (typeof _debug_ !== 'undefined') {
|
|
@@ -30649,7 +30730,7 @@ function holeCloserNext(pairs, holeCloser) {
|
|
|
30649
30730
|
|
|
30650
30731
|
|
|
30651
30732
|
|
|
30733
|
+
// export { getMeta } from './find-mat/get-meta.js';
|
|
30652
30734
|
|
|
30653
30735
|
|
|
30654
|
-
|
|
30655
|
-
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 };
|