flo-mat 4.0.1 → 4.0.3

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 (220) hide show
  1. package/README.md +1 -1
  2. package/__tests__/find-2-prong/get-medial/get-closest-points.spec.ts +49 -0
  3. package/__tests__/specific-cases/specific-cases.spec.ts +6 -0
  4. package/browser/index.js +9994 -12650
  5. package/browser/index.min.js +1 -1
  6. package/node/closest-boundary-point/foot-and-endpoint-info.d.ts +0 -3
  7. package/node/closest-boundary-point/get-close-boundary-points-certified.d.ts +1 -1
  8. package/node/closest-boundary-point/get-close-boundary-points-certified.js +2 -2
  9. package/node/closest-boundary-point/get-close-boundary-points-certified.js.map +1 -1
  10. package/node/closest-boundary-point/get-potential-closest-points-on-curve-certified.d.ts +1 -2
  11. package/node/closest-boundary-point/get-potential-closest-points-on-curve-certified.js +34 -24
  12. package/node/closest-boundary-point/get-potential-closest-points-on-curve-certified.js.map +1 -1
  13. package/node/closest-boundary-point/root-interval-to-distance-squared-interval.d.ts +1 -1
  14. package/node/closest-boundary-point/root-interval-to-distance-squared-interval.js +6 -9
  15. package/node/closest-boundary-point/root-interval-to-distance-squared-interval.js.map +1 -1
  16. package/node/cp-node/fs/insert-cp-node.d.ts +2 -2
  17. package/node/cp-node/fs/insert-cp-node.js.map +1 -1
  18. package/node/cp-node/fs/is-on-same-loop.d.ts +3 -0
  19. package/node/cp-node/fs/is-on-same-loop.js +6 -0
  20. package/node/cp-node/fs/is-on-same-loop.js.map +1 -0
  21. package/node/cp-node/fs/is-order-correct.d.ts +2 -2
  22. package/node/cp-node/fs/is-order-correct.js.map +1 -1
  23. package/node/cp-node/fs/traverse-cp.js.map +1 -1
  24. package/node/cp-node/fs/traverse-vertices.d.ts +1 -1
  25. package/node/cp-node/fs/traverse-vertices.js.map +1 -1
  26. package/node/debug/debug.d.ts +10 -15
  27. package/node/debug/debug.js +35 -46
  28. package/node/debug/debug.js.map +1 -1
  29. package/node/debug/functions/draw-elem/draw-branch.d.ts +1 -1
  30. package/node/debug/functions/draw-elem/draw-branch.js.map +1 -1
  31. package/node/debug/functions/draw-elem/draw-cp-node.d.ts +1 -1
  32. package/node/debug/functions/draw-elem/draw-cp-node.js +2 -2
  33. package/node/debug/functions/draw-elem/draw-cp-node.js.map +1 -1
  34. package/node/debug/functions/draw-elem/draw-leaves.d.ts +1 -1
  35. package/node/debug/functions/draw-elem/draw-leaves.js +2 -2
  36. package/node/debug/functions/draw-elem/draw-leaves.js.map +1 -1
  37. package/node/debug/functions/draw-elem/draw-mat.d.ts +1 -1
  38. package/node/debug/functions/draw-elem/draw-mat.js +1 -2
  39. package/node/debug/functions/draw-elem/draw-mat.js.map +1 -1
  40. package/node/debug/functions/draw-elem/draw-min-y.d.ts +1 -1
  41. package/node/debug/functions/draw-elem/draw-min-y.js.map +1 -1
  42. package/node/debug/functions/draw-elem/draw-three-prong.d.ts +1 -1
  43. package/node/debug/functions/draw-elem/draw-three-prong.js +2 -2
  44. package/node/debug/functions/draw-elem/draw-three-prong.js.map +1 -1
  45. package/node/debug/functions/draw-elem/draw-vertex.d.ts +1 -1
  46. package/node/debug/functions/draw-elem/draw-vertex.js +0 -2
  47. package/node/debug/functions/draw-elem/draw-vertex.js.map +1 -1
  48. package/node/error-analysis/gamma.d.ts +32 -0
  49. package/node/error-analysis/gamma.js +39 -0
  50. package/node/error-analysis/gamma.js.map +1 -0
  51. package/node/find-2-prong/add-1-prong.js +1 -4
  52. package/node/find-2-prong/add-1-prong.js.map +1 -1
  53. package/node/find-2-prong/find-2-prong.js +5 -5
  54. package/node/find-2-prong/find-2-prong.js.map +1 -1
  55. package/node/find-2-prong/get-medial/get-closest-points.js +27 -23
  56. package/node/find-2-prong/get-medial/get-closest-points.js.map +1 -1
  57. package/node/find-3-prong/calc-better-x.d.ts +1 -1
  58. package/node/find-3-prong/calc-better-x.js +6 -4
  59. package/node/find-3-prong/calc-better-x.js.map +1 -1
  60. package/node/find-3-prong/calc-initial-3-prong-center.d.ts +1 -1
  61. package/node/find-3-prong/calc-initial-3-prong-center.js +4 -3
  62. package/node/find-3-prong/calc-initial-3-prong-center.js.map +1 -1
  63. package/node/find-3-prong/find-3-prong-for-delta3s.js +22 -5
  64. package/node/find-3-prong/find-3-prong-for-delta3s.js.map +1 -1
  65. package/node/find-3-prong/find-and-add-3-prong.d.ts +2 -2
  66. package/node/find-3-prong/find-and-add-3-prong.js +15 -0
  67. package/node/find-3-prong/find-and-add-3-prong.js.map +1 -1
  68. package/node/find-3-prong/find-and-add-3-prongs-on-loop.js +8 -21
  69. package/node/find-3-prong/find-and-add-3-prongs-on-loop.js.map +1 -1
  70. package/node/find-3-prong/find-and-add-3-prongs.d.ts +1 -4
  71. package/node/find-3-prong/find-and-add-3-prongs.js +1 -2
  72. package/node/find-3-prong/find-and-add-3-prongs.js.map +1 -1
  73. package/node/find-3-prong/get-closest-points.d.ts +1 -1
  74. package/node/find-3-prong/get-closest-points.js +2 -2
  75. package/node/find-3-prong/get-closest-points.js.map +1 -1
  76. package/node/find-3-prong/timed-cc.d.ts +3 -0
  77. package/node/find-3-prong/timed-cc.js +5 -0
  78. package/node/find-3-prong/timed-cc.js.map +1 -0
  79. package/node/find-mat/create-initial-cp-tree.d.ts +2 -2
  80. package/node/find-mat/create-initial-cp-tree.js +2 -2
  81. package/node/find-mat/create-initial-cp-tree.js.map +1 -1
  82. package/node/find-mat/find-mat.d.ts +4 -4
  83. package/node/find-mat/find-mat.js +1 -2
  84. package/node/find-mat/find-mat.js.map +1 -1
  85. package/node/find-mat/find-mats.js +2 -2
  86. package/node/find-mat/find-mats.js.map +1 -1
  87. package/node/find-mat/get-meta.d.ts +1 -6
  88. package/node/find-mat/get-meta.js +4 -25
  89. package/node/find-mat/get-meta.js.map +1 -1
  90. package/node/index.d.ts +5 -2
  91. package/node/index.js +4 -1
  92. package/node/index.js.map +1 -1
  93. package/node/mat/create-new-cp-trees.d.ts +2 -2
  94. package/node/mat/create-new-cp-trees.js +2 -2
  95. package/node/mat/create-new-cp-trees.js.map +1 -1
  96. package/node/mat/get-cp-node-to-left-or-same.d.ts +2 -2
  97. package/node/mat/get-cp-node-to-left-or-same.js +2 -1
  98. package/node/mat/get-cp-node-to-left-or-same.js.map +1 -1
  99. package/node/mat/mat-meta.d.ts +2 -2
  100. package/node/point-on-shape/get-osculating-circle.js +2 -1
  101. package/node/point-on-shape/get-osculating-circle.js.map +1 -1
  102. package/node/reconstruct-from-mat/filter-zero-length.d.ts +10 -0
  103. package/node/reconstruct-from-mat/filter-zero-length.js +14 -0
  104. package/node/reconstruct-from-mat/filter-zero-length.js.map +1 -0
  105. package/node/reconstruct-from-mat/get-all-on-loop-by-loop.d.ts +7 -0
  106. package/node/reconstruct-from-mat/get-all-on-loop-by-loop.js +38 -0
  107. package/node/reconstruct-from-mat/get-all-on-loop-by-loop.js.map +1 -0
  108. package/node/reconstruct-from-mat/get-bezier-piece-length.d.ts +3 -0
  109. package/node/reconstruct-from-mat/get-bezier-piece-length.js +6 -0
  110. package/node/reconstruct-from-mat/get-bezier-piece-length.js.map +1 -0
  111. package/node/reconstruct-from-mat/get-boundary.d.ts +7 -0
  112. package/node/reconstruct-from-mat/get-boundary.js +18 -0
  113. package/node/reconstruct-from-mat/get-boundary.js.map +1 -0
  114. package/node/reconstruct-from-mat/get-cp-nodess-for-sat.d.ts +4 -0
  115. package/node/reconstruct-from-mat/get-cp-nodess-for-sat.js +15 -0
  116. package/node/reconstruct-from-mat/get-cp-nodess-for-sat.js.map +1 -0
  117. package/node/reconstruct-from-mat/get-matching-beziers.d.ts +10 -0
  118. package/node/reconstruct-from-mat/get-matching-beziers.js +29 -0
  119. package/node/reconstruct-from-mat/get-matching-beziers.js.map +1 -0
  120. package/node/reconstruct-from-mat/get-mbss-by-loop-per-sat.d.ts +6 -0
  121. package/node/reconstruct-from-mat/get-mbss-by-loop-per-sat.js +10 -0
  122. package/node/reconstruct-from-mat/get-mbss-by-loop-per-sat.js.map +1 -0
  123. package/node/reconstruct-from-mat/get-mbss-by-loop-with-opp-arr.d.ts +7 -0
  124. package/node/reconstruct-from-mat/get-mbss-by-loop-with-opp-arr.js +47 -0
  125. package/node/reconstruct-from-mat/get-mbss-by-loop-with-opp-arr.js.map +1 -0
  126. package/node/reconstruct-from-mat/get-sats2.d.ts +10 -0
  127. package/node/reconstruct-from-mat/get-sats2.js +16 -0
  128. package/node/reconstruct-from-mat/get-sats2.js.map +1 -0
  129. package/node/reconstruct-from-mat/is-fully-terminating.d.ts +3 -0
  130. package/node/reconstruct-from-mat/is-fully-terminating.js +19 -0
  131. package/node/reconstruct-from-mat/is-fully-terminating.js.map +1 -0
  132. package/node/reconstruct-from-mat/matched-beziers.d.ts +10 -0
  133. package/node/reconstruct-from-mat/matched-beziers.js +2 -0
  134. package/node/reconstruct-from-mat/matched-beziers.js.map +1 -0
  135. package/node/reconstruct-from-mat/reconstruct-from-mat.d.ts +4 -0
  136. package/node/reconstruct-from-mat/reconstruct-from-mat.js +28 -0
  137. package/node/reconstruct-from-mat/reconstruct-from-mat.js.map +1 -0
  138. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.d.ts +12 -0
  139. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js +46 -0
  140. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js.map +1 -0
  141. package/node/reconstruct-from-mat/split-tri-path.d.ts +5 -0
  142. package/node/reconstruct-from-mat/split-tri-path.js +209 -0
  143. package/node/reconstruct-from-mat/split-tri-path.js.map +1 -0
  144. package/node/sat/add-debug-info.js +1 -2
  145. package/node/sat/add-debug-info.js.map +1 -1
  146. package/node/utils/clip.d.ts +2 -0
  147. package/node/utils/clip.js +6 -0
  148. package/node/utils/clip.js.map +1 -0
  149. package/package.json +6 -7
  150. package/src/closest-boundary-point/foot-and-endpoint-info.ts +0 -3
  151. package/src/closest-boundary-point/get-close-boundary-points-certified.ts +0 -2
  152. package/src/closest-boundary-point/get-potential-closest-points-on-curve-certified.ts +41 -27
  153. package/src/closest-boundary-point/root-interval-to-distance-squared-interval.ts +5 -10
  154. package/src/cp-node/fs/insert-cp-node.ts +2 -2
  155. package/src/cp-node/fs/is-on-same-loop.ts +15 -0
  156. package/src/cp-node/fs/is-order-correct.ts +2 -2
  157. package/src/cp-node/fs/traverse-cp.ts +1 -1
  158. package/src/cp-node/fs/traverse-vertices.ts +1 -2
  159. package/src/debug/debug.ts +54 -72
  160. package/src/debug/functions/check-ordering.ts +0 -1
  161. package/src/debug/functions/draw-elem/draw-branch.ts +1 -3
  162. package/src/debug/functions/draw-elem/draw-cp-node.ts +3 -4
  163. package/src/debug/functions/draw-elem/draw-leaves.ts +3 -3
  164. package/src/debug/functions/draw-elem/draw-mat.ts +2 -5
  165. package/src/debug/functions/draw-elem/draw-min-y.ts +2 -2
  166. package/src/debug/functions/draw-elem/draw-three-prong.ts +3 -3
  167. package/src/debug/functions/draw-elem/draw-vertex.ts +1 -4
  168. package/src/error-analysis/gamma.ts +9 -2
  169. package/src/find-2-prong/add-1-prong.ts +1 -5
  170. package/src/find-2-prong/find-2-prong.ts +7 -6
  171. package/src/find-2-prong/get-medial/get-closest-points.ts +24 -26
  172. package/src/find-3-prong/calc-better-x.ts +7 -4
  173. package/src/find-3-prong/calc-initial-3-prong-center.ts +2 -3
  174. package/src/find-3-prong/find-3-prong-for-delta3s.ts +23 -5
  175. package/src/find-3-prong/find-and-add-3-prong.ts +18 -4
  176. package/src/find-3-prong/find-and-add-3-prongs-on-loop.ts +7 -23
  177. package/src/find-3-prong/find-and-add-3-prongs.ts +5 -3
  178. package/src/find-3-prong/get-closest-points.ts +0 -2
  179. package/src/find-3-prong/timed-cc.ts +9 -0
  180. package/src/find-mat/create-initial-cp-tree.ts +3 -3
  181. package/src/find-mat/find-mat.ts +6 -8
  182. package/src/find-mat/find-mats.ts +4 -2
  183. package/src/find-mat/get-meta.ts +3 -38
  184. package/src/index.ts +6 -3
  185. package/src/mat/create-new-cp-trees.ts +3 -3
  186. package/src/mat/get-cp-node-to-left-or-same.ts +4 -3
  187. package/src/mat/mat-meta.ts +2 -2
  188. package/src/point-on-shape/get-osculating-circle.ts +2 -1
  189. package/src/reconstruct-from-mat/filter-zero-length.ts +23 -0
  190. package/src/reconstruct-from-mat/get-all-on-loop-by-loop.ts +52 -0
  191. package/src/reconstruct-from-mat/get-bezier-piece-length.ts +12 -0
  192. package/src/reconstruct-from-mat/get-boundary.ts +32 -0
  193. package/src/reconstruct-from-mat/get-cp-nodess-for-sat.ts +24 -0
  194. package/src/reconstruct-from-mat/get-matching-beziers.ts +46 -0
  195. package/src/reconstruct-from-mat/get-mbss-by-loop-per-sat.ts +19 -0
  196. package/src/reconstruct-from-mat/get-mbss-by-loop-with-opp-arr.ts +69 -0
  197. package/src/reconstruct-from-mat/get-sats2.ts +25 -0
  198. package/src/reconstruct-from-mat/is-fully-terminating.ts +27 -0
  199. package/src/reconstruct-from-mat/matched-beziers.ts +14 -0
  200. package/src/reconstruct-from-mat/reconstruct-from-mat.ts +45 -0
  201. package/src/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.ts +62 -0
  202. package/src/reconstruct-from-mat/split-tri-path.ts +280 -0
  203. package/src/sat/add-debug-info.ts +1 -2
  204. package/src/utils/clip.ts +13 -0
  205. package/wallaby.mjs +1 -0
  206. package/node/closest-boundary-point/get-p-from-box.d.ts +0 -3
  207. package/node/closest-boundary-point/get-p-from-box.js +0 -11
  208. package/node/closest-boundary-point/get-p-from-box.js.map +0 -1
  209. package/node/debug/functions/general.d.ts +0 -48
  210. package/node/debug/functions/general.js +0 -53
  211. package/node/debug/functions/general.js.map +0 -1
  212. package/node/point-on-shape/pos-to-human-string.d.ts +0 -8
  213. package/node/point-on-shape/pos-to-human-string.js +0 -12
  214. package/node/point-on-shape/pos-to-human-string.js.map +0 -1
  215. package/src/debug/elem-type-two-prong.ts +0 -8
  216. package/src/debug/functions/cmp-cp-on-delta.ts +0 -54
  217. package/src/debug/functions/general.ts +0 -79
  218. package/src/debug/functions/three-prong.ts +0 -249
  219. package/src/debug/functions/two-prong.ts +0 -203
  220. package/src/find-2-prong/add-debug-info.ts +0 -45
