flo-mat 3.0.6 → 3.0.9

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.
Files changed (193) hide show
  1. package/__tests__/cp-node/fs/add-distance-from.spec.ts +7 -0
  2. package/__tests__/cp-node/fs/check-jsog-eql-calc.spec.ts +30 -0
  3. package/__tests__/cp-node/fs/clone.spec.ts +7 -0
  4. package/__tests__/cp-node/fs/cp-nodes-to-boundary-beziers.spec.ts +7 -0
  5. package/__tests__/cp-node/fs/create-cp-node.spec.ts +7 -0
  6. package/__tests__/cp-node/fs/enhance-cp-node.spec.ts +7 -0
  7. package/__tests__/cp-node/fs/find-first.spec.ts +7 -0
  8. package/__tests__/cp-node/fs/get-all-between.spec.ts +7 -0
  9. package/__tests__/cp-node/fs/get-all-on-circle.spec.ts +92 -0
  10. package/__tests__/cp-node/fs/get-all-on-loop.spec.ts +7 -0
  11. package/__tests__/cp-node/fs/get-all-vertices.spec.ts +7 -0
  12. package/__tests__/cp-node/fs/get-angle-between-mat-curves.spec.ts +7 -0
  13. package/__tests__/cp-node/fs/get-avg-speed.spec.ts +7 -0
  14. package/__tests__/cp-node/fs/get-boundary-bezier-parts-to-next.spec.ts +7 -0
  15. package/__tests__/cp-node/fs/get-boundary-beziers-between.spec.ts +7 -0
  16. package/__tests__/cp-node/fs/get-boundary-beziers-to-next.spec.ts +7 -0
  17. package/__tests__/cp-node/fs/get-boundary-distance-to-next.spec.ts +7 -0
  18. package/__tests__/cp-node/fs/get-branch-beziers.spec.ts +7 -0
  19. package/__tests__/cp-node/fs/get-branch.spec.ts +7 -0
  20. package/__tests__/cp-node/fs/get-children.spec.ts +7 -0
  21. package/__tests__/cp-node/fs/get-cp-node-ordering.spec.ts +7 -0
  22. package/__tests__/cp-node/fs/get-distance-between.spec.ts +7 -0
  23. package/__tests__/cp-node/fs/get-distance-to-next.spec.ts +7 -0
  24. package/__tests__/cp-node/fs/get-edge-direction.spec.ts +7 -0
  25. package/__tests__/cp-node/fs/get-first-exit.spec.ts +7 -0
  26. package/__tests__/cp-node/fs/get-hole-closers.spec.ts +7 -0
  27. package/__tests__/cp-node/fs/get-implied-boundary-bezier-between.spec.ts +7 -0
  28. package/__tests__/cp-node/fs/get-mat-curve-between.spec.ts +7 -0
  29. package/__tests__/cp-node/fs/get-mat-curve-to-next.spec.ts +7 -0
  30. package/__tests__/cp-node/fs/get-mat-curves-between.spec.ts +7 -0
  31. package/__tests__/cp-node/fs/get-non-terminating-on-circle.spec.ts +7 -0
  32. package/__tests__/cp-node/fs/get-prong-count.spec.ts +7 -0
  33. package/__tests__/cp-node/fs/get-real-prong-count.spec.ts +7 -0
  34. package/__tests__/cp-node/fs/get-salience.spec.ts +7 -0
  35. package/__tests__/cp-node/fs/get-smoothed-speed.spec.ts +7 -0
  36. package/__tests__/cp-node/fs/get-smoothed.spec.ts +7 -0
  37. package/__tests__/cp-node/fs/get-speed.spec.ts +7 -0
  38. package/__tests__/cp-node/fs/get-terminating-on-circle.spec.ts +7 -0
  39. package/__tests__/cp-node/fs/get-vertex-forward-children.spec.ts +7 -0
  40. package/__tests__/cp-node/fs/insert-cp-node.spec.ts +7 -0
  41. package/__tests__/cp-node/fs/is-fully-terminating.spec.ts +7 -0
  42. package/__tests__/cp-node/fs/is-on-same-circle.spec.ts +7 -0
  43. package/__tests__/cp-node/fs/is-one-prong.spec.ts +7 -0
  44. package/__tests__/cp-node/fs/is-order-correct.spec.ts +7 -0
  45. package/__tests__/cp-node/fs/is-sharp.spec.ts +7 -0
  46. package/__tests__/cp-node/fs/is-single-3-prong.spec.ts +7 -0
  47. package/__tests__/cp-node/fs/is-special.spec.ts +7 -0
  48. package/__tests__/cp-node/fs/is-terminating.spec.ts +7 -0
  49. package/__tests__/cp-node/fs/is-trivial.spec.ts +7 -0
  50. package/__tests__/cp-node/fs/is-two-prong.spec.ts +7 -0
  51. package/__tests__/cp-node/fs/is-vertex-special.spec.ts +7 -0
  52. package/__tests__/cp-node/fs/is-vertex.spec.ts +7 -0
  53. package/__tests__/cp-node/fs/iterate-all-on-loop.spec.ts +7 -0
  54. package/__tests__/cp-node/fs/mat-dummys.ts +6716 -0
  55. package/__tests__/cp-node/fs/remove-cp-node.spec.ts +7 -0
  56. package/__tests__/cp-node/fs/traverse-all-forward.spec.ts +7 -0
  57. package/__tests__/cp-node/fs/traverse-cp.spec.ts +7 -0
  58. package/__tests__/cp-node/fs/traverse-edges.spec.ts +7 -0
  59. package/__tests__/cp-node/fs/traverse-vertices.spec.ts +7 -0
  60. package/__tests__/lib-load.spec.ts +9 -10
  61. package/browser/index.js +259 -174
  62. package/browser/index.min.js +1 -1
  63. package/jest.config.cjs +32 -0
  64. package/node/corner/get-interface-ccw.js +0 -1
  65. package/node/corner/get-interface-ccw.js.map +1 -1
  66. package/node/cp-node/cp-node-fs.d.ts +43 -43
  67. package/node/cp-node/cp-node-fs.js +43 -43
  68. package/node/cp-node/cp-node.d.ts +27 -35
  69. package/node/cp-node/fs/clone.d.ts +3 -3
  70. package/node/cp-node/fs/clone.js +3 -3
  71. package/node/cp-node/fs/enhance-cp-node.d.ts +1 -5
  72. package/node/cp-node/fs/enhance-cp-node.js.map +1 -1
  73. package/node/cp-node/fs/get-all-between.d.ts +3 -3
  74. package/node/cp-node/fs/get-all-between.js +3 -3
  75. package/node/cp-node/fs/get-all-between.js.map +1 -1
  76. package/node/cp-node/fs/get-all-on-circle.d.ts +7 -1
  77. package/node/cp-node/fs/get-all-on-circle.js +11 -7
  78. package/node/cp-node/fs/get-all-on-circle.js.map +1 -1
  79. package/node/cp-node/fs/get-all-on-loop.d.ts +1 -1
  80. package/node/cp-node/fs/get-all-on-loop.js.map +1 -1
  81. package/node/cp-node/fs/get-boundary-bezier-parts-to-next.d.ts +12 -3
  82. package/node/cp-node/fs/get-boundary-bezier-parts-to-next.js +22 -7
  83. package/node/cp-node/fs/get-boundary-bezier-parts-to-next.js.map +1 -1
  84. package/node/cp-node/fs/get-boundary-beziers-between.d.ts +1 -1
  85. package/node/cp-node/fs/get-boundary-beziers-between.js.map +1 -1
  86. package/node/cp-node/fs/get-boundary-beziers-to-next.js.map +1 -1
  87. package/node/cp-node/fs/insert-cp-node.d.ts +3 -1
  88. package/node/cp-node/fs/insert-cp-node.js +12 -2
  89. package/node/cp-node/fs/insert-cp-node.js.map +1 -1
  90. package/node/cp-node/fs/is-fully-terminating.d.ts +7 -0
  91. package/node/cp-node/fs/is-fully-terminating.js +7 -0
  92. package/node/cp-node/fs/is-fully-terminating.js.map +1 -1
  93. package/node/cp-node/fs/is-terminating.d.ts +1 -1
  94. package/node/cp-node/fs/remove-cp-node.d.ts +3 -4
  95. package/node/cp-node/fs/remove-cp-node.js +3 -1
  96. package/node/cp-node/fs/remove-cp-node.js.map +1 -1
  97. package/node/curve/curve.d.ts +18 -11
  98. package/node/find-2-prong/add-1-prong.js +1 -1
  99. package/node/find-2-prong/add-1-prong.js.map +1 -1
  100. package/node/find-2-prong/add-2-prong.js +9 -7
  101. package/node/find-2-prong/add-2-prong.js.map +1 -1
  102. package/node/find-2-prong/calc-seperation-tolerance.d.ts +8 -1
  103. package/node/find-2-prong/calc-seperation-tolerance.js +73 -59
  104. package/node/find-2-prong/calc-seperation-tolerance.js.map +1 -1
  105. package/node/find-2-prong/find-2-prong.js +2 -2
  106. package/node/find-2-prong/find-2-prong.js.map +1 -1
  107. package/node/find-2-prong/get-initial-bezier-pieces.d.ts +2 -3
  108. package/node/find-2-prong/get-initial-bezier-pieces.js +4 -1
  109. package/node/find-2-prong/get-initial-bezier-pieces.js.map +1 -1
  110. package/node/find-3-prong.ts/find-and-add-3-prong.js +1 -1
  111. package/node/find-3-prong.ts/find-and-add-3-prong.js.map +1 -1
  112. package/node/find-3-prong.ts/find-and-add-3-prongs-on-loop.d.ts +2 -2
  113. package/node/find-3-prong.ts/find-and-add-3-prongs-on-loop.js +8 -3
  114. package/node/find-3-prong.ts/find-and-add-3-prongs-on-loop.js.map +1 -1
  115. package/node/find-mat/create-initial-cp-tree.d.ts +7 -3
  116. package/node/find-mat/create-initial-cp-tree.js +7 -5
  117. package/node/find-mat/create-initial-cp-tree.js.map +1 -1
  118. package/node/find-mat/find-mat.d.ts +2 -1
  119. package/node/find-mat/find-mat.js +14 -4
  120. package/node/find-mat/find-mat.js.map +1 -1
  121. package/node/find-mat/get-meta.d.ts +5 -2
  122. package/node/find-mat/get-meta.js +15 -14
  123. package/node/find-mat/get-meta.js.map +1 -1
  124. package/node/index.d.ts +1 -1
  125. package/node/index.js +1 -1
  126. package/node/index.js.map +1 -1
  127. package/node/mat/add-to-cp-tree.d.ts +5 -6
  128. package/node/mat/add-to-cp-tree.js +5 -2
  129. package/node/mat/add-to-cp-tree.js.map +1 -1
  130. package/node/mat/get-branches.d.ts +7 -0
  131. package/node/mat/get-branches.js +7 -0
  132. package/node/mat/get-branches.js.map +1 -1
  133. package/node/mat/mat-meta.d.ts +8 -1
  134. package/node/mat/mat.d.ts +3 -3
  135. package/node/mat/simplify-mat.js +1 -1
  136. package/node/mat/simplify-mat.js.map +1 -1
  137. package/node/point-on-shape/compare-poss.d.ts +3 -3
  138. package/node/point-on-shape/compare-poss.js +3 -3
  139. package/node/point-on-shape/get-osculating-circle.d.ts +1 -1
  140. package/node/point-on-shape/get-osculating-circle.js +1 -1
  141. package/node/point-on-shape/point-on-shape.d.ts +1 -1
  142. package/node/point-on-shape/pos-to-human-string.d.ts +1 -1
  143. package/node/point-on-shape/pos-to-human-string.js +1 -1
  144. package/node/sat/to-scale-axis.d.ts +1 -1
  145. package/node/sat/to-scale-axis.js +1 -1
  146. package/node/vertex/remove-vertex.d.ts +3 -4
  147. package/node/vertex/remove-vertex.js +3 -2
  148. package/node/vertex/remove-vertex.js.map +1 -1
  149. package/package.json +9 -6
  150. package/src/corner/get-interface-ccw.ts +0 -1
  151. package/src/cp-node/cp-node-fs.ts +43 -43
  152. package/src/cp-node/cp-node.ts +27 -39
  153. package/src/cp-node/fs/clone.ts +3 -3
  154. package/src/cp-node/fs/enhance-cp-node.ts +0 -1
  155. package/src/cp-node/fs/get-all-between.ts +31 -28
  156. package/src/cp-node/fs/get-all-on-circle.ts +13 -8
  157. package/src/cp-node/fs/get-all-on-loop.ts +12 -10
  158. package/src/cp-node/fs/get-boundary-bezier-parts-to-next.ts +39 -22
  159. package/src/cp-node/fs/get-boundary-beziers-between.ts +6 -2
  160. package/src/cp-node/fs/get-boundary-beziers-to-next.ts +6 -4
  161. package/src/cp-node/fs/insert-cp-node.ts +13 -2
  162. package/src/cp-node/fs/is-fully-terminating.ts +7 -0
  163. package/src/cp-node/fs/is-terminating.ts +1 -1
  164. package/src/cp-node/fs/remove-cp-node.ts +8 -4
  165. package/src/curve/curve.ts +19 -13
  166. package/src/debug/functions/check-ordering.ts +7 -3
  167. package/src/find-2-prong/add-1-prong.ts +1 -1
  168. package/src/find-2-prong/add-2-prong.ts +79 -74
  169. package/src/find-2-prong/calc-seperation-tolerance.ts +88 -78
  170. package/src/find-2-prong/find-2-prong.ts +2 -2
  171. package/src/find-2-prong/get-initial-bezier-pieces.ts +5 -1
  172. package/src/find-3-prong.ts/add-3-prong.ts +73 -70
  173. package/src/find-3-prong.ts/find-and-add-3-prong.ts +1 -1
  174. package/src/find-3-prong.ts/find-and-add-3-prongs-on-loop.ts +9 -8
  175. package/src/find-mat/create-initial-cp-tree.ts +10 -6
  176. package/src/find-mat/find-mat.ts +18 -5
  177. package/src/find-mat/get-meta.ts +36 -20
  178. package/src/get-curve/get-curve-between.ts +2 -2
  179. package/src/index.ts +1 -1
  180. package/src/mat/add-to-cp-tree.ts +18 -9
  181. package/src/mat/get-branches.ts +35 -28
  182. package/src/mat/mat-meta.ts +6 -1
  183. package/src/mat/mat.ts +3 -3
  184. package/src/mat/simplify-mat.ts +1 -1
  185. package/src/point-on-shape/compare-poss.ts +3 -3
  186. package/src/point-on-shape/get-osculating-circle.ts +1 -1
  187. package/src/point-on-shape/point-on-shape.ts +1 -1
  188. package/src/point-on-shape/pos-to-human-string.ts +1 -1
  189. package/src/sat/to-scale-axis.ts +1 -1
  190. package/src/vertex/remove-vertex.ts +7 -5
  191. package/.mocharc.cjs +0 -17
  192. package/src/debug/functions/draw-elem/branch.ts +0 -26
  193. package/src/find-mat/create-initial-cp-graph.ts +0 -59
