flo-mat 4.1.5 → 5.0.2

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 (356) hide show
  1. package/__tests__/closest-boundary-point/get-endpoint-info.spec.ts +140 -0
  2. package/__tests__/closest-boundary-point/root-interval-to-distance-squared-interval.spec.ts +87 -0
  3. package/__tests__/cp-node/fs/get-all-on-loop-by-loop.spec.ts +55 -0
  4. package/__tests__/cp-node/fs/get-angle-between-mat-curves.spec.ts +39 -3
  5. package/__tests__/cp-node/fs/get-boundary-bezier-parts-to-next.spec.ts +87 -3
  6. package/__tests__/cp-node/fs/get-boundary-beziers-between.spec.ts +68 -3
  7. package/__tests__/cp-node/fs/get-boundary-beziers-to-next.spec.ts +41 -3
  8. package/__tests__/cp-node/fs/get-boundary-distance-to-next.spec.ts +20 -3
  9. package/__tests__/cp-node/fs/get-branch-beziers.spec.ts +42 -3
  10. package/__tests__/cp-node/fs/get-branch.spec.ts +60 -3
  11. package/__tests__/cp-node/fs/get-cp-node-ordering.spec.ts +19 -3
  12. package/__tests__/cp-node/fs/get-distance-to-next.spec.ts +37 -4
  13. package/__tests__/cp-node/fs/get-edge-direction.spec.ts +50 -3
  14. package/__tests__/cp-node/fs/get-first-exit.spec.ts +78 -3
  15. package/__tests__/cp-node/fs/get-hole-closers.spec.ts +32 -3
  16. package/__tests__/cp-node/fs/get-implied-boundary-bezier-between.spec.ts +48 -3
  17. package/__tests__/cp-node/fs/get-mat-curve-between.spec.ts +77 -3
  18. package/__tests__/cp-node/fs/get-mat-curve-to-next.spec.ts +17 -4
  19. package/__tests__/cp-node/fs/get-mat-curves-between.spec.ts +38 -3
  20. package/__tests__/cp-node/fs/get-salience.spec.ts +68 -3
  21. package/__tests__/cp-node/fs/get-vertex-forward-children.spec.ts +40 -3
  22. package/__tests__/cp-node/fs/insert-cp-node.spec.ts +87 -3
  23. package/__tests__/cp-node/fs/is-special.spec.ts +1 -1
  24. package/__tests__/cp-node/fs/remove-cp-node.spec.ts +42 -3
  25. package/__tests__/find-2-prong/calc-seperation-tolerance.spec.ts +46 -0
  26. package/__tests__/find-2-prong/get-medial/get-closest-points.spec.ts +1 -1
  27. package/__tests__/floyd-warshall/get-graph.spec.ts +100 -0
  28. package/__tests__/get-mats-with-hole.ts +28 -0
  29. package/__tests__/get-mats1.spec.ts +61 -0
  30. package/__tests__/get-mats1.ts +75 -67
  31. package/__tests__/helpers/cp-node-by-id.ts +27 -0
  32. package/__tests__/helpers/expect-point-close.ts +42 -0
  33. package/__tests__/mat/hausdorff-distance-one-sided-exceeds.spec.ts +129 -0
  34. package/__tests__/mat/simplify-mat.spec.ts +85 -0
  35. package/__tests__/reconstruct-from-mat/reconstruct-from-mat.spec.ts +39 -0
  36. package/__tests__/specific-cases/test-svgs/achispado.svg +14 -0
  37. package/__tests__/utils/get-beziers-from-tangents.spec.ts +142 -0
  38. package/browser/index.js +12985 -9965
  39. package/browser/index.min.js +1 -1
  40. package/node/closest-boundary-point/cull-curve-pieces.d.ts +21 -0
  41. package/node/closest-boundary-point/cull-curve-pieces.js +40 -0
  42. package/node/closest-boundary-point/cull-curve-pieces.js.map +1 -0
  43. package/node/closest-boundary-point/get-close-boundary-points-certified.js +5 -2
  44. package/node/closest-boundary-point/get-close-boundary-points-certified.js.map +1 -1
  45. package/node/closest-boundary-point/get-endpoint-info.d.ts +39 -0
  46. package/node/closest-boundary-point/get-endpoint-info.js +78 -0
  47. package/node/closest-boundary-point/get-endpoint-info.js.map +1 -0
  48. package/node/closest-boundary-point/get-potential-closest-points-on-curve-certified.js +5 -19
  49. package/node/closest-boundary-point/get-potential-closest-points-on-curve-certified.js.map +1 -1
  50. package/node/closest-boundary-point/root-interval-to-distance-squared-interval.d.ts +17 -5
  51. package/node/closest-boundary-point/root-interval-to-distance-squared-interval.js +37 -50
  52. package/node/closest-boundary-point/root-interval-to-distance-squared-interval.js.map +1 -1
  53. package/node/corner/get-corner.d.ts +18 -1
  54. package/node/corner/get-corner.js +8 -1
  55. package/node/corner/get-corner.js.map +1 -1
  56. package/node/corner/get-interface-ccw.js.map +1 -1
  57. package/node/cp-node/cp-node.d.ts +4 -3
  58. package/node/cp-node/fs/get-all-on-loop-by-loop.js +0 -4
  59. package/node/cp-node/fs/get-all-on-loop-by-loop.js.map +1 -1
  60. package/node/cp-node/fs/get-angle-between-mat-curves.js +6 -4
  61. package/node/cp-node/fs/get-angle-between-mat-curves.js.map +1 -1
  62. package/node/cp-node/fs/get-boundary-beziers-between.d.ts +6 -4
  63. package/node/cp-node/fs/get-boundary-beziers-between.js +6 -4
  64. package/node/cp-node/fs/get-boundary-beziers-between.js.map +1 -1
  65. package/node/cp-node/fs/get-branch-beziers.d.ts +2 -1
  66. package/node/cp-node/fs/get-branch-beziers.js +3 -2
  67. package/node/cp-node/fs/get-branch-beziers.js.map +1 -1
  68. package/node/cp-node/fs/get-branch.js +1 -2
  69. package/node/cp-node/fs/get-branch.js.map +1 -1
  70. package/node/cp-node/fs/get-distance-to-next.js +4 -2
  71. package/node/cp-node/fs/get-distance-to-next.js.map +1 -1
  72. package/node/cp-node/fs/get-first-exit.d.ts +7 -3
  73. package/node/cp-node/fs/get-first-exit.js +13 -11
  74. package/node/cp-node/fs/get-first-exit.js.map +1 -1
  75. package/node/cp-node/fs/get-implied-boundary-bezier-between.d.ts +9 -1
  76. package/node/cp-node/fs/get-implied-boundary-bezier-between.js +11 -55
  77. package/node/cp-node/fs/get-implied-boundary-bezier-between.js.map +1 -1
  78. package/node/cp-node/fs/get-mat-curve-between.d.ts +4 -3
  79. package/node/cp-node/fs/get-mat-curve-between.js +5 -49
  80. package/node/cp-node/fs/get-mat-curve-between.js.map +1 -1
  81. package/node/cp-node/fs/get-mat-curve-to-next.d.ts +1 -1
  82. package/node/cp-node/fs/get-mat-curves-between.d.ts +8 -0
  83. package/node/cp-node/fs/get-mat-curves-between.js +9 -2
  84. package/node/cp-node/fs/get-mat-curves-between.js.map +1 -1
  85. package/node/cp-node/fs/get-real-prong-count.d.ts +2 -1
  86. package/node/cp-node/fs/get-real-prong-count.js +11 -5
  87. package/node/cp-node/fs/get-real-prong-count.js.map +1 -1
  88. package/node/cp-node/fs/get-salience.d.ts +10 -0
  89. package/node/cp-node/fs/get-salience.js +17 -1
  90. package/node/cp-node/fs/get-salience.js.map +1 -1
  91. package/node/cp-node/fs/is-fully-terminating.d.ts +4 -2
  92. package/node/cp-node/fs/is-fully-terminating.js +6 -15
  93. package/node/cp-node/fs/is-fully-terminating.js.map +1 -1
  94. package/node/cp-node/fs/is-on-same-loop.d.ts +1 -1
  95. package/node/cp-node/fs/is-special.d.ts +7 -0
  96. package/node/cp-node/fs/is-special.js +9 -2
  97. package/node/cp-node/fs/is-special.js.map +1 -1
  98. package/node/cp-node/fs/is-vertex.d.ts +1 -1
  99. package/node/cp-node/fs/traverse-edges.d.ts +7 -3
  100. package/node/cp-node/fs/traverse-edges.js +7 -3
  101. package/node/cp-node/fs/traverse-edges.js.map +1 -1
  102. package/node/cp-node/stringification/from-stringifyable.d.ts +2 -2
  103. package/node/cp-node/stringification/from-stringifyable.js +1 -1
  104. package/node/cp-node/stringification/from-stringifyable.js.map +1 -1
  105. package/node/cp-node/stringification/to-stringifyable.d.ts +3 -3
  106. package/node/cp-node/stringification/to-stringifyable.js +3 -3
  107. package/node/debug/debug.d.ts +26 -3
  108. package/node/debug/debug.js +16 -5
  109. package/node/debug/debug.js.map +1 -1
  110. package/node/find-2-prong/add-2-prong.js +1 -7
  111. package/node/find-2-prong/add-2-prong.js.map +1 -1
  112. package/node/find-2-prong/calc-seperation-tolerance.d.ts +28 -5
  113. package/node/find-2-prong/calc-seperation-tolerance.js +32 -89
  114. package/node/find-2-prong/calc-seperation-tolerance.js.map +1 -1
  115. package/node/find-2-prong/find-2-prong.js +8 -10
  116. package/node/find-2-prong/find-2-prong.js.map +1 -1
  117. package/node/find-2-prong/find-and-add-2-prongs.js +2 -2
  118. package/node/find-2-prong/find-and-add-2-prongs.js.map +1 -1
  119. package/node/find-2-prong/get-medial/get-antipodal-points.d.ts +1 -2
  120. package/node/find-2-prong/get-medial/get-antipodal-points.js +2 -3
  121. package/node/find-2-prong/get-medial/get-antipodal-points.js.map +1 -1
  122. package/node/find-2-prong/get-medial/get-closest-points.d.ts +1 -8
  123. package/node/find-2-prong/get-medial/get-closest-points.js +4 -40
  124. package/node/find-2-prong/get-medial/get-closest-points.js.map +1 -1
  125. package/node/find-2-prong/reduce-radius.d.ts +1 -1
  126. package/node/find-2-prong/reduce-radius.js +6 -3
  127. package/node/find-2-prong/reduce-radius.js.map +1 -1
  128. package/node/find-3-prong/calc-better-x.js +1 -1
  129. package/node/find-3-prong/calc-better-x.js.map +1 -1
  130. package/node/find-3-prong/find-3-prong-for-delta3s.d.ts +3 -2
  131. package/node/find-3-prong/find-3-prong-for-delta3s.js +35 -41
  132. package/node/find-3-prong/find-3-prong-for-delta3s.js.map +1 -1
  133. package/node/find-3-prong/find-3-prong.js +3 -1
  134. package/node/find-3-prong/find-3-prong.js.map +1 -1
  135. package/node/find-3-prong/find-and-add-3-prongs.js +16 -0
  136. package/node/find-3-prong/find-and-add-3-prongs.js.map +1 -1
  137. package/node/find-mat/create-initial-cp-tree.js +2 -2
  138. package/node/find-mat/create-initial-cp-tree.js.map +1 -1
  139. package/node/find-mat/find-mat.js +3 -4
  140. package/node/find-mat/find-mat.js.map +1 -1
  141. package/node/find-mat/find-mats.d.ts +6 -12
  142. package/node/find-mat/find-mats.js +10 -27
  143. package/node/find-mat/find-mats.js.map +1 -1
  144. package/node/find-mat/get-dull-corners-on-loop.js +2 -2
  145. package/node/find-mat/get-dull-corners-on-loop.js.map +1 -1
  146. package/node/find-mat/get-for-1-prongs-on-loop.js +36 -8
  147. package/node/find-mat/get-for-1-prongs-on-loop.js.map +1 -1
  148. package/node/find-mat/get-meta.d.ts +14 -4
  149. package/node/find-mat/get-meta.js +30 -24
  150. package/node/find-mat/get-meta.js.map +1 -1
  151. package/node/find-mat/get-sharp-corners.js +2 -2
  152. package/node/find-mat/get-sharp-corners.js.map +1 -1
  153. package/node/find-mat/mat-options.d.ts +2 -2
  154. package/node/floyd-warshall/get-graph.d.ts +12 -1
  155. package/node/floyd-warshall/get-graph.js +41 -38
  156. package/node/floyd-warshall/get-graph.js.map +1 -1
  157. package/node/geometry/get-bounding-box-.d.ts +16 -2
  158. package/node/geometry/get-bounding-box-.js +5 -2
  159. package/node/geometry/get-bounding-box-.js.map +1 -1
  160. package/node/geometry/get-closest-square-distance-to-rect.d.ts +3 -0
  161. package/node/geometry/get-closest-square-distance-to-rect.js +7 -5
  162. package/node/geometry/get-closest-square-distance-to-rect.js.map +1 -1
  163. package/node/geometry/get-closest-squared-distance-to-rotated-rect.d.ts +4 -0
  164. package/node/geometry/get-closest-squared-distance-to-rotated-rect.js +11 -5
  165. package/node/geometry/get-closest-squared-distance-to-rotated-rect.js.map +1 -1
  166. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.js +1 -2
  167. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.js.map +1 -1
  168. package/node/index.d.ts +3 -2
  169. package/node/index.js +2 -1
  170. package/node/index.js.map +1 -1
  171. package/node/mat/clone-mat.d.ts +9 -0
  172. package/node/mat/clone-mat.js +17 -0
  173. package/node/mat/clone-mat.js.map +1 -0
  174. package/node/mat/clone-meta.d.ts +12 -0
  175. package/node/mat/clone-meta.js +24 -0
  176. package/node/mat/clone-meta.js.map +1 -0
  177. package/node/mat/get-boundary-piece-beziers.d.ts +5 -0
  178. package/node/mat/get-boundary-piece-beziers.js +7 -93
  179. package/node/mat/get-boundary-piece-beziers.js.map +1 -1
  180. package/node/mat/get-largest-3-prong.d.ts +6 -0
  181. package/node/mat/get-largest-3-prong.js +8 -5
  182. package/node/mat/get-largest-3-prong.js.map +1 -1
  183. package/node/mat/get-largest-vertex.d.ts +15 -1
  184. package/node/mat/get-largest-vertex.js +20 -7
  185. package/node/mat/get-largest-vertex.js.map +1 -1
  186. package/node/mat/hausdorff-distance-one-sided-exceeds.d.ts +79 -0
  187. package/node/mat/hausdorff-distance-one-sided-exceeds.js +251 -0
  188. package/node/mat/hausdorff-distance-one-sided-exceeds.js.map +1 -0
  189. package/node/mat/mat-meta.d.ts +0 -6
  190. package/node/mat/simplify-mat.d.ts +25 -8
  191. package/node/mat/simplify-mat.js +182 -53
  192. package/node/mat/simplify-mat.js.map +1 -1
  193. package/node/mat/trim-mat.d.ts +4 -2
  194. package/node/mat/trim-mat.js +3 -1
  195. package/node/mat/trim-mat.js.map +1 -1
  196. package/node/point-on-shape/get-boundary-tangent-line.d.ts +19 -0
  197. package/node/point-on-shape/get-boundary-tangent-line.js +33 -0
  198. package/node/point-on-shape/get-boundary-tangent-line.js.map +1 -0
  199. package/node/point-on-shape/get-osculating-circle.d.ts +6 -4
  200. package/node/point-on-shape/get-osculating-circle.js +6 -4
  201. package/node/point-on-shape/get-osculating-circle.js.map +1 -1
  202. package/node/point-on-shape/get-pos-corner.js +2 -2
  203. package/node/point-on-shape/get-pos-corner.js.map +1 -1
  204. package/node/reconstruct-from-mat/reconstruct-from-mat.js +20 -80
  205. package/node/reconstruct-from-mat/reconstruct-from-mat.js.map +1 -1
  206. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.d.ts +4 -0
  207. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js +4 -0
  208. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js.map +1 -1
  209. package/node/sat/cull.d.ts +7 -6
  210. package/node/sat/cull.js +13 -16
  211. package/node/sat/cull.js.map +1 -1
  212. package/node/sat/get-sat-culls.d.ts +12 -2
  213. package/node/sat/get-sat-culls.js +21 -16
  214. package/node/sat/get-sat-culls.js.map +1 -1
  215. package/node/svg/get-shape-bounds.d.ts +1 -12
  216. package/node/svg/get-shape-bounds.js +2 -3
  217. package/node/svg/get-shape-bounds.js.map +1 -1
  218. package/node/sweep-line/sweep-line.js.map +1 -1
  219. package/node/utils/get-beziers-from-tangents.d.ts +28 -0
  220. package/node/utils/get-beziers-from-tangents.js +92 -0
  221. package/node/utils/get-beziers-from-tangents.js.map +1 -0
  222. package/node/vertex/remove-vertex.d.ts +5 -3
  223. package/node/vertex/remove-vertex.js +5 -3
  224. package/node/vertex/remove-vertex.js.map +1 -1
  225. package/package.json +9 -9
  226. package/qv-infinite-loop.md +120 -0
  227. package/src/closest-boundary-point/cull-curve-pieces.ts +49 -0
  228. package/src/closest-boundary-point/get-close-boundary-points-certified.ts +5 -2
  229. package/src/closest-boundary-point/get-endpoint-info.ts +96 -0
  230. package/src/closest-boundary-point/get-potential-closest-points-on-curve-certified.ts +5 -23
  231. package/src/closest-boundary-point/root-interval-to-distance-squared-interval.ts +42 -60
  232. package/src/corner/get-corner.ts +10 -1
  233. package/src/corner/get-interface-ccw.ts +2 -2
  234. package/src/cp-node/cp-node.ts +4 -3
  235. package/src/cp-node/fs/get-all-on-loop-by-loop.ts +0 -4
  236. package/src/cp-node/fs/get-angle-between-mat-curves.ts +6 -4
  237. package/src/cp-node/fs/get-boundary-beziers-between.ts +10 -8
  238. package/src/cp-node/fs/get-branch-beziers.ts +3 -2
  239. package/src/cp-node/fs/get-branch.ts +1 -2
  240. package/src/cp-node/fs/get-distance-to-next.ts +4 -2
  241. package/src/cp-node/fs/get-first-exit.ts +15 -14
  242. package/src/cp-node/fs/get-implied-boundary-bezier-between.ts +17 -69
  243. package/src/cp-node/fs/get-mat-curve-between.ts +9 -67
  244. package/src/cp-node/fs/get-mat-curves-between.ts +9 -2
  245. package/src/cp-node/fs/get-real-prong-count.ts +11 -7
  246. package/src/cp-node/fs/get-salience.ts +15 -2
  247. package/src/cp-node/fs/is-fully-terminating.ts +6 -18
  248. package/src/cp-node/fs/is-on-same-loop.ts +2 -2
  249. package/src/cp-node/fs/is-special.ts +11 -6
  250. package/src/cp-node/fs/is-vertex.ts +1 -1
  251. package/src/cp-node/fs/traverse-edges.ts +8 -4
  252. package/src/cp-node/stringification/from-stringifyable.ts +75 -75
  253. package/src/cp-node/stringification/to-stringifyable.ts +3 -3
  254. package/src/debug/debug.ts +44 -8
  255. package/src/find-2-prong/add-2-prong.ts +2 -9
  256. package/src/find-2-prong/calc-seperation-tolerance.ts +34 -115
  257. package/src/find-2-prong/find-2-prong.ts +9 -11
  258. package/src/find-2-prong/find-and-add-2-prongs.ts +2 -2
  259. package/src/find-2-prong/get-medial/get-antipodal-points.ts +1 -3
  260. package/src/find-2-prong/get-medial/get-closest-points.ts +6 -51
  261. package/src/find-2-prong/reduce-radius.ts +6 -4
  262. package/src/find-3-prong/calc-better-x.ts +2 -2
  263. package/src/find-3-prong/find-3-prong-for-delta3s.ts +197 -214
  264. package/src/find-3-prong/find-3-prong.ts +54 -51
  265. package/src/find-3-prong/find-and-add-3-prongs.ts +20 -1
  266. package/src/find-mat/create-initial-cp-tree.ts +2 -2
  267. package/src/find-mat/find-mat.ts +4 -6
  268. package/src/find-mat/find-mats.ts +83 -105
  269. package/src/find-mat/get-dull-corners-on-loop.ts +2 -2
  270. package/src/find-mat/get-for-1-prongs-on-loop.ts +40 -8
  271. package/src/find-mat/get-meta.ts +34 -39
  272. package/src/find-mat/get-sharp-corners.ts +2 -2
  273. package/src/find-mat/mat-options.ts +2 -2
  274. package/src/floyd-warshall/get-graph.ts +46 -47
  275. package/src/geometry/get-bounding-box-.ts +5 -2
  276. package/src/geometry/get-closest-square-distance-to-rect.ts +7 -7
  277. package/src/geometry/get-closest-squared-distance-to-rotated-rect.ts +12 -10
  278. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.ts +1 -2
  279. package/src/index.ts +3 -2
  280. package/src/mat/clone-mat.ts +9 -3
  281. package/src/mat/clone-meta.ts +8 -0
  282. package/src/mat/get-boundary-piece-beziers.ts +16 -117
  283. package/src/mat/get-largest-3-prong.ts +9 -6
  284. package/src/mat/get-largest-vertex.ts +25 -9
  285. package/src/mat/hausdorff-distance-one-sided-exceeds.ts +314 -0
  286. package/src/mat/mat-meta.ts +0 -9
  287. package/src/mat/simplify-mat.ts +254 -116
  288. package/src/mat/trim-mat.ts +6 -4
  289. package/src/point-on-shape/get-boundary-tangent-line.ts +36 -0
  290. package/src/point-on-shape/get-osculating-circle.ts +7 -5
  291. package/src/point-on-shape/get-pos-corner.ts +2 -2
  292. package/src/reconstruct-from-mat/reconstruct-from-mat.ts +22 -111
  293. package/src/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.ts +4 -0
  294. package/src/sat/cull.ts +16 -20
  295. package/src/sat/get-sat-culls.ts +28 -23
  296. package/src/svg/get-shape-bounds.ts +2 -3
  297. package/src/sweep-line/sweep-line.ts +1 -1
  298. package/src/utils/get-beziers-from-tangents.ts +110 -0
  299. package/src/utils/map-map.ts +1 -1
  300. package/src/vertex/remove-vertex.ts +5 -3
  301. package/__tests__/cp-node/fs/get-distance-between.spec.ts +0 -7
  302. package/__tests__/cp-node/fs/get-terminating-on-circle.spec.ts +0 -24
  303. package/__tests__/cp-node/fs/is-single-3-prong.spec.ts +0 -17
  304. package/__tests__/cp-node/fs/iterate-all-on-loop.spec.ts +0 -17
  305. package/__tests__/cp-node/fs/traverse-all-forward.spec.ts +0 -14
  306. package/node/closest-boundary-point/cull-bezier-pieces-1.d.ts +0 -9
  307. package/node/closest-boundary-point/cull-bezier-pieces-1.js +0 -17
  308. package/node/closest-boundary-point/cull-bezier-pieces-1.js.map +0 -1
  309. package/node/closest-boundary-point/cull-by-loose-bounding-box.d.ts +0 -13
  310. package/node/closest-boundary-point/cull-by-loose-bounding-box.js +0 -27
  311. package/node/closest-boundary-point/cull-by-loose-bounding-box.js.map +0 -1
  312. package/node/closest-boundary-point/cull-by-tight-boundary-box.d.ts +0 -11
  313. package/node/closest-boundary-point/cull-by-tight-boundary-box.js +0 -27
  314. package/node/closest-boundary-point/cull-by-tight-boundary-box.js.map +0 -1
  315. package/node/cp-node/fs/find-first.d.ts +0 -10
  316. package/node/cp-node/fs/find-first.js +0 -19
  317. package/node/cp-node/fs/find-first.js.map +0 -1
  318. package/node/debug/functions/check-ordering.d.ts +0 -4
  319. package/node/debug/functions/check-ordering.js +0 -43
  320. package/node/debug/functions/check-ordering.js.map +0 -1
  321. package/node/find-2-prong/cull-bezier-pieces.d.ts +0 -13
  322. package/node/find-2-prong/cull-bezier-pieces.js +0 -43
  323. package/node/find-2-prong/cull-bezier-pieces.js.map +0 -1
  324. package/node/floyd-warshall/get-hole-closer-pairs.d.ts +0 -8
  325. package/node/floyd-warshall/get-hole-closer-pairs.js +0 -27
  326. package/node/floyd-warshall/get-hole-closer-pairs.js.map +0 -1
  327. package/node/utils/dual-set.d.ts +0 -27
  328. package/node/utils/dual-set.js +0 -55
  329. package/node/utils/dual-set.js.map +0 -1
  330. package/node/utils/tri-map.d.ts +0 -27
  331. package/node/utils/tri-map.js +0 -49
  332. package/node/utils/tri-map.js.map +0 -1
  333. package/src/closest-boundary-point/cull-bezier-pieces-1.ts +0 -36
  334. package/src/closest-boundary-point/cull-by-loose-bounding-box.ts +0 -42
  335. package/src/closest-boundary-point/cull-by-tight-boundary-box.ts +0 -43
  336. package/src/closest-boundary-point/get-p-from-box.ts +0 -14
  337. package/src/cp-node/fs/add-distance-from.ts +0 -49
  338. package/src/cp-node/fs/get-distance-between.ts +0 -16
  339. package/src/cp-node/fs/get-terminating-on-circle.ts +0 -24
  340. package/src/cp-node/fs/is-single-3-prong.ts +0 -15
  341. package/src/cp-node/fs/iterate-all-on-loop.ts +0 -15
  342. package/src/cp-node/fs/traverse-all-forward.ts +0 -24
  343. package/src/debug/functions/draw/draw-beziers-as-single-path.ts +0 -40
  344. package/src/debug/functions/draw/draw-disk.ts +0 -34
  345. package/src/debug/functions/draw/xmlns.ts +0 -5
  346. package/src/find-2-prong/cull-bezier-pieces.ts +0 -61
  347. package/src/find-2-prong/find-and-add-2-prong.ts +0 -30
  348. package/src/find-2-prong/get-medial/get-closest-points-d.ts +0 -213
  349. package/src/find-2-prong/x-for-debugging.ts +0 -13
  350. package/src/floyd-warshall/get-hole-closer-pairs.ts +0 -35
  351. package/src/mat/get-two-prong-type.ts +0 -13
  352. package/src/point-on-shape/is-pos-dull-corner.ts +0 -18
  353. package/src/point-on-shape/is-pos-quite-dull-corner.ts +0 -18
  354. package/src/point-on-shape/is-pos-quite-sharp-corner.ts +0 -18
  355. package/src/point-on-shape/pos-to-human-string.ts +0 -18
  356. package/src/sweep-line/are-boxes-intersecting.ts +0 -37