@@ -0,0 +1,52 @@
1
+ import type { CpNode } from '../cp-node/cp-node.js';
2
+
3
+
4
+ /**
5
+ * Returns all `CpNode`s on the MAT that this `CpNode` is part of
6
+ * starting from the current one and going anti-clockwise around the shape.
7
+ */
8
+ function getAllOnLoop_ByLoop(
9
+ cpNode: CpNode) {
10
+
11
+ const cpNodess: CpNode[][] = [];
12
+
13
+ const cpStarts: CpNode[] = [cpNode];
14
+ const cpStartSet = new Set(cpStarts);
15
+ if (cpNode.isHoleClosing) {
16
+ cpStartSet.add(cpNode.prevOnCircle.holeCloserTwin!);
17
+ }
18
+ cpStartSet.add(cpNode);
19
+
20
+ while (cpStarts.length > 0) {
21
+ const cpNodes: CpNode[] = [];
22
+
23
+ const cpStart = cpStarts.pop()!;
24
+ const _loop = cpStart.pointOnShape.curve.loop;
25
+ let cpNode = cpStart;
26
+
27
+ do {
28
+ const loop = cpNode.pointOnShape.curve.loop;
29
+ if (_loop === loop) {
30
+ cpNodes.push(cpNode);
31
+ cpNode = cpNode.next;
32
+ continue;
33
+ }
34
+
35
+ const twin = cpNode.holeCloserTwin!;
36
+ if (!cpStartSet.has(twin)) {
37
+ cpStartSet.add(twin);
38
+ cpStartSet.add(twin.prevOnCircle.holeCloserTwin!);
39
+ cpStarts.push(twin);
40
+ }
41
+
42
+ cpNode = cpNode.prev.holeCloserTwin!;
43
+ } while (cpNode !== cpStart);
44
+
45
+ cpNodess.push(cpNodes);
46
+ }
47
+
48
+ return cpNodess;
49
+ }
50
+
51
+
52
+ export { getAllOnLoop_ByLoop }
@@ -0,0 +1,12 @@
1
+ import type { BezierPiece } from "flo-bezier3";
2
+ import { length } from 'flo-bezier3';
3
+
4
+
5
+ function getBezierPieceLength(
6
+ bezierPiece: BezierPiece): number {
7
+
8
+ return length(bezierPiece.ts, bezierPiece.ps);
9
+ }
10
+
11
+
12
+ export { getBezierPieceLength }
@@ -0,0 +1,32 @@
1
+ import type { BezierPiece } from 'flo-bezier3';
2
+ import type { CpNode } from '../cp-node/cp-node.js';
3
+ import { getBoundaryBezierPartsToNext } from '../cp-node/fs/get-boundary-bezier-parts-to-next.js';
4
+ import { filterZeroLength } from "./filter-zero-length.js";
5
+ import { isFullyTerminating } from './is-fully-terminating.js';
6
+
7
+
8
+ function getBoundary(
9
+ cpNode: CpNode): {
10
+ boundaryBeziers: BezierPiece[];
11
+ boundaryBeziersOpp: BezierPiece[] | undefined;
12
+ } {
13
+
14
+ const cpNodeOpp = isFullyTerminating(cpNode)
15
+ ? undefined // no opposite boundary
16
+ : cpNode.next.prevOnCircle;
17
+
18
+ const boundaryBeziers =
19
+ filterZeroLength(getBoundaryBezierPartsToNext(cpNode));
20
+
21
+ const boundaryBeziersOpp = cpNodeOpp === undefined
22
+ ? undefined
23
+ : filterZeroLength(getBoundaryBezierPartsToNext(cpNodeOpp));
24
+
25
+ return {
26
+ boundaryBeziers,
27
+ boundaryBeziersOpp
28
+ };
29
+ }
30
+
31
+
32
+ export { getBoundary }
@@ -0,0 +1,24 @@
1
+ import type { CpNode } from "../cp-node/cp-node.js";
2
+ import type { Mat } from '../mat/mat.js';
3
+ import { isOnSameLoop } from "../cp-node/fs/is-on-same-loop.js";
4
+ import { isFullyTerminating } from "./is-fully-terminating.js";
5
+ import { getAllOnLoop_ByLoop } from "./get-all-on-loop-by-loop.js";
6
+
7
+
8
+ function getCpNodessForSat(
9
+ sat: Mat): CpNode[][] {
10
+
11
+ let { cpNode } = sat;
12
+
13
+ while (!isFullyTerminating(cpNode)) {
14
+ cpNode = cpNode.next;
15
+ }
16
+ if (!isOnSameLoop(cpNode, cpNode.next)) {
17
+ cpNode = cpNode.holeCloserTwin!;
18
+ }
19
+
20
+ return getAllOnLoop_ByLoop(cpNode);
21
+ }
22
+
23
+
24
+ export { getCpNodessForSat }
@@ -0,0 +1,46 @@
1
+ import type { BezierPiece } from 'flo-bezier3';
2
+ import type { CpNode } from '../cp-node/cp-node.js';
3
+ import type { MatchedBeziers } from './matched-beziers.js';
4
+ import { getMatCurveToNext } from '../cp-node/fs/get-mat-curve-to-next.js'
5
+ import { splitTriPath } from './split-tri-path.js';
6
+ import { getBoundary } from './get-boundary.js';
7
+ import { isOnSameLoop } from '../cp-node/fs/is-on-same-loop.js';
8
+
9
+
10
+ /**
11
+ * Returns a correspondence between boundary bezier curves and a medial axis
12
+ * bezier curve. They will later be interpolated.
13
+ *
14
+ * @param cpNode the start `CpNode`
15
+ */
16
+ function getMatchingBeziers(
17
+ cpNode: CpNode): MatchedBeziers[] | undefined {
18
+
19
+ const medialBezier: BezierPiece = {
20
+ ps: getMatCurveToNext(cpNode),
21
+ ts: [0,1]
22
+ };
23
+
24
+ if (cpNode.isHoleClosing && // short-circuit
25
+ !isOnSameLoop(cpNode, cpNode.next)) {
26
+
27
+ // We get here for half of hole-closers, as only half of hole-closers are on a different loop.
28
+ // This cpNode indicates we should connect the hole
29
+ // console.log('hole-closing dummy case');
30
+ return undefined;
31
+ }
32
+
33
+ const r = getBoundary(cpNode);
34
+ const { boundaryBeziers, boundaryBeziersOpp } = r;
35
+
36
+ const matchedBezierss: MatchedBeziers[] = splitTriPath(
37
+ boundaryBeziers,
38
+ medialBezier,
39
+ boundaryBeziersOpp ?? []
40
+ );
41
+
42
+ return matchedBezierss;
43
+ }
44
+
45
+
46
+ export { getMatchingBeziers }
@@ -0,0 +1,19 @@
1
+ import type { Mat } from "../mat/mat.js";
2
+ import { getSats2 } from "./get-sats2.js";
3
+ import { getMbssByLoopWithOppArr } from "./get-mbss-by-loop-with-opp-arr.js";
4
+ import { getCpNodessForSat } from "./get-cp-nodess-for-sat.js";
5
+
6
+
7
+ function getMbssByLoopPerSat(
8
+ mats: Mat[],
9
+ satScale: number) {
10
+
11
+ const sats = getSats2(mats, satScale);
12
+
13
+ const cpNodessPerSat = sats.map(getCpNodessForSat);
14
+
15
+ return cpNodessPerSat.map(getMbssByLoopWithOppArr);
16
+ }
17
+
18
+
19
+ export { getMbssByLoopPerSat }
@@ -0,0 +1,69 @@
1
+ import type { CpNode } from "../cp-node/cp-node.js";
2
+ import type { MatchedBeziers } from "./matched-beziers.js";
3
+ import { getMatchingBeziers } from "./get-matching-beziers.js";
4
+ import { isFullyTerminating } from "./is-fully-terminating.js";
5
+
6
+
7
+ function getMbssByLoopWithOppArr(
8
+ cpNodess: CpNode[][]) {
9
+
10
+ const mbssByLoop: (MatchedBeziers[] | undefined)[][] = [];
11
+
12
+ /**
13
+ * An array with each entry being a pair of indices mapping from
14
+ * `MatchedBeziers[]` on one side to `MatchedBeziers[]` on the other side
15
+ */
16
+ const mbMap: Map<CpNode, [number,number]> = new Map();
17
+
18
+ for (let l=0; l<cpNodess.length; l++) {
19
+ const cpNodes = cpNodess[l];
20
+
21
+ const mbss: (MatchedBeziers[] | undefined)[] = [];
22
+ for (let i=0; i<cpNodes.length; i++) {
23
+ const cpNode = cpNodes[i];
24
+
25
+ mbMap.set(cpNode, [l,i]);
26
+
27
+ const mbs = getMatchingBeziers(cpNode);
28
+
29
+ mbss.push(mbs);
30
+ }
31
+
32
+ mbssByLoop.push(mbss);
33
+ }
34
+
35
+
36
+ const oppArr: [[number,number],[number,number]][] = [];
37
+
38
+ for (let l=0; l<cpNodess.length; l++) {
39
+ const cpNodes = cpNodess[l];
40
+
41
+ for (let i=0; i<cpNodes.length; i++) {
42
+ const cpNode = cpNodes[i];
43
+
44
+ const cpNodeOpp = isFullyTerminating(cpNode)
45
+ ? undefined // no opposite boundary
46
+ : cpNode.next.prevOnCircle;
47
+
48
+ // if (cpNodeOpp === undefined) {
49
+ // continue;
50
+ // }
51
+
52
+ const oppIdxs = cpNodeOpp === undefined
53
+ ? [255,65535] as [number,number]
54
+ : mbMap.get(cpNodeOpp);
55
+
56
+ const mbs = mbssByLoop[l][i];
57
+ if (oppIdxs !== undefined && mbs !== undefined) {
58
+ oppArr.push([[l,i], oppIdxs]);
59
+ } else {
60
+ oppArr.push([[l,i], [255,65535]]);
61
+ }
62
+ }
63
+ }
64
+
65
+ return { mbssByLoop, oppArr };
66
+ }
67
+
68
+
69
+ export { getMbssByLoopWithOppArr }
@@ -0,0 +1,25 @@
1
+ import type { Mat } from '../mat/mat.js';
2
+ import { findMats } from '../find-mat/find-mats.js';
3
+ import { removeSatInducedTrivial3Prongs } from "./remove-sat-induced-trivial-3prongs.js";
4
+ import { toScaleAxis } from '../sat/to-scale-axis.js';
5
+
6
+
7
+ /**
8
+ * Returns the shape information.
9
+ *
10
+ * @param font$$ the font from which the glyph outlines will be retrieved
11
+ * @param glyphId the glyph id for which the shape is to be retrieved
12
+ * @param options the options for SAT computation
13
+ */
14
+ // TODO
15
+ function getSats2(
16
+ mats: Mat[],
17
+ satScale: number): Mat[] {
18
+
19
+ const sats = mats.map(mat => toScaleAxis(mat, satScale));
20
+
21
+ return sats.map(removeSatInducedTrivial3Prongs);
22
+ }
23
+
24
+
25
+ export { getSats2 }
@@ -0,0 +1,27 @@
1
+ import type { CpNode } from '../cp-node/cp-node.js';
2
+ import { getAllOnCircle } from '../cp-node/fs/get-all-on-circle.js';
3
+ import { isTerminating } from '../cp-node/fs/is-terminating.js';
4
+ import { isTrivial } from '../cp-node/fs/is-trivial.js';
5
+
6
+
7
+ // TODO - DUPLICATE! -> likely other version needs fixing
8
+ function isFullyTerminating(cpNode: CpNode) {
9
+ if (!isTerminating(cpNode)) {
10
+ return false;
11
+ }
12
+
13
+ if (isTrivial(cpNode)) {
14
+ return true;
15
+ }
16
+
17
+ while (cpNode.prev === cpNode.prevOnCircle) {
18
+ cpNode = cpNode.prev;
19
+ }
20
+
21
+ const otherOnCircle = getAllOnCircle(cpNode.prevOnCircle, true);
22
+
23
+ return otherOnCircle.every(isTerminating);
24
+ }
25
+
26
+
27
+ export { isFullyTerminating }
@@ -0,0 +1,14 @@
1
+ import type { BezierPiece } from 'flo-bezier3';
2
+
3
+
4
+ /**
5
+ * A type representing a correspondence between 3 bezier curves (one on the
6
+ * boundary, one on the medial axis and one on the opposite boundary)
7
+ */
8
+ interface MatchedBeziers {
9
+ readonly medialBezier: BezierPiece;
10
+ readonly boundaryBezier: BezierPiece;
11
+ }
12
+
13
+
14
+ export type { MatchedBeziers }
@@ -0,0 +1,45 @@
1
+ import type { BezierPiece } from 'flo-bezier3';
2
+ import type { Mat } from '../mat/mat.js';
3
+ import { getMbssByLoopPerSat } from './get-mbss-by-loop-per-sat.js';
4
+ import { getMbssByLoopWithOppArr } from './get-mbss-by-loop-with-opp-arr.js';
5
+
6
+
7
+ function reconstructFromMats(
8
+ mats: Mat[]) {
9
+
10
+ const loopss: number[][][][] = [];
11
+
12
+ const bzs: BezierPiece[] = [];
13
+
14
+ const mbssByLoopPerSat = getMbssByLoopPerSat(mats, 1.5)!;
15
+
16
+ for (const mbssByLoopPS of mbssByLoopPerSat) {
17
+ const { mbssByLoop, oppArr } = mbssByLoopPS;
18
+
19
+ for (let l=0; l<mbssByLoop.length; l++) {
20
+ const rs = mbssByLoop[l];
21
+
22
+ for (let i=0; i<rs.length; i++) {
23
+ const r = mbssByLoop[l][i];
24
+
25
+ if (r === undefined) { continue; }
26
+
27
+ const matchedBezierss = r;
28
+
29
+ for (let j=0; j<matchedBezierss.length; j++) {
30
+ const mb = matchedBezierss[j];
31
+ const { boundaryBezier, medialBezier } = mb;
32
+
33
+ bzs.push(boundaryBezier)
34
+ }
35
+ }
36
+ }
37
+ }
38
+
39
+
40
+ return bzs;
41
+ // return loopss;
42
+ }
43
+
44
+
45
+ export { reconstructFromMats }
@@ -0,0 +1,62 @@
1
+ import type { Mutable } from '../utils/mutable.js';
2
+ import type { Mat } from '../mat/mat.js';
3
+ import { isFullyTerminating } from './is-fully-terminating.js';
4
+
5
+
6
+ /**
7
+ * In-place removes trivial 3-prongs from the SAT graph; just to simplify
8
+ * subsequent processing.
9
+ *
10
+ * These are 3-prongs that are induced by the SAT construction, and do
11
+ * not correspond to actual 3-prongs in the shape.
12
+ *
13
+ * @param sat the SAT
14
+ */
15
+ function removeSatInducedTrivial3Prongs(
16
+ sat: Mat): Mat {
17
+
18
+ let { cpNode } = sat;
19
+
20
+ let cpStart = cpNode;
21
+ do {
22
+ if (isFullyTerminating(cpNode) ||
23
+ // cpNode.isHoleClosing || // hole-closers are fully terminating
24
+ cpNode.next !== cpNode.nextOnCircle) {
25
+
26
+ cpNode = cpNode.next;
27
+ continue;
28
+ }
29
+
30
+ //-----------------------------
31
+ // Delete the trivial 3-prong
32
+ //-----------------------------
33
+ // console.log('Removing SAT-induced trivial 3-prong');
34
+
35
+ const next = cpNode.next;
36
+ const nextNext = next.next;
37
+ const nextNextOC = cpNode.next.nextOnCircle;
38
+
39
+ //-------------------------------------------------------------
40
+ // In-place update of links to remove the trivial 3-prong node
41
+ //-------------------------------------------------------------
42
+ (cpNode as Mutable<typeof cpNode>).next = nextNext;
43
+ (cpNode as Mutable<typeof cpNode>).nextOnCircle = nextNextOC;
44
+ (nextNext as Mutable<typeof nextNext>).prev = cpNode;
45
+ (nextNextOC as Mutable<typeof nextNextOC>).prevOnCircle = cpNode;
46
+ //-------------------------------------------------------------
47
+
48
+ if (cpStart === next) {
49
+ cpStart = cpNode; // ...otherwise the loop will never terminate
50
+ }
51
+
52
+ cpNode = cpNode.next;
53
+ } while (cpNode !== cpStart)
54
+
55
+ // ...otherwise the caller will have a reference to a node that has been removed from the graph
56
+ (sat as Mutable<Mat>).cpNode = cpNode;
57
+
58
+ return sat;
59
+ }
60
+
61
+
62
+ export { removeSatInducedTrivial3Prongs }