package/browser/index.js CHANGED
@@ -916,10 +916,10 @@ function floydWarshall(graph) {
916
916
 
917
917
  ;// ./src/point-on-shape/compare-poss.ts
918
918
  /**
919
- * Compares two [[PointOnShape]]s according to their cyclic ordering imposed
919
+ * Compares two `PointOnShape`s according to their cyclic ordering imposed
920
920
  * by their relative positions on the shape boundary.
921
- * @param a The first [[PointOnShape]].
922
- * @param b The second [[PointOnShape]].
921
+ * @param a The first `PointOnShape`.
922
+ * @param b The second `PointOnShape`.
923
923
  * @internal
924
924
  */
925
925
  function comparePoss(a, b) {
@@ -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
- let cpNode_ = startCpNode;
6422
- const cpNodes = [];
6423
- do {
6424
- if (!(exclThis && cpNode_ === startCpNode)) {
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
- } while (cpNode_ !== startCpNode);
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 [[CpNode]]. Can be used to copy the MAT
6754
- * since cloning a single [[CpNode]] necessarily implies cloning all
6755
- * [[CpNode]]s on the same MAT tree.
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 bezierParts = [];
6825
+ const bezierPieces = [];
6807
6826
  if (curveNext === curveThis) {
6808
- bezierParts.push({ ps: posThis.curve.ps, ts: [posThis.t, posNext.t] });
6827
+ bezierPieces.push({
6828
+ ps: posThis.curve.ps,
6829
+ ts: [posThis.t, posNext.t]
6830
+ });
6809
6831
  }
6810
6832
  else {
6811
- bezierParts.push({ ps: posThis.curve.ps, ts: [posThis.t, 1] });
6812
- addSkippedBeziers(bezierParts, posThis.curve, posNext.curve, posNext.t);
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 bezierParts;
6839
+ return bezierPieces;
6815
6840
  }
6816
6841
  /**
6817
6842
  * @internal
6818
6843
  * Adds pieces of skipped beziers.
6819
6844
  */
6820
- function addSkippedBeziers(bezierParts, curveStart, curveEnd, t1) {
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
- bezierParts.push(bezierPart);
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, cpTrees) {
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, cpTrees) {
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, cpTrees));
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 (exclisive the last one).
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,23 +7215,23 @@ 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 [[CpNode]] when seen as a MAT edge. Only
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
- * except the 'backward' edge given by [[prevOnCircle]], even terminating
7220
+ * except the 'backward' edge given by `prevOnCircle`, even terminating
7193
7221
  * edges.
7194
7222
  */
7195
7223
  getChildren: getChildren,
7196
7224
  /**
7197
- * Similar to [[getChildren]] but returns the child nodes of the tree when
7198
- * [[CpNode]] is seen as a MAT vertex point (as opposed to edge). In this
7225
+ * Similar to `getChildren` but returns the child nodes of the tree when
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
- * [[traverseVertices]]. Generally, however, traversing the edges is
7228
+ * `traverseVertices`. Generally, however, traversing the edges is
7201
7229
  * preferred as it returns the entire Medial Axis (by utilizing
7202
- * [[getMatCurveToNext]] on each returned edge).
7230
+ * `getMatCurveToNext` on each returned edge).
7203
7231
  */
7204
7232
  getVertexForwardChildren: getVertexForwardChildren,
7205
7233
  /**
7206
- * Returns all [[CpNode]]s on the MAT that this [[CpNode]] is part of
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
- * [[CpNode]].
7242
+ * `CpNode`.
7215
7243
  */
7216
7244
  getAllOnCircle: getAllOnCircle,
7217
7245
  /**
7218
- * Returns true if the 2 given [[CpNode]]s are on the same maximal disk
7246
+ * Returns true if the 2 given `CpNode`s are on the same maximal disk
7219
7247
  * circle.
7220
- * @param cpNode1 A [[CpNode]].
7221
- * @param cpNode2 Another [[CpNode]]
7248
+ * @param cpNode1 A `CpNode`.
7249
+ * @param cpNode2 Another `CpNode`
7222
7250
  */
7223
7251
  isOnSameCircle: isOnSameCircle,
7224
7252
  /**
7225
- * Returns true if this [[CpNode]] is terminating, i.e. implies a leaf MAT
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,8 +7258,8 @@ 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 [[CpNode]] of course) will be terminating with the
7234
- * other point being its [[next]], whereas the other point will *not* be
7261
+ * (represented by a `CpNode` of course) will be terminating with the
7262
+ * other point being its `next`, whereas the other point will *not* be
7235
7263
  * terminating and 'points' back into the shape.
7236
7264
  */
7237
7265
  isTerminating: isTerminating,
@@ -7241,48 +7269,48 @@ const CpNodeFs = {
7241
7269
  */
7242
7270
  isFullyTerminating: isFullyTerminating,
7243
7271
  /**
7244
- * Returns the first [[CpNode]] (from this one by successively applying
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 [[CpNode]] represents a sharp corner, i.e. the
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 [[CpNode]]s are stored for each sharp corner, one being
7253
- * terminating and one not. See [[isTerminating]] for more details.
7280
+ * Note that two `CpNode`s are stored for each sharp corner, one being
7281
+ * terminating and one not. See `isTerminating` for more details.
7254
7282
  */
7255
7283
  isSharp: isSharp,
7256
7284
  /**
7257
- * Returns true if this [[CpNode]]'s maximal disk has only one contact point
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 [[CpNode]]s are stored for each such point to
7262
- * preserve symmetry - see [[isTerminating]] for more details.
7289
+ * Note, however, that two `CpNode`s are stored for each such point to
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 [[CpNode]].
7295
+ * by this `CpNode`.
7268
7296
  *
7269
7297
  * Note, however, that even one-prongs and sharp corners will return 2 (see
7270
- * [[isTerminating]] for more details); if this is not desired use
7271
- * [[getRealProngCount]] instead which will return 1 in these cases.
7298
+ * `isTerminating` for more details); if this is not desired use
7299
+ * `getRealProngCount` instead which will return 1 in these cases.
7272
7300
  */
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 [[CpNode]].
7304
+ * maximal disk circle implied by this `CpNode`.
7277
7305
  *
7278
- * See also [[getProngCount]].
7306
+ * See also `getProngCount`.
7279
7307
  */
7280
7308
  getRealProngCount: getRealProngCount,
7281
7309
  /**
7282
7310
  * Primarily for internal use.
7283
7311
  *
7284
- * Compares the order of two [[CpNode]]s. The order is cyclic and depends
7285
- * on a [[CpNode]]'s relative position along the shape boundary.
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 [[CpNode]]).
7306
- * @param cpNode Any [[CpNode]] representing the start vertex.
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 [[CpNode]]) on the MAT.
7341
+ * (represented by a `CpNode`) on the MAT.
7314
7342
  *
7315
- * It is usually preferable to use [[traverseEdges]] as it allows for the
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 [[CpNode]] representing the start vertex.
7318
- * @param traverseVerticesCallback A callback function taking a single [[CpNode]] as parameter.
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 [[CpNode]]. Can be used to copy the MAT
7323
- * since cloning a single [[CpNode]] necessarily implies cloning all
7324
- * [[CpNode]]s on the same MAT tree.
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 [[CpNodes]] of the MAT.
7342
- * @param cpNode The [[CpNode]] to remove.
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 [[CpNode]] to the
7347
- * next [[CpNode]]'s maximal disk and thus directly represents a piece of the
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 [[CpNode]] to another
7358
- * [[CpNode]]'s maximal disk.
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.cpTrees);
25456
+ removeVertex(cpNode, mat.meta);
25422
25457
  }
25423
25458
  }
25424
25459
  return {
@@ -25706,7 +25741,7 @@ function getSatCulls(cpNode, s) {
25706
25741
  * boundary of the shape. The SAT is a simplification of the MAT that preserves
25707
25742
  * less detail the higher the applied scale factor. The severity at which noise
25708
25743
  * are removed depends on the local scale of the shape.
25709
- * @param mat The Medial Axis Transform ([[Mat]]) on which to apply the SAT.
25744
+ * @param mat The Medial Axis Transform (`Mat`) on which to apply the SAT.
25710
25745
  * @param s The scale factor >= 1 (e.g. 1.3)
25711
25746
  */
25712
25747
  function toScaleAxis(mat, s) {
@@ -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 = { cp, isHoleClosing, isIntersection };
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, cpTrees, poss, neighbors) {
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.cpTrees, poss, δ3s.map(v => v[0])).cpNodes
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.cpTrees, closeBysFor3Prong, cpNodeSet, cpNodeGoodSet);
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(cpTrees, closeBysFor3Prong, cpNodeSet, cpNodeGoodSet) {
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, cpTrees);
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 shape
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 getMeta(maxCoordinate, squaredDiagonalLength, loops, cpTrees) {
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
- for (let curve of loop.curves) {
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 */
@@ -27658,7 +27714,7 @@ function tangentExact(ps, t) {
27658
27714
  *
27659
27715
  * @param minCurvature If not Number.POSITIVE_INFINITY then the
27660
27716
  * circle radius will be limited to this value.
27661
- * @param pos The [[PointOnShape]] identifying the point.
27717
+ * @param pos The `PointOnShape` identifying the point.
27662
27718
  * @param useMaxRadius
27663
27719
  */
27664
27720
  function getOsculatingCircle(minCurvature, pos,
@@ -27745,7 +27801,10 @@ function findEquidistantPointOnLineDd(x, y, z) {
27745
27801
 
27746
27802
 
27747
27803
  /** @internal */
27748
- function getInitialBezierPieces(angle, isHoleClosing, loop, loops, cpTrees, y, circle) {
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.cpTrees, [pos, pos]);
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
- // * see https://en.wikipedia.org/wiki/Law_of_cosines, Version suited to small angles
28003
- function calcSeperationTolerance3(R, r, δ) {
28004
- const a = r + δ; //?
28005
- const c = R - r; //?
28006
- const b = R; //?
28007
- // = (a - b)² + 4ab*sin²(θ/2) OR
28008
- // (c² - (a - b)²)/4ab = sin²(θ/2)
28009
- const cc = c * c; //?
28010
- const abc = a * a + b * b - 2 * a * b; //?
28011
- const A = cc - abc; //?
28012
- const B = calc_seperation_tolerance_sqrt(A / (4 * a * b)); //?
28013
- const θ = 2 * asin(B); //?
28014
- return θ;
28015
- // return r*θ; // approximate arc with line
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, cpTrees } = meta;
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, cpTrees, y, { center: xO, radius: rO });
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, cpTrees, poss);
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, cpTrees);
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(cpTrees, cpNodes);
28290
+ closeHole(meta, cpNodes);
28219
28291
  }
28220
28292
  return cpNodes[0]; // return the source `CpNode`
28221
28293
  }
28222
- function closeHole(cpTrees, cpNodes) {
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,22 @@ 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 meta = getMeta(maxCoordinate, squaredDiagonalLength, loops, cpTrees);
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
+ };
29058
+ // const cpTrees: Map<Loop, LlRbTree<CpNode>> = new Map();
29059
+ // const lastInsertId = { id: 0 };
29060
+ // createInitialCpTree(loops, cpTrees, sharpCornersPerLoop, lastInsertId);
29061
+ // const meta = getMeta(maxCoordinate, squaredDiagonalLength, loops, cpTrees, lastInsertId);
28977
29062
  let cpNode;
28978
29063
  cpNode = findAndAddHoleClosing2Prongs(meta);
28979
29064
  if (typeof _debug_ !== 'undefined') {
@@ -29170,7 +29255,7 @@ function trimMat(mat) {
29170
29255
 
29171
29256
  ;// ./src/point-on-shape/pos-to-human-string.ts
29172
29257
  /**
29173
- * Returns a human-readable string of the given [[PointOnShape]].
29258
+ * Returns a human-readable string of the given `PointOnShape`.
29174
29259
  * For debugging only.
29175
29260
  * @internal
29176
29261
  */
@@ -30652,4 +30737,4 @@ function holeCloserNext(pairs, holeCloser) {
30652
30737
 
30653
30738
 
30654
30739
 
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 };
30740
+ 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, getPartialMeta, getPathsFromStr, getPointToCpNode, getPotentialClosestPointsOnCurveCertified, getSatCulls, get_shape_bounds_getShapeBounds as getShapeBounds, getSharpCornersOnLoop, isVertexSpecial, loopFromBeziers, simplifyMat, sweep_line_sweepLine as sweepLine, toScaleAxis, trimMat };