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
@@ -1,9 +1,20 @@
1
- import { BezierPiece } from 'flo-bezier3';
2
- import { CpNode } from '../cp-node.js';
3
- import { Curve } from '../../curve/curve.js';
1
+ import type { BezierPiece } from 'flo-bezier3';
2
+ import type { CpNode } from '../cp-node.js';
3
+ import type { Curve } from '../../curve/curve.js';
4
4
 
5
5
 
6
- function getBoundaryBezierPartsToNext(cpNode: CpNode): BezierPiece[] {
6
+ /**
7
+ * Returns the boundary beziers pieces between this `CpNode` and the next
8
+ * one.
9
+ *
10
+ * * returns `undefined` if the next `CpNode` is on a different loop,
11
+ * as this is a hole-closer and there are no boundary beziers between them.
12
+ *
13
+ * @param cpNode
14
+ */
15
+ function getBoundaryBezierPartsToNext(
16
+ cpNode: CpNode): BezierPiece[] | undefined {
17
+
7
18
  const cpThis = cpNode;
8
19
  const cpNext = cpNode.next;
9
20
 
@@ -16,29 +27,35 @@ function getBoundaryBezierPartsToNext(cpNode: CpNode): BezierPiece[] {
16
27
  if (curveThis.loop !== curveNext.loop) {
17
28
  // It is a hole-closer going over to the other loop - a kind of terminal
18
29
  // CpNode.
19
- return undefined!;
30
+ return undefined;
20
31
  }
21
32
 
22
- const bezierParts: BezierPiece[] = [];
33
+ const bezierPieces: BezierPiece[] = [];
23
34
 
24
35
  if (curveNext === curveThis) {
25
- bezierParts.push(
26
- { ps: posThis.curve.ps, ts: [posThis.t, posNext.t] }
36
+ bezierPieces.push(
37
+ {
38
+ ps: posThis.curve.ps,
39
+ ts: [posThis.t, posNext.t]
40
+ }
27
41
  );
28
42
  } else {
29
- bezierParts.push(
30
- { ps: posThis.curve.ps, ts: [posThis.t, 1] }
43
+ bezierPieces.push(
44
+ {
45
+ ps: posThis.curve.ps,
46
+ ts: [posThis.t, 1]
47
+ }
31
48
  );
32
49
 
33
50
  addSkippedBeziers(
34
- bezierParts,
35
- posThis.curve,
36
- posNext.curve,
37
- posNext.t
51
+ bezierPieces,
52
+ posThis.curve,
53
+ posNext.curve,
54
+ posNext.t
38
55
  );
39
- }
40
-
41
- return bezierParts;
56
+ }
57
+
58
+ return bezierPieces;
42
59
  }
43
60
 
44
61
 
@@ -47,10 +64,10 @@ function getBoundaryBezierPartsToNext(cpNode: CpNode): BezierPiece[] {
47
64
  * Adds pieces of skipped beziers.
48
65
  */
49
66
  function addSkippedBeziers(
50
- bezierParts: { ps: number[][]; ts: number[] }[],
51
- curveStart : Curve,
52
- curveEnd : Curve,
53
- t1 : number) {
67
+ bezierPieces: BezierPiece[],
68
+ curveStart: Curve,
69
+ curveEnd: Curve,
70
+ t1: number) {
54
71
 
55
72
  let curveThis = curveStart;
56
73
  do {
@@ -59,7 +76,7 @@ function addSkippedBeziers(
59
76
  ? { ps: curveThis.ps, ts: [0, t1] }
60
77
  : { ps: curveThis.ps, ts: [0, 1] }
61
78
 
62
- bezierParts.push(bezierPart);
79
+ bezierPieces.push(bezierPart);
63
80
  } while (curveThis !== curveEnd);
64
81
  }
65
82
 
@@ -1,4 +1,5 @@
1
- import { CpNode } from "../cp-node.js";
1
+ import type { BezierPiece } from "flo-bezier3";
2
+ import type { CpNode } from "../cp-node.js";
2
3
  import { cpNodesToBoundaryBeziers } from "./cp-nodes-to-boundary-beziers.js";
3
4
  import { getAllBetween } from "./get-all-between.js";
4
5
 
@@ -17,7 +18,10 @@ import { getAllBetween } from "./get-all-between.js";
17
18
  function getBoundaryBeziersBetween(
18
19
  cpNode1: CpNode,
19
20
  cpNode2: CpNode,
20
- inclAllIfEqual = true) {
21
+ inclAllIfEqual = true): {
22
+ pss: number[][][],
23
+ hasHoleCloser: boolean
24
+ } {
21
25
 
22
26
  const allBetween = getAllBetween(cpNode1,cpNode2,inclAllIfEqual);
23
27
 
@@ -3,7 +3,9 @@ import { CpNode } from '../cp-node.js';
3
3
  import { Curve } from '../../curve/curve.js';
4
4
 
5
5
 
6
- function getBoundaryBeziersToNext(cpNode: CpNode): number[][][] {
6
+ function getBoundaryBeziersToNext(
7
+ cpNode: CpNode): number[][][] {
8
+
7
9
  const cpThis = cpNode;
8
10
  const cpNext = cpNode.next;
9
11
 
@@ -19,7 +21,7 @@ function getBoundaryBeziersToNext(cpNode: CpNode): number[][][] {
19
21
  // return undefined!;
20
22
  return [];
21
23
  }
22
-
24
+
23
25
  const beziers = [];
24
26
 
25
27
  if (curveNext === curveThis) {
@@ -37,8 +39,8 @@ function getBoundaryBeziersToNext(cpNode: CpNode): number[][][] {
37
39
  posNext.curve,
38
40
  posNext.t
39
41
  );
40
- }
41
-
42
+ }
43
+
42
44
  return beziers;
43
45
  }
44
46
 
@@ -10,7 +10,8 @@ function insertCpNode(
10
10
  isIntersection: boolean,
11
11
  cpTree: LlRbTree<CpNode>,
12
12
  cp: ContactPoint,
13
- _prev: CpNode | undefined) {
13
+ _prev: CpNode | undefined,
14
+ lastInsertId: { id: number }): CpNode | undefined {
14
15
 
15
16
  if (_prev !== undefined &&
16
17
  !isOrderCorrect(cpTree, cp, _prev.next)) {
@@ -21,7 +22,17 @@ function insertCpNode(
21
22
  }
22
23
  }
23
24
 
24
- const cpNode = { cp, isHoleClosing, isIntersection } as CpNode;
25
+ const cpNode: CpNode = {
26
+ cp,
27
+ isHoleClosing,
28
+ isIntersection,
29
+ id: lastInsertId.id,
30
+ next: undefined!,
31
+ prev: undefined!,
32
+ nextOnCircle: undefined!,
33
+ prevOnCircle: undefined!
34
+ };
35
+ lastInsertId.id++;
25
36
 
26
37
  const prev = _prev === undefined ? cpNode : _prev;
27
38
  const next = _prev === undefined ? cpNode : prev.next;
@@ -3,6 +3,13 @@ import { getAllOnCircle } from "./get-all-on-circle.js";
3
3
  import { isTerminating } from "./is-terminating.js";
4
4
 
5
5
 
6
+ /**
7
+ * Returns `true` if this `CpNode` is fully terminating, meaning that all
8
+ * `CpNode`s (except `CpNode.prevOnCircle`) on the same circle are terminating,
9
+ * `false` otherwise.
10
+ *
11
+ * @param cpNode
12
+ */
6
13
  function isFullyTerminating(cpNode: CpNode) {
7
14
  const otherOnCircle = getAllOnCircle(cpNode.prevOnCircle, true);
8
15
 
@@ -1,4 +1,4 @@
1
- import { CpNode } from "../cp-node.js";
1
+ import type { CpNode } from "../cp-node.js";
2
2
 
3
3
 
4
4
  function isTerminating(cpNode: CpNode) {
@@ -1,11 +1,15 @@
1
- import { Loop } from 'flo-boolean';
2
- import { LlRbTree } from 'flo-ll-rb-tree';
3
- import { CpNode } from "../cp-node.js";
1
+ // import { Loop } from 'flo-boolean';
2
+ // import { LlRbTree } from 'flo-ll-rb-tree';
3
+ import type { CpNode } from "../cp-node.js";
4
+ import type { MatMeta } from '../../mat/mat-meta.js';
4
5
 
5
6
 
6
7
  function removeCpNode(
7
8
  cpNode: CpNode,
8
- cpTrees: Map<Loop, LlRbTree<CpNode>>): void {
9
+ meta: MatMeta): void {
10
+ // cpTrees: Map<Loop, LlRbTree<CpNode>>): void {
11
+
12
+ const { cpTrees } = meta;
9
13
 
10
14
  const prev = cpNode.prev;
11
15
  const next = cpNode.next;
@@ -5,25 +5,31 @@ import { Loop } from 'flo-boolean';
5
5
  * Represents a bezier curve on the shape boundary / loop.
6
6
  */
7
7
  interface Curve {
8
-
9
- /**
10
- * Primarily for internal use.
11
- * @param loop The closed loop of bezier curves representing the shape
8
+ /**
9
+ * The closed loop of bezier curves representing the shape
12
10
  * boundary this curve belongs to.
13
- * @param ps The bezier control points.
14
- * @param prev The previous curve (when going in a negative direction around
15
- * the shape boundary, i.e. clockwise for the outer shape and anti-clockwise
16
- * for the holes (if any)).
17
- * @param next The next curve (when going in a positive direction around
18
- * the shape boundary, i.e. anti-clockwise for the outer shape and clockwise
19
- * for the holes (if any)).
20
- * @param idx The curve's ordered index in the loop. This imposes a cycling
21
- * ordering of the curves in the loop.
22
11
  */
23
12
  loop : Loop;
13
+ /**
14
+ * The bezier control points.
15
+ */
24
16
  ps : number[][];
17
+ /**
18
+ * The previous curve (when going in a negative direction around
19
+ * the shape boundary, i.e. clockwise for the outer shape and anti-clockwise
20
+ * for the holes (if any))
21
+ */
25
22
  prev : Curve;
23
+ /**
24
+ * The next curve (when going in a positive direction around
25
+ * the shape boundary, i.e. anti-clockwise for the outer shape and clockwise
26
+ * for the holes (if any))
27
+ */
26
28
  next : Curve;
29
+ /**
30
+ * The curve's ordered index in the loop. This imposes a cycling
31
+ * ordering of the curves in the loop
32
+ */
27
33
  idx : number;
28
34
  }
29
35
 
@@ -1,5 +1,6 @@
1
- import { Loop } from "flo-boolean";
2
- import { LlRbTree } from "flo-ll-rb-tree";
1
+ import type { Loop } from "flo-boolean";
2
+ import type { LlRbTree } from "flo-ll-rb-tree";
3
+ import type { MatMeta } from "../../mat/mat-meta.js";
3
4
  import { compareCps } from "../../contact-point/contact-point.js";
4
5
  import { CpNode } from "../../cp-node/cp-node.js";
5
6
  import { getAllOnLoop } from "../../cp-node/fs/get-all-on-loop.js";
@@ -8,9 +9,12 @@ import { isOrderCorrect } from "../../cp-node/fs/is-order-correct.js";
8
9
 
9
10
 
10
11
  function checkOrdering(
11
- cpTrees: Map<Loop,LlRbTree<CpNode>>,
12
+ // cpTrees: Map<Loop,LlRbTree<CpNode>>,
13
+ meta: MatMeta,
12
14
  cpStart: CpNode) {
13
15
 
16
+ const { cpTrees } = meta;
17
+
14
18
  const cpNodes = getAllOnLoop(cpStart);
15
19
 
16
20
  const wrongsPerLoop: Map<Loop,[Order,Order][]> = new Map();
@@ -50,7 +50,7 @@ function add1Prong(
50
50
  return;
51
51
  }
52
52
 
53
- const { anyFailed, cpNodes } = addToCpTree(false, false, circle, [-0.5, +0.5], meta.cpTrees, [pos, pos]);
53
+ const { anyFailed, cpNodes } = addToCpTree(false, false, circle, [-0.5, +0.5], meta, [pos, pos]);
54
54
 
55
55
  // if (typeof _debug_ !== 'undefined') {
56
56
  // _debug_.generated.elems.oneProng.push(cpNodes);
@@ -25,85 +25,90 @@ import { removeCpNode } from '../cp-node/fs/remove-cp-node.js';
25
25
  * tolerances.
26
26
  */
27
27
  function add2Prong(
28
- meta: MatMeta,
28
+ meta: MatMeta,
29
29
  circle: Circle,
30
- poss: PointOnShape[],
31
- isHoleClosing: boolean): CpNode | undefined {
32
-
33
- const { cpTrees } = meta;
34
-
35
- poss[0] = poss[0].t === 0
36
- ? createPos(poss[0].curve.prev, 1, true)
37
- : poss[0];
38
-
39
- const orders = poss.map(pos => calcPosOrder(circle, pos));
40
-
41
- // Make sure there isn't already a ContactPoint close by - it can cause
42
- // floating point stability issues.
43
- for (let i=0; i<poss.length; i++) {
44
- if (!!getCloseByCpIfExist(meta, poss[i], circle, orders[i], 0, 2)) {
45
- return undefined;
46
- }
47
- }
48
-
49
- const { anyFailed, cpNodes } = addToCpTree(isHoleClosing, isHoleClosing, circle, orders, cpTrees, poss);
50
-
51
- if (anyFailed) {
52
- cpNodes.forEach(cpNode => {
53
- if (cpNode !== undefined) {
54
- removeCpNode(cpNode, cpTrees);
55
- }
56
- });
57
- return undefined;
58
- }
59
-
60
- // Get points ordered according to their angle with the x-axis
61
- // joinSpokes(circle, cpNodes);
62
-
63
- if (isHoleClosing) {
64
- closeHole(cpTrees, cpNodes as CpNode[]);
65
- }
66
-
67
- return cpNodes[0]; // return the source `CpNode`
30
+ poss: PointOnShape[],
31
+ isHoleClosing: boolean): CpNode | undefined {
32
+
33
+ poss[0] = poss[0].t === 0
34
+ ? createPos(poss[0].curve.prev, 1, true)
35
+ : poss[0];
36
+
37
+ const orders = poss.map(pos => calcPosOrder(circle, pos));
38
+
39
+ // Make sure there isn't already a ContactPoint close by - it can cause
40
+ // floating point stability issues.
41
+ for (let i=0; i<poss.length; i++) {
42
+ if (!!getCloseByCpIfExist(meta, poss[i], circle, orders[i], 0, 2)) {
43
+ return undefined;
44
+ }
45
+ }
46
+
47
+ const { anyFailed, cpNodes } = addToCpTree(
48
+ isHoleClosing, isHoleClosing, circle, orders, meta, poss
49
+ );
50
+
51
+ if (anyFailed) {
52
+ cpNodes.forEach(cpNode => {
53
+ if (cpNode !== undefined) {
54
+ removeCpNode(cpNode, meta);
55
+ }
56
+ });
57
+ return undefined;
58
+ }
59
+
60
+ // Get points ordered according to their angle with the x-axis
61
+ // joinSpokes(circle, cpNodes);
62
+
63
+ if (isHoleClosing) {
64
+ closeHole(meta, cpNodes as CpNode[]);
65
+ }
66
+
67
+ return cpNodes[0]; // return the source `CpNode`
68
68
  }
69
69
 
70
70
 
71
71
  function closeHole(
72
- cpTrees: Map<Loop, LlRbTree<CpNode>>,
73
- cpNodes: CpNode[]) {
74
-
75
- const [cpNodeA, cpNodeB] = cpNodes;
76
- // Duplicate ContactPoints
77
- // const antipodeCpNode = cpNodeB[0];
78
- const cpAntipode = cpNodeB.cp;
79
-
80
- const cpNodeB2 = insertCpNode(
81
- true,
82
- true, false,
83
- cpTrees.get(cpAntipode.pointOnShape.curve.loop)!,
84
- { ...cpAntipode, order2: +1 },
85
- cpNodeB
86
- )!;
87
-
88
- const cpNodeB1 = insertCpNode(
89
- true,
90
- true, false,
91
- cpTrees.get(cpNodeA.cp.pointOnShape.curve.loop)!,
92
- { ...cpNodeA.cp, order2: -1 },
93
- cpNodeA.prev
94
- )!;
95
-
96
- // Connect graph
97
- cpNodeB1.prevOnCircle = cpNodeB2;
98
- cpNodeB1.nextOnCircle = cpNodeB2;
99
- cpNodeB2.prevOnCircle = cpNodeB1;
100
- cpNodeB2.nextOnCircle = cpNodeB1;
101
-
102
- cpNodeB.next = cpNodeA;
103
- cpNodeA.prev = cpNodeB;
104
-
105
- cpNodeB1.next = cpNodeB2;
106
- cpNodeB2.prev = cpNodeB1;
72
+ meta: MatMeta,
73
+ // cpTrees: Map<Loop, LlRbTree<CpNode>>,
74
+ cpNodes: CpNode[]) {
75
+
76
+ const { cpTrees } = meta;
77
+
78
+ const [cpNodeA, cpNodeB] = cpNodes;
79
+ // Duplicate ContactPoints
80
+ // const antipodeCpNode = cpNodeB[0];
81
+ const cpAntipode = cpNodeB.cp;
82
+
83
+ const cpNodeB2 = insertCpNode(
84
+ true,
85
+ true, false,
86
+ cpTrees.get(cpAntipode.pointOnShape.curve.loop)!,
87
+ { ...cpAntipode, order2: +1 },
88
+ cpNodeB,
89
+ meta.lastInsertId
90
+ )!;
91
+
92
+ const cpNodeB1 = insertCpNode(
93
+ true,
94
+ true, false,
95
+ cpTrees.get(cpNodeA.cp.pointOnShape.curve.loop)!,
96
+ { ...cpNodeA.cp, order2: -1 },
97
+ cpNodeA.prev,
98
+ meta.lastInsertId
99
+ )!;
100
+
101
+ // Connect graph
102
+ cpNodeB1.prevOnCircle = cpNodeB2;
103
+ cpNodeB1.nextOnCircle = cpNodeB2;
104
+ cpNodeB2.prevOnCircle = cpNodeB1;
105
+ cpNodeB2.nextOnCircle = cpNodeB1;
106
+
107
+ cpNodeB.next = cpNodeA;
108
+ cpNodeA.prev = cpNodeB;
109
+
110
+ cpNodeB1.next = cpNodeB2;
111
+ cpNodeB2.prev = cpNodeB1;
107
112
  }
108
113
 
109
114
 
@@ -18,52 +18,6 @@ const { asin, acos, cos, sqrt, PI: π } = Math;
18
18
  * @param r radius of the MAT circle
19
19
  * @param θ angle between point...
20
20
  */
21
- function calcSeperationTolerance2(
22
- R: number,
23
- r: number,
24
- δ: number) {
25
-
26
- const a = r + δ;
27
- if (a >= R) {
28
- return Number.POSITIVE_INFINITY;
29
- }
30
-
31
- const b = R - r; //?
32
- const c = R; //?
33
-
34
- const N = c*c - a*a - b*b; //?
35
- const N_ = qdq(qdq(tp(c,c), tp(a,a)), tp(b,b));
36
- const D = 2*a*b; //?
37
- const D_ = tp(-2*a,b);
38
- const Q = ddDivDd(N_,D_)[1]; //?
39
- const cosC = -N/D; //?
40
- const C = acos(cosC);
41
- const CC = acos(Q);
42
-
43
- const θ = π - CC; //?
44
-
45
- return θ;
46
- // return r*θ; // approximate arc with line
47
- }
48
-
49
-
50
- export { calcSeperationTolerance }
51
-
52
- function degToRad(degrees: number) {
53
- return degrees/360*2*Math.PI;
54
- }
55
- function radToDeg(rad: number) {
56
- return rad*360/2/Math.PI;
57
- }
58
-
59
-
60
- const R = 699;
61
- const r = 698;
62
- const δ = 1000*2**-46; //?
63
- calcSeperationTolerance(R,r,δ); //?
64
- calcSeperationTolerance2(R,r,δ); //?
65
- calcSeperationTolerance3(R,r,δ); //?
66
-
67
21
  function calcSeperationTolerance(
68
22
  R: number,
69
23
  r: number,
@@ -75,47 +29,103 @@ function calcSeperationTolerance(
75
29
  }
76
30
 
77
31
 
78
- const R_r_ = twoDiff(R,r); //?
79
- const A_ = qmd(r,R_r_); //?
80
- const N_ = qdq(qdq(A_, tp(r,δ)), tp(δ,δ/2)); //?
81
- const D_ = qaq(A_,qmd(δ,R_r_)); //?
32
+ const R_r_ = twoDiff(R,r);
33
+ const A_ = qmd(r,R_r_);
34
+ const N_ = qdq(qdq(A_, tp(r,δ)), tp(δ,δ/2));
35
+ const D_ = qaq(A_,qmd(δ,R_r_));
82
36
 
83
- const R_r = R - r; //?
84
- const A = r*R_r; //?
85
- const N = A - r*δ - (δ*δ)/2; //?
86
- const D = A + R_r*δ; //?
87
- const cosC = N/D; //?
88
- const Q = ddDivDd(N_,D_)[1];//?
89
- // const Q = N_[1]/D_[1];//?
37
+ const R_r = R - r;
38
+ const A = r*R_r;
39
+ const N = A - r*δ - (δ*δ)/2;
40
+ const D = A + R_r*δ;
41
+ const cosC = N/D;
42
+ const Q = ddDivDd(N_,D_)[1];
43
+ // const Q = N_[1]/D_[1];
90
44
  const C = acos(cosC);
91
45
  const CC = acos(Q)
92
46
 
93
- const θ = CC; //?
47
+ const θ = CC;
94
48
 
95
49
  // return r*θ;
96
50
  return r*θ;
97
51
  }
98
52
 
99
53
 
100
- // * see https://en.wikipedia.org/wiki/Law_of_cosines, Version suited to small angles
101
- function calcSeperationTolerance3(
102
- R: number,
103
- r: number,
104
- δ: number) {
54
+ export { calcSeperationTolerance }
55
+
105
56
 
106
- const a = r + δ; //?
107
- const c = R - r; //?
108
- const b = R; //?
57
+ // Quokka tests
58
+
59
+ // /**
60
+ // * Calculates and returns an appropriate seperation tolerance between `CpNode`s.
61
+ // *
62
+ // * @param R radius of the circle implied by the curvature at the boundary
63
+ // * @param r radius of the MAT circle
64
+ // * @param θ angle between point...
65
+ // */
66
+ // function calcSeperationTolerance2(
67
+ // R: number,
68
+ // r: number,
69
+ // δ: number) {
70
+
71
+ // const a = r + δ;
72
+ // if (a >= R) {
73
+ // return Number.POSITIVE_INFINITY;
74
+ // }
75
+
76
+ // const b = R - r;
77
+ // const c = R;
78
+
79
+ // const N = c*c - a*a - b*b;
80
+ // const N_ = qdq(qdq(tp(c,c), tp(a,a)), tp(b,b));
81
+ // const D = 2*a*b;
82
+ // const D_ = tp(-2*a,b);
83
+ // const Q = ddDivDd(N_,D_)[1];
84
+ // const cosC = -N/D;
85
+ // const C = acos(cosC);
86
+ // const CC = acos(Q);
87
+
88
+ // const θ = π - CC;
89
+
90
+ // return θ;
91
+ // // return r*θ; // approximate arc with line
92
+ // }
93
+
94
+
95
+ // function degToRad(degrees: number) {
96
+ // return degrees/360*2*Math.PI;
97
+ // }
98
+ // function radToDeg(rad: number) {
99
+ // return rad*360/2/Math.PI;
100
+ // }
101
+
102
+
103
+ // const R = 699;
104
+ // const r = 698;
105
+ // const δ = 1000*2**-46;
106
+ // calcSeperationTolerance(R,r,δ);
107
+ // calcSeperationTolerance2(R,r,δ);
108
+ // calcSeperationTolerance3(R,r,δ);
109
+
110
+ // // * see https://en.wikipedia.org/wiki/Law_of_cosines, Version suited to small angles
111
+ // function calcSeperationTolerance3(
112
+ // R: number,
113
+ // r: number,
114
+ // δ: number) {
115
+
116
+ // const a = r + δ;
117
+ // const c = R - r;
118
+ // const b = R;
109
119
 
110
- // c² = (a - b)² + 4ab*sin²(θ/2) OR
111
- // (c² - (a - b)²)/4ab = sin²(θ/2)
112
- const cc = c*c; //?
113
- const abc = a*a + b*b - 2*a*b; //?
114
- const A = cc - abc; //?
115
- const B = sqrt(A/(4*a*b)); //?
116
-
117
- const θ = 2*asin(B); //?
118
-
119
- return θ;
120
- // return r*θ; // approximate arc with line
121
- }
120
+ // // c² = (a - b)² + 4ab*sin²(θ/2) OR
121
+ // // (c² - (a - b)²)/4ab = sin²(θ/2)
122
+ // const cc = c*c;
123
+ // const abc = a*a + b*b - 2*a*b;
124
+ // const A = cc - abc;
125
+ // const B = sqrt(A/(4*a*b));
126
+
127
+ // const θ = 2*asin(B);
128
+
129
+ // return θ;
130
+ // // return r*θ; // approximate arc with line
131
+ // }
@@ -47,7 +47,7 @@ function find2Prong(
47
47
  angle: number,
48
48
  y: PointOnShape): { circle: Circle, zs: PointOnShape[] } | undefined {
49
49
 
50
- const { loops, maxCoordinate, squaredDiagonalLength, cpTrees } = meta;
50
+ const { loops, maxCoordinate, squaredDiagonalLength } = meta;
51
51
 
52
52
  const loop = y.curve.loop;
53
53
 
@@ -68,7 +68,7 @@ function find2Prong(
68
68
  // The boundary piece that should contain the other point of
69
69
  // the 2-prong circle. (Defined by start and end points).
70
70
  let bezierPieces = getInitialBezierPieces(
71
- angle, isHoleClosing, loop, loops, cpTrees, y, { center: xO, radius: rO }
71
+ angle, isHoleClosing, loop, loops, meta, y, { center: xO, radius: rO }
72
72
  );
73
73
  // console.log(bezierPieces.length);
74
74