@@ -1,25 +1,26 @@
1
- import { CpNode } from "../cp-node.js";
1
+ import type { CpNode } from "../cp-node.js";
2
+ import { isTerminating } from "./is-terminating.js";
2
3
 
3
4
 
4
5
  /**
5
- * Returns the first `CpNode` (from this one by successively applying
6
- * .nextOnCircle) that exits the circle.
6
+ * Returns the first `CpNode` *after* the given one (by successively applying
7
+ * `.nextOnCircle`) that exits the circle, i.e. the first one that is not
8
+ * terminating - the given `CpNode` itself is never returned.
9
+ *
10
+ * * returns `undefined` if no other `CpNode` on the circle exits (e.g. the
11
+ * other `CpNode` of a 1-prong, or the MAT is a single point)
7
12
  */
8
- function getFirstExit(cpNode: CpNode) {
9
- // const startNode = this as CpNode;
10
- const startNode = cpNode;
11
- let cpNode_ = startNode;
13
+ function getFirstExit(cpNode: CpNode): CpNode | undefined {
14
+ let cpNode_ = cpNode.nextOnCircle;
12
15
 
13
- while (cpNode_.next === cpNode_.prevOnCircle) {
14
- cpNode_ = cpNode_.next;
15
-
16
- if (cpNode_ === startNode) {
17
- // The very special case the MAT is a single point.
18
- return undefined;
16
+ while (cpNode_ !== cpNode) {
17
+ if (!isTerminating(cpNode_)) {
18
+ return cpNode_;
19
19
  }
20
+ cpNode_ = cpNode_.nextOnCircle;
20
21
  }
21
22
 
22
- return cpNode_;
23
+ return undefined;
23
24
  }
24
25
 
25
26
 
@@ -1,76 +1,24 @@
1
1
  import type { CpNode } from '../cp-node.js';
2
- import { tangent } from 'flo-bezier3';
3
- import { fromTo, dot, cross, translate, lineLineIntersection, toUnitVector } from 'flo-vector2d';
4
-
5
- const { abs } = Math;
6
-
7
-
8
- /** @internal */
9
- const TOLERANCE_ADD_2PRONG = 0.01;
10
- /** @internal */
11
- const TOLERANCE_USE_LINE = 0.0001; // else cubic
12
-
13
-
2
+ import { getBoundaryTangentLine } from '../../point-on-shape/get-boundary-tangent-line.js';
3
+ import { getBeziersFromTangents } from '../../utils/get-beziers-from-tangents.js';
4
+
5
+
6
+ /**
7
+ * Returns the bezier curves (an array of 1 or 2 lines or quadratics joined
8
+ * smoothly) approximating the shape boundary between the contact points of
9
+ * two `CpNode`s.
10
+ *
11
+ * @param cpNodeA
12
+ * @param cpNodeB
13
+ */
14
14
  function getImpliedBoundaryBezierBetween(
15
15
  cpNodeA: CpNode,
16
- cpNodeB: CpNode): number[][] | undefined {
17
-
18
- const posA = cpNodeA.pointOnShape;
19
- const posB = cpNodeB.pointOnShape;
20
-
21
- let { curve: curveA, p: pA, t: tA } = posA;
22
- let { curve: curveB, p: pB, t: tB } = posB;
23
-
24
- if (pA[0] === pB[0] && pA[1] === pB[1]) {
25
- return [pA];
26
- }
27
-
28
- if (tA === 1) { tA = 0; curveA = curveA.next; }
29
- if (tB === 0) { tB = 1; curveB = curveB.prev; }
30
-
31
- const { ps: psA } = curveA;
32
- const { ps: psB } = curveB;
33
-
34
- const lA = [pA,translate(pA)(toUnitVector(tangent(psA, tA)))];
35
- const lB = [pB,translate(pB)(toUnitVector(tangent(psB, tB)))];
36
-
37
- const mid = lineLineIntersection(lA, lB);
38
-
39
- const c = fromTo(pA,pB);
40
-
41
- let twisted: boolean;
42
- if (!mid) {
43
- twisted = true;
44
- } else {
45
- const a = fromTo(pA, mid);
46
- const b = fromTo(pB, mid);
47
-
48
- twisted = dot(a,c) < 0 || dot(b,c) > 0;
49
- }
50
-
51
- if (!twisted) {
52
- // drawFs.bezier(g, [pA, mid!, pB], 'thin10 pink nofill', 0)
53
- return [pA, mid!, pB];
54
- }
55
-
56
- const w1 = fromTo(lA[0], lA[1]); // This is a unit vector
57
- const w2 = fromTo(lB[0], lB[1]); // This is a unit vector
58
-
59
- const d1 = abs(cross(c, w1)) / (3*3);
60
- const d2 = abs(cross(c, w2)) / (3*3);
61
-
62
- if (d1 > TOLERANCE_ADD_2PRONG || d2 > TOLERANCE_ADD_2PRONG) {
63
- // not within tolerance
64
- return undefined;
65
- }
66
-
67
- if (d1 > TOLERANCE_USE_LINE || d2 > TOLERANCE_USE_LINE) {
68
- // approximate with cubic bezier?
69
- return undefined; // add 2-prong
70
- }
16
+ cpNodeB: CpNode): number[][][] {
71
17
 
72
- // Within tolerance - approximate with a straight line.
73
- return [pA, pB];
18
+ return getBeziersFromTangents(
19
+ getBoundaryTangentLine(cpNodeA.pointOnShape, true),
20
+ getBoundaryTangentLine(cpNodeB.pointOnShape, false)
21
+ );
74
22
  }
75
23
 
76
24
 
@@ -1,82 +1,24 @@
1
1
  import type { CpNode } from '../cp-node.js';
2
- import {
3
- fromTo as fromToVec, dot, cross, rotate90Degrees, interpolate, translate,
4
- lineLineIntersection
5
- } from 'flo-vector2d';
6
2
  import { getEdgeDirection } from './get-edge-direction.js';
7
-
8
- const { abs } = Math;
9
-
10
-
11
- /** @internal */
12
- const TOLERANCE_ADD_2PRONG = 0.01;
13
- /** @internal */
14
- const TOLERANCE_USE_LINE = 0.0001; // else cubic
3
+ import { getBeziersFromTangents } from '../../utils/get-beziers-from-tangents.js';
15
4
 
16
5
 
17
6
  /**
18
- * Returns the bezier curve from the maximal disk of one `CpNode` to another
19
- * `CpNode`'s maximal disk.
7
+ * Returns the bezier curves (an array of 1 or 2 lines or quadratics joined
8
+ * smoothly) from the maximal disk of one `CpNode` to another `CpNode`'s
9
+ * maximal disk.
20
10
  *
21
11
  * @param cpNodeFrom
22
12
  * @param cpNodeTo
23
13
  */
24
14
  function getMatCurveBetween(
25
15
  cpNodeFrom: CpNode,
26
- cpNodeTo: CpNode): number[][] {
27
-
28
- const fromCc = cpNodeFrom.pointOnShape.circle.center;
29
- const fromL = getEdgeDirection(cpNodeFrom);
30
-
31
- const toCc = cpNodeTo.pointOnShape.circle.center;
32
- const toL = getEdgeDirection(cpNodeTo.prevOnCircle);
33
-
34
- const mid = lineLineIntersection(fromL, toL);
35
-
36
- const c = fromToVec(fromCc,toCc);
37
-
38
- let twisted: boolean;
39
- if (!mid) {
40
- twisted = true;
41
- } else {
42
- const a = fromToVec(fromCc, mid);
43
- const b = fromToVec(toCc, mid);
44
-
45
- twisted = dot(a,c) < 0 || dot(b,c) > 0;
46
- }
47
-
48
- if (!twisted) {
49
- return [fromCc, mid!, toCc];
50
- }
51
-
52
- const r = rotate90Degrees(c);
53
- const w1 = fromToVec(fromL[0], fromL[1]); // This is a unit vector
54
- const w2 = fromToVec(toL[0], toL[1]); // This is a unit vector
55
-
56
- const d1 = abs(cross(c, w1)) / (3*3);
57
- const d2 = abs(cross(c, w2)) / (3*3);
58
-
59
- if (d1 > TOLERANCE_ADD_2PRONG || d2 > TOLERANCE_ADD_2PRONG) {
60
- // FUTURE - not within tolerance - must add additional 2-prong
61
- return [fromCc, toCc];
62
- }
63
-
64
- if (d1 > TOLERANCE_USE_LINE || d2 > TOLERANCE_USE_LINE) {
65
- // approximate with cubic bezier
66
- const m1 = interpolate(fromCc,toCc,1/3);
67
- const m2 = interpolate(fromCc,toCc,2/3);
68
- const v1 = translate(r, m1);
69
- const v2 = translate(r, m2);
70
- const l1 = [m1,v1];
71
- const l2 = [m2,v2];
72
- const mid1 = lineLineIntersection(fromL, l1)!;
73
- const mid2 = lineLineIntersection(toL, l2)!;
74
-
75
- return [fromCc, mid1, mid2, toCc];
76
- }
16
+ cpNodeTo: CpNode): number[][][] {
77
17
 
78
- // Within tolerance - approximate with a straight line.
79
- return [fromCc, toCc];
18
+ return getBeziersFromTangents(
19
+ getEdgeDirection(cpNodeFrom),
20
+ getEdgeDirection(cpNodeTo.prevOnCircle)
21
+ );
80
22
  }
81
23
 
82
24
 
@@ -2,6 +2,14 @@ import { CpNode } from '../cp-node.js';
2
2
  import { getMatCurveBetween } from './get-mat-curve-between.js';
3
3
 
4
4
 
5
+ /**
6
+ * Returns the (flattened) array of bezier curves (lines or quadratics)
7
+ * representing the medial axis from one `CpNode` to another by following
8
+ * `next` repeatedly.
9
+ *
10
+ * @param cpNodeS
11
+ * @param cpNodeE
12
+ */
5
13
  function getMatCurvesBetween(
6
14
  cpNodeS: CpNode,
7
15
  cpNodeE: CpNode) {
@@ -9,8 +17,7 @@ function getMatCurvesBetween(
9
17
  let cpNode = cpNodeS;
10
18
  const pss: number[][][] = [];
11
19
  while (cpNode !== cpNodeE) {
12
- const ps = getMatCurveBetween(cpNode, cpNode.next);
13
- pss.push(ps);
20
+ pss.push(...getMatCurveBetween(cpNode, cpNode.next));
14
21
 
15
22
  cpNode = cpNode.next;
16
23
  }
@@ -1,19 +1,23 @@
1
1
  import { CpNode } from "../cp-node.js";
2
- import { getAllOnCircle } from "./get-all-on-circle.js";
3
2
  import { isTerminating } from "./is-terminating.js";
4
3
 
5
4
 
6
5
  /**
7
- * Returns the number of contact points (up to planar coordinates) on the
8
- * maximal disk circle implied by this `CpNode`.
9
- *
6
+ * Returns the number of contact points (up to planar coordinates) on the
7
+ * maximal disk circle implied by this `CpNode`, i.e. the number of
8
+ * non-terminating `CpNode`s on its circle.
9
+ *
10
10
  * See also `getProngCount`.
11
11
  */
12
12
  function getRealProngCount(cpNode: CpNode) {
13
- const nonTerminatingCpNodes = getAllOnCircle(cpNode)
14
- .filter(cpNode => !isTerminating(cpNode));
13
+ let count = 0;
14
+ let cpNode_ = cpNode;
15
+ do {
16
+ if (!isTerminating(cpNode_)) { count++; }
17
+ cpNode_ = cpNode_.nextOnCircle;
18
+ } while (cpNode_ !== cpNode);
15
19
 
16
- return nonTerminatingCpNodes.length;
20
+ return count;
17
21
  }
18
22
 
19
23
 
@@ -6,8 +6,18 @@ import { sum } from '../../utils/sum.js';
6
6
 
7
7
 
8
8
  /**
9
+ * Returns the salience of the given `CpNode`: the ratio of the boundary length
10
+ * from its contact point forward to the next contact point on its circle to
11
+ * the straight distance between those two points.
12
+ *
13
+ * * `Infinity` if that stretch of boundary passes a hole closer
14
+ * * `0` if the two contact points coincide with no boundary in between (the
15
+ * terminating `CpNode` of a 1-prong) - the other `CpNode` of a 1-prong,
16
+ * whose stretch is the entire boundary, gives `Infinity`
17
+ *
9
18
  * See https://research.gold.ac.uk/id/eprint/31944/
10
- * @param cpNode
19
+ *
20
+ * @param cpNode
11
21
  */
12
22
  function getSalience(cpNode: CpNode) {
13
23
  const cpNode1 = cpNode;
@@ -21,7 +31,10 @@ function getSalience(cpNode: CpNode) {
21
31
 
22
32
  const s = sum(pss.map(ps => totalLength(ps)));
23
33
 
24
- return hasHoleCloser ? Infinity : s/d;
34
+ if (hasHoleCloser) { return Infinity; }
35
+ if (s === 0) { return 0; } // (avoids `0/0` for the 1-prong case)
36
+
37
+ return s/d;
25
38
  }
26
39
 
27
40
 
@@ -1,28 +1,16 @@
1
1
  import type { CpNode } from "../cp-node.js";
2
- import { getAllOnCircle } from "./get-all-on-circle.js";
2
+ import { getRealProngCount } from "./get-real-prong-count.js";
3
3
  import { isTerminating } from "./is-terminating.js";
4
- import { isTrivial } from "./is-trivial.js";
5
4
 
6
5
 
7
6
  /**
8
- * Like `isTerminating` but only returns true if all `CpNode`s on the circle
9
- * (except this.prevOnCircle) is terminating.
7
+ * Like `isTerminating` but only returns `true` if all `CpNode`s on the circle
8
+ * (except possibly the one leading back, i.e. `this.prevOnCircle`) are
9
+ * terminating - i.e. the `CpNode` is terminating and its vertex has at most
10
+ * one real prong.
10
11
  */
11
12
  function isFullyTerminating(cpNode: CpNode) {
12
- if (!isTerminating(cpNode)) {
13
- return false;
14
- }
15
-
16
- if (isTrivial(cpNode)) {
17
- return true;
18
- }
19
-
20
- while (cpNode.prev === cpNode.prevOnCircle) {
21
- cpNode = cpNode.prev;
22
- }
23
-
24
- return getAllOnCircle(cpNode.prevOnCircle, true)
25
- .every(isTerminating);
13
+ return isTerminating(cpNode) && getRealProngCount(cpNode) <= 1;
26
14
  }
27
15
 
28
16
 
@@ -1,4 +1,4 @@
1
- import type { CpNode } from "flo-mat";
1
+ import { CpNode } from "../cp-node.js";
2
2
 
3
3
 
4
4
  function isOnSameLoop(
@@ -12,4 +12,4 @@ function isOnSameLoop(
12
12
  }
13
13
 
14
14
 
15
- export { isOnSameLoop }
15
+ export { isOnSameLoop }
@@ -2,13 +2,18 @@ import type { CpNode } from "../cp-node.js";
2
2
  import { getRealProngCount } from "./get-real-prong-count.js";
3
3
 
4
4
 
5
- function isSpecial(
6
- cpNode: CpNode) {
7
-
5
+ /**
6
+ * Returns `true` if the given `CpNode` is on a 'special' MAT vertex, i.e. one
7
+ * that is not a plain 2-prong: a leaf, a 3-prong (or higher) or a hole-closer.
8
+ *
9
+ * * these are the vertices that must be kept when simplifying the MAT and
10
+ * the vertices of the MAT seen as a graph
11
+ */
12
+ function isSpecial(cpNode: CpNode) {
8
13
  return (
9
- (getRealProngCount(cpNode) !== 2) &&
10
- !cpNode.isHoleClosing
11
- )
14
+ getRealProngCount(cpNode) !== 2 ||
15
+ cpNode.isHoleClosing
16
+ );
12
17
  }
13
18
 
14
19
 
@@ -1,4 +1,4 @@
1
- import { CpNode } from "../cp-node.js";
1
+ import type { CpNode } from "../cp-node.js";
2
2
  import { getAllOnCircle } from "./get-all-on-circle.js";
3
3
 
4
4
 
@@ -4,10 +4,14 @@ import { getAllOnLoop } from './get-all-on-loop.js';
4
4
 
5
5
 
6
6
  /**
7
- * Traverses all edges (depth first) of the given MAT tree starting at the given
8
- * vertex (represented by a `CpNode`).
9
- * @param cpNode Any `CpNode` representing the start vertex.
10
- * @param traverseEdgesCallback A callback function for each CpNode representing the vertex at the
7
+ * Traverses all edges of the given MAT tree exactly once each, calling the
8
+ * callback for one of the two `CpNode`s representing each edge.
9
+ *
10
+ * * the edges are visited in boundary order starting from the given `CpNode`
11
+ * (not depth first)
12
+ *
13
+ * @param cpNode Any `CpNode` on the MAT.
14
+ * @param traverseEdgesCallback A callback function for each CpNode representing the vertex at the
11
15
  * start of an edge.
12
16
  */
13
17
  function traverseEdges(
@@ -1,75 +1,75 @@
1
- import type { PointOnShape } from "../../point-on-shape/point-on-shape.js";
2
- import type { CpNode } from "../cp-node";
3
- import type { CpNodeStringifyable } from "./cp-node-stringifyable";
4
- import type { Mutable } from "../../utils/mutable.js";
5
- import { EDGES } from "./cp-node-stringifyable";
6
- import { getAllOnCircle } from "../fs/get-all-on-circle.js";
7
- import { loopFromStringifyable } from './loop-from-stringifyable.js';
8
-
9
-
10
- function fromStringifyable(
11
- cpNodesStringifyable: CpNodeStringifyable) {
12
-
13
- const { cpNodes: _cpNodes, loops: _loops } = cpNodesStringifyable;
14
- const loops = _loops.map(loopFromStringifyable);
15
- const loopsByIdx = new Map(loops.map(loop => [loop.idx, loop]));
16
-
17
- //--------------------------------------------------------------------------
18
- // First pass: build all CpNode objects with proper `cp`.
19
- // Edges still hold number ids at this point.
20
- //--------------------------------------------------------------------------
21
- const cpNodes: CpNode[] = _cpNodes.map(cpNode_ => {
22
- const { id, pointOnShape, isHoleClosing, isIntersection } = cpNode_;
23
- const { circle, order, order2 } = pointOnShape;
24
- const { curveIdx, loopIdx, p, pDd, t, isSource } = pointOnShape;
25
-
26
- const curve = loopsByIdx.get(loopIdx)!.curves[curveIdx];
27
-
28
- const pointOnShape_: PointOnShape = {
29
- circle,
30
- curve, p, pDd, t, isSource,
31
- order, order2
32
- };
33
-
34
- return {
35
- ...cpNode_,
36
- id, isHoleClosing, isIntersection,
37
- pointOnShape: pointOnShape_
38
- } as CpNode;
39
- });
40
-
41
- //--------------------------------------------------------------------------
42
- // Second pass: replace number id edges with real CpNode references.
43
- //--------------------------------------------------------------------------
44
- const nodeMap = new Map<number, CpNode>(cpNodes.map(n => [n.id, n]));
45
-
46
- for (const cpNode of cpNodes) {
47
- for (const edge of EDGES) {
48
- const id = cpNode[edge] as unknown as number | undefined;
49
- if (id === undefined) { continue; }
50
-
51
- // @ts-ignore
52
- cpNode[edge] = nodeMap.get(id)!;
53
- }
54
- }
55
-
56
- //--------------------------------------------------------------------------
57
- // Third pass: one shared `Circle` object per on-circle ring, as when the
58
- // MAT was built (the JSON gave every contact point its own copy).
59
- //--------------------------------------------------------------------------
60
- const done = new Set<CpNode>();
61
- for (const cpNode of cpNodes) {
62
- if (done.has(cpNode)) { continue; }
63
-
64
- const { circle } = cpNode.pointOnShape;
65
- for (const cp of getAllOnCircle(cpNode)) {
66
- done.add(cp);
67
- (cp.pointOnShape as Mutable<PointOnShape>).circle = circle;
68
- }
69
- }
70
-
71
- return cpNodes[0];
72
- }
73
-
74
-
75
- export { fromStringifyable }
1
+ import type { PointOnShape } from "../../point-on-shape/point-on-shape.js";
2
+ import type { CpNode } from "../cp-node.js";
3
+ import type { CpNodeStringifyable } from "./cp-node-stringifyable.js";
4
+ import type { Mutable } from "../../utils/mutable.js";
5
+ import { EDGES } from "./cp-node-stringifyable.js";
6
+ import { getAllOnCircle } from "../fs/get-all-on-circle.js";
7
+ import { loopFromStringifyable } from './loop-from-stringifyable.js';
8
+
9
+
10
+ function fromStringifyable(
11
+ cpNodesStringifyable: CpNodeStringifyable) {
12
+
13
+ const { cpNodes: _cpNodes, loops: _loops } = cpNodesStringifyable;
14
+ const loops = _loops.map(loopFromStringifyable);
15
+ const loopsByIdx = new Map(loops.map(loop => [loop.idx, loop]));
16
+
17
+ //--------------------------------------------------------------------------
18
+ // First pass: build all CpNode objects with proper `cp`.
19
+ // Edges still hold number ids at this point.
20
+ //--------------------------------------------------------------------------
21
+ const cpNodes: CpNode[] = _cpNodes.map(cpNode_ => {
22
+ const { id, pointOnShape, isHoleClosing, isIntersection } = cpNode_;
23
+ const { circle, order, order2 } = pointOnShape;
24
+ const { curveIdx, loopIdx, p, pDd, t, isSource } = pointOnShape;
25
+
26
+ const curve = loopsByIdx.get(loopIdx)!.curves[curveIdx];
27
+
28
+ const pointOnShape_: PointOnShape = {
29
+ circle,
30
+ curve, p, pDd, t, isSource,
31
+ order, order2
32
+ };
33
+
34
+ return {
35
+ ...cpNode_,
36
+ id, isHoleClosing, isIntersection,
37
+ pointOnShape: pointOnShape_
38
+ } as CpNode;
39
+ });
40
+
41
+ //--------------------------------------------------------------------------
42
+ // Second pass: replace number id edges with real CpNode references.
43
+ //--------------------------------------------------------------------------
44
+ const nodeMap = new Map<number, CpNode>(cpNodes.map(n => [n.id, n]));
45
+
46
+ for (const cpNode of cpNodes) {
47
+ for (const edge of EDGES) {
48
+ const id = cpNode[edge] as unknown as number | undefined;
49
+ if (id === undefined) { continue; }
50
+
51
+ // @ts-ignore
52
+ cpNode[edge] = nodeMap.get(id)!;
53
+ }
54
+ }
55
+
56
+ //--------------------------------------------------------------------------
57
+ // Third pass: one shared `Circle` object per on-circle ring, as when the
58
+ // MAT was built (the JSON gave every contact point its own copy).
59
+ //--------------------------------------------------------------------------
60
+ const done = new Set<CpNode>();
61
+ for (const cpNode of cpNodes) {
62
+ if (done.has(cpNode)) { continue; }
63
+
64
+ const { circle } = cpNode.pointOnShape;
65
+ for (const cp of getAllOnCircle(cpNode)) {
66
+ done.add(cp);
67
+ (cp.pointOnShape as Mutable<PointOnShape>).circle = circle;
68
+ }
69
+ }
70
+
71
+ return cpNodes[0];
72
+ }
73
+
74
+
75
+ export { fromStringifyable }
@@ -5,9 +5,9 @@ import { loopToStringifyable } from "./loop-to-stringifyable.js";
5
5
 
6
6
 
7
7
  /**
8
- * Returns a deep clone of this `CpNode`. Can be used to copy the MAT
9
- * since cloning a single `CpNode` necessarily implies cloning all
10
- * `CpNode`s on the same MAT tree.
8
+ * Returns a plain, acyclic representation of the entire MAT the given `CpNode`
9
+ * is part of (the `CpNode` edges replaced by ids and the boundary loops
10
+ * included) suitable for `JSON.stringify`; `fromStringifyable` reverses it.
11
11
  */
12
12
  function toStringifyable(
13
13
  cpNode: CpNode): CpNodeStringifyable {
@@ -1,8 +1,10 @@
1
+ import type { Curve } from 'flo-boolean';
2
+
1
3
 
2
4
  /** @internal */
3
5
  interface Debug {
4
6
  /** Generated by debug object for later inspection */
5
- elems: {};
7
+ elems: Elems;
6
8
  timing: Timing;
7
9
 
8
10
  /**
@@ -14,6 +16,28 @@ interface Debug {
14
16
  }
15
17
 
16
18
 
19
+ /**
20
+ * Elements generated during `findMats` for later inspection (only available
21
+ * if debug has been enabled via `enableDebugForMat(true)`).
22
+ *
23
+ * The arrays are reset at the start of each `findMats` call and accumulate
24
+ * over all MATs found in that call, one entry per boundary bezier curve in the
25
+ * order the curves are encountered.
26
+ */
27
+ interface Elems {
28
+ /** The loose (axis-aligned) bounding box of each boundary bezier curve */
29
+ readonly looseBoundingBoxes: number[][][];
30
+ /** The tight (rotated) bounding box of each boundary bezier curve */
31
+ readonly tightBoundingBoxes: number[][][];
32
+ /** The bounding hull of each boundary bezier curve */
33
+ readonly boundingHulls: number[][][];
34
+ /** The curves whose end point forms a quite sharp corner with the next curve */
35
+ readonly sharpCorners: Curve[];
36
+ /** The curves whose end point forms a quite dull corner with the next curve */
37
+ readonly dullCorners: Curve[];
38
+ }
39
+
40
+
17
41
  /** @internal */
18
42
  interface Timing {
19
43
  holeClosers: number;
@@ -35,18 +59,31 @@ interface Directives {
35
59
  }
36
60
 
37
61
 
62
+ /** Returns a fresh (empty) set of debug `Elems`. */
63
+ function createEmptyElems(): Elems {
64
+ return {
65
+ looseBoundingBoxes: [],
66
+ tightBoundingBoxes: [],
67
+ boundingHulls: [],
68
+ sharpCorners: [],
69
+ dullCorners: []
70
+ };
71
+ }
72
+
73
+
38
74
  function enableDebugForMat(debugOn: boolean) {
39
75
  if (!debugOn) {
40
- (window as any)._debug_ = undefined;
76
+ (globalThis as any)._debug_ = undefined;
41
77
  return;
42
78
  }
43
79
 
44
- let debug: Debug = (window as any)._debug_;
80
+ let debug: Debug = (globalThis as any)._debug_;
45
81
 
46
82
  debug = {
47
83
  ...debug,
48
84
  elems: {
49
- ...debug?.elems
85
+ ...debug?.elems,
86
+ ...createEmptyElems()
50
87
  },
51
88
  timing: {
52
89
  ...debug?.timing,
@@ -71,10 +108,9 @@ function enableDebugForMat(debugOn: boolean) {
71
108
  }
72
109
  };
73
110
 
74
- (window as any)._debug_ = debug;
111
+ (globalThis as any)._debug_ = debug;
75
112
  }
76
113
 
77
114
 
78
- export type { Debug, Timing, Directives }
79
- export { enableDebugForMat }
80
-
115
+ export type { Debug, Elems, Timing, Directives }
116
+ export { enableDebugForMat, createEmptyElems }