flo-mat 4.1.4 → 5.0.1

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 (379) 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/circle-identity.spec.ts +56 -0
  4. package/__tests__/cp-node/fs/get-all-on-loop-by-loop.spec.ts +55 -0
  5. package/__tests__/cp-node/fs/get-angle-between-mat-curves.spec.ts +39 -3
  6. package/__tests__/cp-node/fs/get-boundary-bezier-parts-to-next.spec.ts +87 -3
  7. package/__tests__/cp-node/fs/get-boundary-beziers-between.spec.ts +68 -3
  8. package/__tests__/cp-node/fs/get-boundary-beziers-to-next.spec.ts +41 -3
  9. package/__tests__/cp-node/fs/get-boundary-distance-to-next.spec.ts +20 -3
  10. package/__tests__/cp-node/fs/get-branch-beziers.spec.ts +42 -3
  11. package/__tests__/cp-node/fs/get-branch.spec.ts +60 -3
  12. package/__tests__/cp-node/fs/get-cp-node-ordering.spec.ts +19 -3
  13. package/__tests__/cp-node/fs/get-distance-to-next.spec.ts +37 -4
  14. package/__tests__/cp-node/fs/get-edge-direction.spec.ts +50 -3
  15. package/__tests__/cp-node/fs/get-first-exit.spec.ts +78 -3
  16. package/__tests__/cp-node/fs/get-hole-closers.spec.ts +32 -3
  17. package/__tests__/cp-node/fs/get-implied-boundary-bezier-between.spec.ts +48 -3
  18. package/__tests__/cp-node/fs/get-mat-curve-between.spec.ts +77 -3
  19. package/__tests__/cp-node/fs/get-mat-curve-to-next.spec.ts +17 -4
  20. package/__tests__/cp-node/fs/get-mat-curves-between.spec.ts +38 -3
  21. package/__tests__/cp-node/fs/get-salience.spec.ts +68 -3
  22. package/__tests__/cp-node/fs/get-vertex-forward-children.spec.ts +40 -3
  23. package/__tests__/cp-node/fs/insert-cp-node.spec.ts +87 -3
  24. package/__tests__/cp-node/fs/is-special.spec.ts +1 -1
  25. package/__tests__/cp-node/fs/remove-cp-node.spec.ts +42 -3
  26. package/__tests__/find-2-prong/calc-seperation-tolerance.spec.ts +46 -0
  27. package/__tests__/find-2-prong/get-medial/dd-get-medial-point-coeffs-same-curve.spec.ts +7 -5
  28. package/__tests__/find-2-prong/get-medial/dd-get-medial-point-coeffs.spec.ts +4 -2
  29. package/__tests__/find-2-prong/get-medial/get-closest-points.spec.ts +1 -1
  30. package/__tests__/floyd-warshall/get-graph.spec.ts +100 -0
  31. package/__tests__/get-mats-with-hole.ts +28 -0
  32. package/__tests__/get-mats1.spec.ts +61 -0
  33. package/__tests__/get-mats1.ts +75 -67
  34. package/__tests__/helpers/cp-node-by-id.ts +27 -0
  35. package/__tests__/helpers/expect-point-close.ts +42 -0
  36. package/__tests__/mat/hausdorff-distance-one-sided-exceeds.spec.ts +129 -0
  37. package/__tests__/mat/simplify-mat.spec.ts +85 -0
  38. package/__tests__/reconstruct-from-mat/reconstruct-from-mat.spec.ts +39 -0
  39. package/__tests__/specific-cases/test-svgs/achispado.svg +14 -0
  40. package/__tests__/utils/get-beziers-from-tangents.spec.ts +142 -0
  41. package/browser/index.js +17882 -13800
  42. package/browser/index.min.js +1 -1
  43. package/node/add-n-prong.ts/join-spokes.js +3 -2
  44. package/node/add-n-prong.ts/join-spokes.js.map +1 -1
  45. package/node/closest-boundary-point/cull-curve-pieces.d.ts +21 -0
  46. package/node/closest-boundary-point/cull-curve-pieces.js +40 -0
  47. package/node/closest-boundary-point/cull-curve-pieces.js.map +1 -0
  48. package/node/closest-boundary-point/get-close-boundary-points-certified.js +5 -2
  49. package/node/closest-boundary-point/get-close-boundary-points-certified.js.map +1 -1
  50. package/node/closest-boundary-point/get-endpoint-info.d.ts +39 -0
  51. package/node/closest-boundary-point/get-endpoint-info.js +78 -0
  52. package/node/closest-boundary-point/get-endpoint-info.js.map +1 -0
  53. package/node/closest-boundary-point/get-potential-closest-points-on-curve-certified.js +5 -19
  54. package/node/closest-boundary-point/get-potential-closest-points-on-curve-certified.js.map +1 -1
  55. package/node/closest-boundary-point/root-interval-to-distance-squared-interval.d.ts +17 -5
  56. package/node/closest-boundary-point/root-interval-to-distance-squared-interval.js +37 -50
  57. package/node/closest-boundary-point/root-interval-to-distance-squared-interval.js.map +1 -1
  58. package/node/corner/get-corner.d.ts +18 -1
  59. package/node/corner/get-corner.js +8 -1
  60. package/node/corner/get-corner.js.map +1 -1
  61. package/node/corner/get-interface-ccw.js.map +1 -1
  62. package/node/cp-node/cp-node.d.ts +4 -3
  63. package/node/cp-node/fs/enhance-cp-node.d.ts +9 -9
  64. package/node/cp-node/fs/get-all-on-loop-by-loop.js +0 -4
  65. package/node/cp-node/fs/get-all-on-loop-by-loop.js.map +1 -1
  66. package/node/cp-node/fs/get-angle-between-mat-curves.d.ts +1 -1
  67. package/node/cp-node/fs/get-angle-between-mat-curves.js +7 -4
  68. package/node/cp-node/fs/get-angle-between-mat-curves.js.map +1 -1
  69. package/node/cp-node/fs/get-boundary-beziers-between.d.ts +6 -4
  70. package/node/cp-node/fs/get-boundary-beziers-between.js +6 -4
  71. package/node/cp-node/fs/get-boundary-beziers-between.js.map +1 -1
  72. package/node/cp-node/fs/get-branch-beziers.d.ts +2 -1
  73. package/node/cp-node/fs/get-branch-beziers.js +3 -2
  74. package/node/cp-node/fs/get-branch-beziers.js.map +1 -1
  75. package/node/cp-node/fs/get-branch.js +1 -2
  76. package/node/cp-node/fs/get-branch.js.map +1 -1
  77. package/node/cp-node/fs/get-distance-to-next.js +4 -2
  78. package/node/cp-node/fs/get-distance-to-next.js.map +1 -1
  79. package/node/cp-node/fs/get-edge-direction.js +3 -2
  80. package/node/cp-node/fs/get-edge-direction.js.map +1 -1
  81. package/node/cp-node/fs/get-first-exit.d.ts +7 -3
  82. package/node/cp-node/fs/get-first-exit.js +13 -11
  83. package/node/cp-node/fs/get-first-exit.js.map +1 -1
  84. package/node/cp-node/fs/get-implied-boundary-bezier-between.d.ts +10 -2
  85. package/node/cp-node/fs/get-implied-boundary-bezier-between.js +11 -54
  86. package/node/cp-node/fs/get-implied-boundary-bezier-between.js.map +1 -1
  87. package/node/cp-node/fs/get-mat-curve-between.d.ts +5 -3
  88. package/node/cp-node/fs/get-mat-curve-between.js +6 -49
  89. package/node/cp-node/fs/get-mat-curve-between.js.map +1 -1
  90. package/node/cp-node/fs/get-mat-curve-to-next.d.ts +1 -1
  91. package/node/cp-node/fs/get-mat-curves-between.d.ts +8 -0
  92. package/node/cp-node/fs/get-mat-curves-between.js +9 -2
  93. package/node/cp-node/fs/get-mat-curves-between.js.map +1 -1
  94. package/node/cp-node/fs/get-real-prong-count.d.ts +2 -1
  95. package/node/cp-node/fs/get-real-prong-count.js +11 -5
  96. package/node/cp-node/fs/get-real-prong-count.js.map +1 -1
  97. package/node/cp-node/fs/get-salience.d.ts +10 -0
  98. package/node/cp-node/fs/get-salience.js +17 -1
  99. package/node/cp-node/fs/get-salience.js.map +1 -1
  100. package/node/cp-node/fs/is-fully-terminating.d.ts +4 -2
  101. package/node/cp-node/fs/is-fully-terminating.js +6 -17
  102. package/node/cp-node/fs/is-fully-terminating.js.map +1 -1
  103. package/node/cp-node/fs/is-on-same-circle.d.ts +3 -0
  104. package/node/cp-node/fs/is-on-same-circle.js +4 -4
  105. package/node/cp-node/fs/is-on-same-circle.js.map +1 -1
  106. package/node/cp-node/fs/is-on-same-loop.d.ts +1 -1
  107. package/node/cp-node/fs/is-special.d.ts +7 -0
  108. package/node/cp-node/fs/is-special.js +9 -2
  109. package/node/cp-node/fs/is-special.js.map +1 -1
  110. package/node/cp-node/fs/is-vertex.d.ts +1 -1
  111. package/node/cp-node/fs/traverse-edges.d.ts +7 -3
  112. package/node/cp-node/fs/traverse-edges.js +7 -3
  113. package/node/cp-node/fs/traverse-edges.js.map +1 -1
  114. package/node/cp-node/stringification/from-stringifyable.d.ts +2 -2
  115. package/node/cp-node/stringification/from-stringifyable.js +17 -1
  116. package/node/cp-node/stringification/from-stringifyable.js.map +1 -1
  117. package/node/cp-node/stringification/to-stringifyable.d.ts +3 -3
  118. package/node/cp-node/stringification/to-stringifyable.js +3 -3
  119. package/node/debug/debug.d.ts +26 -3
  120. package/node/debug/debug.js +16 -5
  121. package/node/debug/debug.js.map +1 -1
  122. package/node/find-2-prong/add-2-prong.js +7 -9
  123. package/node/find-2-prong/add-2-prong.js.map +1 -1
  124. package/node/find-2-prong/calc-seperation-tolerance.d.ts +28 -5
  125. package/node/find-2-prong/calc-seperation-tolerance.js +32 -89
  126. package/node/find-2-prong/calc-seperation-tolerance.js.map +1 -1
  127. package/node/find-2-prong/find-2-prong.js +8 -10
  128. package/node/find-2-prong/find-2-prong.js.map +1 -1
  129. package/node/find-2-prong/find-and-add-2-prongs.js +2 -2
  130. package/node/find-2-prong/find-and-add-2-prongs.js.map +1 -1
  131. package/node/find-2-prong/get-medial/get-antipodal-points.d.ts +1 -2
  132. package/node/find-2-prong/get-medial/get-antipodal-points.js +2 -3
  133. package/node/find-2-prong/get-medial/get-antipodal-points.js.map +1 -1
  134. package/node/find-2-prong/get-medial/get-closest-points.d.ts +1 -8
  135. package/node/find-2-prong/get-medial/get-closest-points.js +4 -40
  136. package/node/find-2-prong/get-medial/get-closest-points.js.map +1 -1
  137. package/node/find-2-prong/reduce-radius.d.ts +1 -1
  138. package/node/find-2-prong/reduce-radius.js +6 -3
  139. package/node/find-2-prong/reduce-radius.js.map +1 -1
  140. package/node/find-3-prong/calc-better-x.js +1 -1
  141. package/node/find-3-prong/calc-better-x.js.map +1 -1
  142. package/node/find-3-prong/find-3-prong-for-delta3s.d.ts +3 -2
  143. package/node/find-3-prong/find-3-prong-for-delta3s.js +36 -42
  144. package/node/find-3-prong/find-3-prong-for-delta3s.js.map +1 -1
  145. package/node/find-3-prong/find-3-prong.js +3 -1
  146. package/node/find-3-prong/find-3-prong.js.map +1 -1
  147. package/node/find-3-prong/find-and-add-3-prongs.js +16 -0
  148. package/node/find-3-prong/find-and-add-3-prongs.js.map +1 -1
  149. package/node/find-mat/create-initial-cp-tree.js +2 -2
  150. package/node/find-mat/create-initial-cp-tree.js.map +1 -1
  151. package/node/find-mat/find-mat.js +3 -4
  152. package/node/find-mat/find-mat.js.map +1 -1
  153. package/node/find-mat/find-mats.d.ts +6 -12
  154. package/node/find-mat/find-mats.js +10 -27
  155. package/node/find-mat/find-mats.js.map +1 -1
  156. package/node/find-mat/get-dull-corners-on-loop.js +2 -2
  157. package/node/find-mat/get-dull-corners-on-loop.js.map +1 -1
  158. package/node/find-mat/get-for-1-prongs-on-loop.js +36 -8
  159. package/node/find-mat/get-for-1-prongs-on-loop.js.map +1 -1
  160. package/node/find-mat/get-meta.d.ts +14 -4
  161. package/node/find-mat/get-meta.js +30 -24
  162. package/node/find-mat/get-meta.js.map +1 -1
  163. package/node/find-mat/get-sharp-corners.js +2 -2
  164. package/node/find-mat/get-sharp-corners.js.map +1 -1
  165. package/node/find-mat/mat-options.d.ts +2 -2
  166. package/node/floyd-warshall/get-graph.d.ts +12 -1
  167. package/node/floyd-warshall/get-graph.js +41 -38
  168. package/node/floyd-warshall/get-graph.js.map +1 -1
  169. package/node/geometry/get-bounding-box-.d.ts +16 -2
  170. package/node/geometry/get-bounding-box-.js +5 -2
  171. package/node/geometry/get-bounding-box-.js.map +1 -1
  172. package/node/geometry/get-closest-square-distance-to-rect.d.ts +3 -0
  173. package/node/geometry/get-closest-square-distance-to-rect.js +7 -5
  174. package/node/geometry/get-closest-square-distance-to-rect.js.map +1 -1
  175. package/node/geometry/get-closest-squared-distance-to-rotated-rect.d.ts +4 -0
  176. package/node/geometry/get-closest-squared-distance-to-rotated-rect.js +12 -5
  177. package/node/geometry/get-closest-squared-distance-to-rotated-rect.js.map +1 -1
  178. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.js +1 -2
  179. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.js.map +1 -1
  180. package/node/index.d.ts +3 -2
  181. package/node/index.js +2 -1
  182. package/node/index.js.map +1 -1
  183. package/node/mat/clone-mat.d.ts +9 -0
  184. package/node/mat/clone-mat.js +17 -0
  185. package/node/mat/clone-mat.js.map +1 -0
  186. package/node/mat/clone-meta.d.ts +12 -0
  187. package/node/mat/clone-meta.js +24 -0
  188. package/node/mat/clone-meta.js.map +1 -0
  189. package/node/mat/get-boundary-piece-beziers.d.ts +5 -0
  190. package/node/mat/get-boundary-piece-beziers.js +7 -93
  191. package/node/mat/get-boundary-piece-beziers.js.map +1 -1
  192. package/node/mat/get-closeby-cp-if-exist.js +2 -1
  193. package/node/mat/get-closeby-cp-if-exist.js.map +1 -1
  194. package/node/mat/get-largest-3-prong.d.ts +6 -0
  195. package/node/mat/get-largest-3-prong.js +8 -5
  196. package/node/mat/get-largest-3-prong.js.map +1 -1
  197. package/node/mat/get-largest-vertex.d.ts +15 -1
  198. package/node/mat/get-largest-vertex.js +20 -7
  199. package/node/mat/get-largest-vertex.js.map +1 -1
  200. package/node/mat/hausdorff-distance-one-sided-exceeds.d.ts +79 -0
  201. package/node/mat/hausdorff-distance-one-sided-exceeds.js +251 -0
  202. package/node/mat/hausdorff-distance-one-sided-exceeds.js.map +1 -0
  203. package/node/mat/mat-meta.d.ts +0 -6
  204. package/node/mat/simplify-mat.d.ts +25 -8
  205. package/node/mat/simplify-mat.js +182 -53
  206. package/node/mat/simplify-mat.js.map +1 -1
  207. package/node/mat/trim-mat.d.ts +4 -2
  208. package/node/mat/trim-mat.js +3 -1
  209. package/node/mat/trim-mat.js.map +1 -1
  210. package/node/point-on-shape/get-boundary-tangent-line.d.ts +19 -0
  211. package/node/point-on-shape/get-boundary-tangent-line.js +33 -0
  212. package/node/point-on-shape/get-boundary-tangent-line.js.map +1 -0
  213. package/node/point-on-shape/get-osculating-circle.d.ts +6 -4
  214. package/node/point-on-shape/get-osculating-circle.js +6 -4
  215. package/node/point-on-shape/get-osculating-circle.js.map +1 -1
  216. package/node/point-on-shape/get-pos-corner.js +2 -2
  217. package/node/point-on-shape/get-pos-corner.js.map +1 -1
  218. package/node/point-on-shape/point-on-shape.d.ts +5 -0
  219. package/node/reconstruct-from-mat/reconstruct-from-mat.js +20 -80
  220. package/node/reconstruct-from-mat/reconstruct-from-mat.js.map +1 -1
  221. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.d.ts +4 -0
  222. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js +4 -0
  223. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js.map +1 -1
  224. package/node/sat/cull.d.ts +7 -6
  225. package/node/sat/cull.js +13 -16
  226. package/node/sat/cull.js.map +1 -1
  227. package/node/sat/get-sat-culls.d.ts +12 -2
  228. package/node/sat/get-sat-culls.js +21 -16
  229. package/node/sat/get-sat-culls.js.map +1 -1
  230. package/node/svg/get-shape-bounds.d.ts +1 -12
  231. package/node/svg/get-shape-bounds.js +2 -3
  232. package/node/svg/get-shape-bounds.js.map +1 -1
  233. package/node/sweep-line/sweep-line.js.map +1 -1
  234. package/node/utils/get-beziers-from-tangents.d.ts +28 -0
  235. package/node/utils/get-beziers-from-tangents.js +92 -0
  236. package/node/utils/get-beziers-from-tangents.js.map +1 -0
  237. package/node/vertex/remove-vertex.d.ts +5 -3
  238. package/node/vertex/remove-vertex.js +5 -3
  239. package/node/vertex/remove-vertex.js.map +1 -1
  240. package/package.json +16 -16
  241. package/qv-infinite-loop.md +120 -0
  242. package/src/add-n-prong.ts/join-spokes.ts +4 -2
  243. package/src/closest-boundary-point/cull-curve-pieces.ts +49 -0
  244. package/src/closest-boundary-point/get-close-boundary-points-certified.ts +5 -2
  245. package/src/closest-boundary-point/get-endpoint-info.ts +96 -0
  246. package/src/closest-boundary-point/get-potential-closest-points-on-curve-certified.ts +5 -23
  247. package/src/closest-boundary-point/root-interval-to-distance-squared-interval.ts +42 -60
  248. package/src/corner/get-corner.ts +10 -1
  249. package/src/corner/get-interface-ccw.ts +2 -2
  250. package/src/cp-node/cp-node.ts +4 -3
  251. package/src/cp-node/fs/get-all-on-loop-by-loop.ts +0 -4
  252. package/src/cp-node/fs/get-angle-between-mat-curves.ts +9 -5
  253. package/src/cp-node/fs/get-boundary-beziers-between.ts +10 -8
  254. package/src/cp-node/fs/get-branch-beziers.ts +3 -2
  255. package/src/cp-node/fs/get-branch.ts +1 -2
  256. package/src/cp-node/fs/get-distance-to-next.ts +4 -2
  257. package/src/cp-node/fs/get-edge-direction.ts +4 -2
  258. package/src/cp-node/fs/get-first-exit.ts +15 -14
  259. package/src/cp-node/fs/get-implied-boundary-bezier-between.ts +18 -70
  260. package/src/cp-node/fs/get-mat-curve-between.ts +10 -67
  261. package/src/cp-node/fs/get-mat-curves-between.ts +9 -2
  262. package/src/cp-node/fs/get-real-prong-count.ts +11 -7
  263. package/src/cp-node/fs/get-salience.ts +15 -2
  264. package/src/cp-node/fs/is-fully-terminating.ts +6 -22
  265. package/src/cp-node/fs/is-on-same-circle.ts +6 -7
  266. package/src/cp-node/fs/is-on-same-loop.ts +2 -2
  267. package/src/cp-node/fs/is-special.ts +11 -6
  268. package/src/cp-node/fs/is-vertex.ts +1 -1
  269. package/src/cp-node/fs/traverse-edges.ts +8 -4
  270. package/src/cp-node/stringification/from-stringifyable.ts +75 -58
  271. package/src/cp-node/stringification/to-stringifyable.ts +3 -3
  272. package/src/debug/debug.ts +44 -8
  273. package/src/find-2-prong/add-2-prong.ts +9 -11
  274. package/src/find-2-prong/calc-seperation-tolerance.ts +34 -115
  275. package/src/find-2-prong/find-2-prong.ts +9 -11
  276. package/src/find-2-prong/find-and-add-2-prongs.ts +2 -2
  277. package/src/find-2-prong/get-medial/get-antipodal-points.ts +1 -3
  278. package/src/find-2-prong/get-medial/get-closest-points.ts +6 -51
  279. package/src/find-2-prong/reduce-radius.ts +6 -4
  280. package/src/find-3-prong/calc-better-x.ts +2 -2
  281. package/src/find-3-prong/find-3-prong-for-delta3s.ts +197 -214
  282. package/src/find-3-prong/find-3-prong.ts +54 -51
  283. package/src/find-3-prong/find-and-add-3-prongs.ts +20 -1
  284. package/src/find-mat/create-initial-cp-tree.ts +2 -2
  285. package/src/find-mat/find-mat.ts +4 -6
  286. package/src/find-mat/find-mats.ts +83 -105
  287. package/src/find-mat/get-dull-corners-on-loop.ts +2 -2
  288. package/src/find-mat/get-for-1-prongs-on-loop.ts +40 -8
  289. package/src/find-mat/get-meta.ts +34 -39
  290. package/src/find-mat/get-sharp-corners.ts +2 -2
  291. package/src/find-mat/mat-options.ts +2 -2
  292. package/src/floyd-warshall/get-graph.ts +46 -47
  293. package/src/geometry/get-bounding-box-.ts +5 -2
  294. package/src/geometry/get-closest-square-distance-to-rect.ts +7 -7
  295. package/src/geometry/get-closest-squared-distance-to-rotated-rect.ts +15 -13
  296. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.ts +1 -2
  297. package/src/index.ts +3 -2
  298. package/src/mat/clone-mat.ts +9 -3
  299. package/src/mat/clone-meta.ts +8 -0
  300. package/src/mat/get-boundary-piece-beziers.ts +16 -117
  301. package/src/mat/get-closeby-cp-if-exist.ts +3 -1
  302. package/src/mat/get-largest-3-prong.ts +9 -6
  303. package/src/mat/get-largest-vertex.ts +25 -9
  304. package/src/mat/hausdorff-distance-one-sided-exceeds.ts +314 -0
  305. package/src/mat/mat-meta.ts +0 -9
  306. package/src/mat/simplify-mat.ts +254 -116
  307. package/src/mat/trim-mat.ts +6 -4
  308. package/src/point-on-shape/get-boundary-tangent-line.ts +36 -0
  309. package/src/point-on-shape/get-osculating-circle.ts +7 -5
  310. package/src/point-on-shape/get-pos-corner.ts +2 -2
  311. package/src/point-on-shape/point-on-shape.ts +5 -0
  312. package/src/reconstruct-from-mat/reconstruct-from-mat.ts +22 -111
  313. package/src/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.ts +4 -0
  314. package/src/sat/cull.ts +16 -20
  315. package/src/sat/get-sat-culls.ts +28 -23
  316. package/src/svg/get-shape-bounds.ts +2 -3
  317. package/src/sweep-line/sweep-line.ts +1 -1
  318. package/src/utils/deg-to-rad.ts +4 -2
  319. package/src/utils/get-beziers-from-tangents.ts +110 -0
  320. package/src/utils/map-map.ts +1 -1
  321. package/src/utils/rad-to-deg.ts +4 -1
  322. package/src/vertex/remove-vertex.ts +5 -3
  323. package/webpack.config.cjs +7 -2
  324. package/__tests__/cp-node/fs/get-distance-between.spec.ts +0 -7
  325. package/__tests__/cp-node/fs/get-terminating-on-circle.spec.ts +0 -24
  326. package/__tests__/cp-node/fs/is-single-3-prong.spec.ts +0 -17
  327. package/__tests__/cp-node/fs/iterate-all-on-loop.spec.ts +0 -17
  328. package/__tests__/cp-node/fs/traverse-all-forward.spec.ts +0 -14
  329. package/node/closest-boundary-point/cull-bezier-pieces-1.d.ts +0 -9
  330. package/node/closest-boundary-point/cull-bezier-pieces-1.js +0 -17
  331. package/node/closest-boundary-point/cull-bezier-pieces-1.js.map +0 -1
  332. package/node/closest-boundary-point/cull-by-loose-bounding-box.d.ts +0 -13
  333. package/node/closest-boundary-point/cull-by-loose-bounding-box.js +0 -27
  334. package/node/closest-boundary-point/cull-by-loose-bounding-box.js.map +0 -1
  335. package/node/closest-boundary-point/cull-by-tight-boundary-box.d.ts +0 -11
  336. package/node/closest-boundary-point/cull-by-tight-boundary-box.js +0 -27
  337. package/node/closest-boundary-point/cull-by-tight-boundary-box.js.map +0 -1
  338. package/node/cp-node/fs/find-first.d.ts +0 -10
  339. package/node/cp-node/fs/find-first.js +0 -19
  340. package/node/cp-node/fs/find-first.js.map +0 -1
  341. package/node/debug/functions/check-ordering.d.ts +0 -4
  342. package/node/debug/functions/check-ordering.js +0 -43
  343. package/node/debug/functions/check-ordering.js.map +0 -1
  344. package/node/find-2-prong/cull-bezier-pieces.d.ts +0 -13
  345. package/node/find-2-prong/cull-bezier-pieces.js +0 -43
  346. package/node/find-2-prong/cull-bezier-pieces.js.map +0 -1
  347. package/node/floyd-warshall/get-hole-closer-pairs.d.ts +0 -8
  348. package/node/floyd-warshall/get-hole-closer-pairs.js +0 -27
  349. package/node/floyd-warshall/get-hole-closer-pairs.js.map +0 -1
  350. package/node/utils/dual-set.d.ts +0 -27
  351. package/node/utils/dual-set.js +0 -55
  352. package/node/utils/dual-set.js.map +0 -1
  353. package/node/utils/tri-map.d.ts +0 -27
  354. package/node/utils/tri-map.js +0 -49
  355. package/node/utils/tri-map.js.map +0 -1
  356. package/src/closest-boundary-point/cull-bezier-pieces-1.ts +0 -36
  357. package/src/closest-boundary-point/cull-by-loose-bounding-box.ts +0 -42
  358. package/src/closest-boundary-point/cull-by-tight-boundary-box.ts +0 -43
  359. package/src/closest-boundary-point/get-p-from-box.ts +0 -14
  360. package/src/cp-node/fs/add-distance-from.ts +0 -49
  361. package/src/cp-node/fs/get-distance-between.ts +0 -16
  362. package/src/cp-node/fs/get-terminating-on-circle.ts +0 -24
  363. package/src/cp-node/fs/is-single-3-prong.ts +0 -15
  364. package/src/cp-node/fs/iterate-all-on-loop.ts +0 -15
  365. package/src/cp-node/fs/traverse-all-forward.ts +0 -24
  366. package/src/debug/functions/draw/draw-beziers-as-single-path.ts +0 -40
  367. package/src/debug/functions/draw/draw-disk.ts +0 -34
  368. package/src/debug/functions/draw/xmlns.ts +0 -5
  369. package/src/find-2-prong/cull-bezier-pieces.ts +0 -61
  370. package/src/find-2-prong/find-and-add-2-prong.ts +0 -30
  371. package/src/find-2-prong/get-medial/get-closest-points-d.ts +0 -213
  372. package/src/find-2-prong/x-for-debugging.ts +0 -13
  373. package/src/floyd-warshall/get-hole-closer-pairs.ts +0 -35
  374. package/src/mat/get-two-prong-type.ts +0 -13
  375. package/src/point-on-shape/is-pos-dull-corner.ts +0 -18
  376. package/src/point-on-shape/is-pos-quite-dull-corner.ts +0 -18
  377. package/src/point-on-shape/is-pos-quite-sharp-corner.ts +0 -18
  378. package/src/point-on-shape/pos-to-human-string.ts +0 -18
  379. package/src/sweep-line/are-boxes-intersecting.ts +0 -37
@@ -1,59 +1,66 @@
1
1
  import type { CpNode } from "../cp-node/cp-node.js";
2
- import { getAllOnCircle } from "../cp-node/fs/get-all-on-circle.js";
2
+ import type { Circle } from "../geometry/circle.js";
3
3
  import { getMatDistanceToNext$ } from "../cp-node/fs/get-distance-to-next.js";
4
- import { isOnSameCircle } from "../cp-node/fs/is-on-same-circle.js";
5
4
  import { isVertexSpecial } from "../cp-node/fs/is-vertex-special.js";
6
- import { getHoleCloserPairs } from "./get-hole-closer-pairs.js";
7
5
 
8
6
 
7
+ /**
8
+ * Returns the adjacency matrix (MAT edge lengths, `Infinity` if not adjacent)
9
+ * of the given special vertices (leaves, 3-prongs, ...) seen as the vertices of
10
+ * a graph with the MAT branches between them as edges.
11
+ *
12
+ * * for each vertex every MAT edge leaving it is walked once, up to the next
13
+ * special vertex; if that vertex is one of the given ones the walked length
14
+ * is its distance (the minimum over all such walks if there are several)
15
+ *
16
+ * @param specialVertices the special `CpNode`s (one per vertex)
17
+ */
9
18
  function getGraph(
10
- specialVertices: CpNode[],
11
- holeClosers: CpNode[]) {
12
-
13
- const pairs = getHoleCloserPairs(holeClosers);
19
+ specialVertices: CpNode[]) {
14
20
 
15
21
  const V = specialVertices.length;
16
22
 
23
+ // the column of each given vertex, identified by its circle (all `CpNode`s
24
+ // on a vertex share the same `Circle` object)
25
+ const columnOf = new Map<Circle, number>(
26
+ specialVertices.map((cpNode, j) => [cpNode.pointOnShape.circle, j])
27
+ );
28
+
17
29
  const graph: number[][] = [];
18
30
  for (let i=0; i<V; i++) {
19
31
  const cpNodeA = specialVertices[i];
20
32
 
21
- const row: number[] = [];
22
- for (let j=0; j<V; j++) {
23
- const cpNodeB = specialVertices[j];
24
- if (i === j) {
25
- row.push(0);
26
- continue;
27
- }
28
-
29
- let minD = Infinity;
30
- for (const toChild of getAllOnCircle(cpNodeA)) {
31
- let d = getMatDistanceToNext$(toChild);
32
- let child = toChild.next;
33
- while (true) {
34
- if (isOnSameCircle(child, cpNodeB)) {
35
- break; // Found path from A to B
36
- }
37
- if (child.isHoleClosing) {
38
- // Hole closer found - don't go around loop
39
- child = getHoleCloserNext(pairs, child);
40
- continue;
41
- }
42
- if (isVertexSpecial(child)) {
43
- // we only find the immediate next special ones
44
- d = Infinity;
45
- break; // Next special vertex found but it's not B
46
- }
47
-
48
- d += getMatDistanceToNext$(child);
49
- child = child.next;
33
+ const row: number[] = new Array(V).fill(Infinity);
34
+ row[i] = 0;
35
+
36
+ // walk each edge leaving the vertex up to the next special vertex
37
+ let toChild = cpNodeA;
38
+ do {
39
+ let d = getMatDistanceToNext$(toChild);
40
+ let child = toChild.next;
41
+ while (true) {
42
+ const j = columnOf.get(child.pointOnShape.circle);
43
+ if (j !== undefined) {
44
+ // Found a path from A to one of the given vertices
45
+ if (j !== i && d < row[j]) { row[j] = d; }
46
+ break;
47
+ }
48
+ if (child.isHoleClosing) {
49
+ // Hole closer found - skip it (don't go around loop)
50
+ child = child.holeCloserTwin!.next;
51
+ continue;
52
+ }
53
+ if (isVertexSpecial(child)) {
54
+ // we only find the immediate next special ones
55
+ break; // Next special vertex found but it's not a given one
50
56
  }
51
57
 
52
- if (d < minD) { minD = d; }
58
+ d += getMatDistanceToNext$(child);
59
+ child = child.next;
53
60
  }
54
61
 
55
- row.push(minD);
56
- }
62
+ toChild = toChild.nextOnCircle;
63
+ } while (toChild !== cpNodeA);
57
64
 
58
65
  graph.push(row);
59
66
  }
@@ -62,12 +69,4 @@ function getGraph(
62
69
  }
63
70
 
64
71
 
65
- function getHoleCloserNext(
66
- pairs: Map<CpNode,CpNode>,
67
- holeCloser: CpNode) {
68
-
69
- return pairs.get(holeCloser)!.next;
70
- }
71
-
72
-
73
72
  export { getGraph }
@@ -1,8 +1,11 @@
1
- import { getBoundingBox } from "flo-bezier3";
1
+ import { getBoundingBox, getBoundingBoxTight } from "flo-bezier3";
2
2
  import { memoize } from "flo-memoize";
3
3
 
4
4
 
5
+ /** The (loose, axis-aligned) bounding box of a bezier curve - memoized on its control points. */
5
6
  const getBoundingBox$ = memoize(getBoundingBox);
7
+ /** The tight (rotated) bounding box of a bezier curve - memoized on its control points. */
8
+ const getBoundingBoxTight$ = memoize(getBoundingBoxTight);
6
9
 
7
10
 
8
- export { getBoundingBox$ }
11
+ export { getBoundingBox$, getBoundingBoxTight$ }
@@ -1,7 +1,7 @@
1
- import { squaredDistanceBetween } from 'flo-vector2d';
2
-
3
-
4
1
  /**
2
+ * Returns the closest squared distance from the point `p` to the given
3
+ * axis-aligned box `[[minX, minY], [maxX, maxY]]`, i.e. `0` if `p` is inside.
4
+ *
5
5
  * @internal
6
6
  */
7
7
  function getClosestSquareDistanceToRect(
@@ -18,17 +18,17 @@ function getClosestSquareDistanceToRect(
18
18
 
19
19
  if (xp < x0) {
20
20
  if (yp < y0) {
21
- return squaredDistanceBetween(box[0], p);
21
+ return (x0 - xp)**2 + (y0 - yp)**2;
22
22
  } else if (yp > y1) {
23
- return squaredDistanceBetween([x0,y1], p);
23
+ return (x0 - xp)**2 + (yp - y1)**2;
24
24
  } else {
25
25
  return (x0 - xp)**2;
26
26
  }
27
27
  } else if (xp > x1) {
28
28
  if (yp < y0) {
29
- return squaredDistanceBetween([x1,y0], p);
29
+ return (xp - x1)**2 + (y0 - yp)**2;
30
30
  } else if (yp > y1) {
31
- return squaredDistanceBetween(box[1], p);
31
+ return (xp - x1)**2 + (yp - y1)**2;
32
32
  } else {
33
33
  return (xp - x1)**2;
34
34
  }
@@ -1,29 +1,31 @@
1
- import {
2
- squaredDistanceBetweenPointAndLineSegment, squaredDistanceBetween
3
- } from 'flo-vector2d';
1
+ import { squaredDistanceBetweenPointAndLineSegment, squaredDistanceBetween } from 'flo-vector2d';
2
+
3
+ const { min } = Math;
4
4
 
5
5
 
6
6
  /**
7
+ * Returns the closest squared distance from the point `p` to the given
8
+ * (rotated) rectangle given by its 4 corners in order, i.e. `0` if `p` is
9
+ * inside the rectangle.
10
+ *
7
11
  * @internal
8
12
  */
9
13
  function getClosestSquaredDistanceToRotatedRect(ps: number[][], p: number[]) {
10
- const ds = [0,1,2,3]
11
- .map(i => squaredDistanceBetweenPointAndLineSegment(
12
- p,
13
- [ps[i], ps[(i + 1) % 4]]
14
- )
15
- );
16
-
14
+ const d0 = squaredDistanceBetweenPointAndLineSegment(p, [ps[0], ps[1]]);
15
+ const d1 = squaredDistanceBetweenPointAndLineSegment(p, [ps[1], ps[2]]);
16
+ const d2 = squaredDistanceBetweenPointAndLineSegment(p, [ps[2], ps[3]]);
17
+ const d3 = squaredDistanceBetweenPointAndLineSegment(p, [ps[3], ps[0]]);
18
+
17
19
  const width = squaredDistanceBetween(ps[0], ps[1]);
18
20
  const height = squaredDistanceBetween(ps[0], ps[3]);
19
21
 
20
- if (ds[0] <= height && ds[2] <= height &&
21
- ds[1] <= width && ds[3] <= width) {
22
+ if (d0 <= height && d2 <= height &&
23
+ d1 <= width && d3 <= width) {
22
24
 
23
25
  return 0; // Inside rotated rect
24
26
  }
25
27
 
26
- return Math.min(...ds);
28
+ return min(d0, d1, d2, d3);
27
29
  }
28
30
 
29
31
 
@@ -1,7 +1,6 @@
1
1
  import { toPowerBasisDd } from 'flo-bezier3';
2
- import { twoDiff, ddMultDouble2, ddAddDd, ddMultDd, ddNegativeOf, ddMultByNeg2, ddMultBy2, ddDiffDouble } from 'double-double';
2
+ import { ddMultDouble2, ddAddDd, ddMultDd, ddNegativeOf, ddMultByNeg2, ddMultBy2, ddDiffDouble } from 'double-double';
3
3
 
4
- const td = twoDiff;
5
4
  const qmd = ddMultDouble2;
6
5
  const qaq = ddAddDd;
7
6
  const qmq = ddMultDd;
package/src/index.ts CHANGED
@@ -8,7 +8,7 @@ export type { PointOnShape } from './point-on-shape/point-on-shape.js';
8
8
  export type { Circle } from './geometry/circle.js';
9
9
  export type { CurvePiece } from './mat/curve-piece.js';
10
10
  export type { Timing } from './debug/debug.js';
11
- export type { Debug } from './debug/debug.js';
11
+ export type { Debug, Elems } from './debug/debug.js';
12
12
  export type { MatOptions } from './find-mat/mat-options.js';
13
13
 
14
14
  export { floydWarshall } from './floyd-warshall/floyd-warshall.js';
@@ -35,7 +35,8 @@ export { getSharpCornersOnLoop } from './find-mat/get-sharp-corners.js';
35
35
  export { getFor2ProngsOnLoop } from './find-mat/get-for-2-prongs-on-loop.js';
36
36
  export { getPotentialClosestPointsOnCurveCertified } from './closest-boundary-point/get-potential-closest-points-on-curve-certified.js';
37
37
  export { getCloseBoundaryPointsCertified } from './closest-boundary-point/get-close-boundary-points-certified.js';
38
- export { getPartialMeta } from './find-mat/get-meta.js';
38
+ export { cloneMat } from './mat/clone-mat.js';
39
+ export { cloneMeta } from './mat/clone-meta.js';
39
40
  export { findAndAddHoleClosing2Prongs } from './find-2-prong/find-and-add-hole-closing-2-prongs.js';
40
41
  export { reconstructFromMats } from './reconstruct-from-mat/reconstruct-from-mat.js';
41
42
  export { getOsculatingCircle } from './point-on-shape/get-osculating-circle.js';
@@ -3,14 +3,20 @@ import { clone } from "../cp-node/fs/clone.js";
3
3
  import { cloneMeta } from "./clone-meta.js";
4
4
 
5
5
 
6
+ /**
7
+ * Returns a deep clone of the given `Mat` (its `CpNode`s are cloned and its
8
+ * `meta` rebuilt for the clones; the boundary loops are shared).
9
+ *
10
+ * @param mat the `Mat` to clone
11
+ */
6
12
  function cloneMat(
7
13
  mat: Mat): Mat {
8
14
 
9
- const { cpNode, meta } = mat;
15
+ const cpNode = clone(mat.cpNode);
10
16
 
11
17
  return {
12
- cpNode: clone(cpNode),
13
- meta: cloneMeta(cpNode, meta)
18
+ cpNode,
19
+ meta: cloneMeta(cpNode, mat.meta)
14
20
  }
15
21
  }
16
22
 
@@ -3,6 +3,14 @@ import type { CpNode } from '../cp-node/cp-node.js';
3
3
  import { createNewCpTrees } from './create-new-cp-trees.js';
4
4
 
5
5
 
6
+ /**
7
+ * Returns a clone of the given `MatMeta` for the given (already cloned)
8
+ * `CpNode`, i.e. with `cpTrees` rebuilt from the clone and a fresh
9
+ * `lastInsertId`.
10
+ *
11
+ * @param cpNode the (cloned) `CpNode` the meta is for
12
+ * @param meta the `MatMeta` to clone
13
+ */
6
14
  function cloneMeta(
7
15
  cpNode: CpNode,
8
16
  meta: MatMeta): MatMeta {
@@ -6,29 +6,27 @@ import { comparePoss } from '../point-on-shape/compare-poss.js';
6
6
 
7
7
  /**
8
8
  * Returns the ordered bezier pieces between the two given `CpNode`s.
9
- *
10
- * @param cpNodes - An ordered pair that represents the start and end points of
9
+ *
10
+ * * NOTE: an earlier version 'stitched' pieces together at hole closers and
11
+ * loop endpoints to avoid duplicate antipodal points later; this was removed
12
+ * (duplicates are now checked for in `find2Prong`) - see the git history
13
+ * before 2026-10 for that code.
14
+ *
15
+ * @param cpNodes - An ordered pair that represents the start and end points of
11
16
  * the boundary piece
12
- *
17
+ *
13
18
  * @internal
14
19
  */
15
20
  function getBoundaryPieceBeziers(
16
21
  cpNodes: [CpNode,CpNode]): CurvePiece[] {
17
22
 
18
- let cpThis = cpNodes[0];
23
+ let cpThis = cpNodes[0];
19
24
  const cpEnd = cpNodes[1];
20
-
21
- const curvePieces: CurvePiece[] = [];
22
25
 
23
- // NOTE❗ Currently removed stichables; we're just checking for duplicates
24
- // later in `find2Prong`; KEEP for possible future use.
25
- // We have to stich curves together if they're at a hole closer or at the
26
- // endpoints of a loop to avoid duplicates later within the code; the map
27
- // is from curves
28
- // const stichables: Map<Curve, number[]> = new Map();
26
+ const curvePieces: CurvePiece[] = [];
29
27
 
30
28
  // As opposed to going around the circle and taking the last exit
31
- let goStraight = true;
29
+ let goStraight = true;
32
30
  do {
33
31
  const posThis = cpThis .pointOnShape;
34
32
  const posNext = cpThis.next.pointOnShape;
@@ -37,31 +35,6 @@ function getBoundaryPieceBeziers(
37
35
 
38
36
  if (!goStraight) {
39
37
  goStraight = true;
40
- // NOTE❗ Currently removed stichables; we're just checking for duplicates
41
- // later in `find2Prong`; KEEP for possible future use.
42
- // const { loop: loopThis } = curveThis;
43
- // const cpPrevOnCircle = cpThis.prevOnCircle;
44
- // const curvePrevOnCircle = cpPrevOnCircle.pointOnShape.curve;
45
- // const { loop: loopNext } = cpPrevOnCircle.pointOnShape.curve;
46
-
47
-
48
- // if (loopThis !== loopNext) {
49
- // let idxsThis = stichables.get(curveThis);
50
- // if (idxsThis === undefined) {
51
- // idxsThis = [];
52
- // stichables.set(curveThis, idxsThis);
53
- // }
54
- // idxsThis.push(curvePieces.length - 1); // last `CurvePiece` idx
55
-
56
- // let idxsNext = stichables.get(curvePrevOnCircle);
57
- // if (idxsNext === undefined) {
58
- // idxsNext = [];
59
- // stichables.set(curvePrevOnCircle, idxsNext);
60
- // }
61
- // idxsNext.push(curvePieces.length); // upcoming `CurvePiece` idx
62
- // }
63
-
64
- // cpThis = cpPrevOnCircle; // take last exit
65
38
  cpThis = cpThis.prevOnCircle; // take last exit
66
39
  continue;
67
40
  }
@@ -93,91 +66,17 @@ function getBoundaryPieceBeziers(
93
66
  // so split at t = 1.
94
67
 
95
68
  if (curveThis.loop === curveNext.loop) {
96
- const initialCurvePiece = {
69
+ curvePieces.push({
97
70
  curve: curveThis, ts: [posThis.t, 1]
98
- };
99
- curvePieces.push(initialCurvePiece);
71
+ });
100
72
 
101
73
  // Fill in any curves skipped between the two points.
102
74
  addSkippedBeziers(curvePieces, curveThis, curveNext, posNext.t);
103
-
104
- // NOTE❗ Currently removed stichables; we're just checking for duplicates
105
- // later in `find2Prong`; KEEP for possible future use.
106
- // const finalCurvePiece = curvePieces[curvePieces.length - 1];
107
- // if (initialCurvePiece.curve === finalCurvePiece!.curve) {
108
- // const { ts: tsS } = initialCurvePiece;
109
- // const { ts: tsE } = finalCurvePiece!;
110
-
111
- // // If it is a closed loop we must join the endpoints to prevent duplicate
112
- // // antipodal points later
113
- // if (tsS[0] === tsE[1]) {
114
- // initialCurvePiece.ts[0] = tsE[0];
115
-
116
- // if (curvePieces.length > 1) {
117
- // curvePieces.pop();
118
- // }
119
- // // console.log('was inner closed loop')
120
- // }
121
- // }
122
75
  }
123
76
 
124
77
  cpThis = cpThis.next;
125
78
  } while (cpThis !== cpEnd);
126
79
 
127
- // NOTE❗ Currently removed stichables; we're just checking for duplicates
128
- // later in `find2Prong`; KEEP for possible future use.
129
- // if (stichables.size > 0) {
130
- // for (const [loop,idxs] of stichables.entries()) {
131
- // if (idxs.length === 2) {
132
- // const curvePieceS = curvePieces[idxs[0]]!;
133
- // const curvePieceE = curvePieces[idxs[1]]!;
134
-
135
- // if (curvePieceS === undefined || curvePieceE === undefined) {
136
- // console.log(curvePieceS);
137
- // console.log(curvePieceE);
138
- // continue;
139
- // }
140
-
141
- // const { curve: curveS, ts: tsS } = curvePieceS;
142
- // const { curve: curveE, ts: tsE } = curvePieceE;
143
- // if (curveS !== curveE) {
144
- // continue;
145
- // }
146
-
147
- // // If it is a closed loop we must join the endpoints to prevent duplicate
148
- // // antipodal points later
149
- // if (tsS[0] === tsE[1]) {
150
- // curvePieceS.ts[0] = tsE[0];
151
- // // console.log('was closed loop 1')
152
- // } else if (tsE[0] === tsS[1]) {
153
- // curvePieceS.ts[1] = tsE[1];
154
- // // console.log('was closed loop 2')
155
- // }
156
- // if (idxs[0] !== idxs[1]) {
157
- // curvePieces[idxs[1]] = undefined;
158
- // }
159
- // }
160
- // }
161
- // }
162
-
163
- // NOTE❗ The below endcurve check is not enough for specific cases involving
164
- // multiple hole closers; KEEP for now but must use stichables instead
165
- // if (curvePieces[0]!.curve === curvePieces[curvePieces.length - 1]!.curve) {
166
- // const { ts: tsS } = curvePieces[0]!;
167
- // const { ts: tsE } = curvePieces[curvePieces.length - 1]!;
168
-
169
- // // If it is a closed loop we must join the endpoints to prevent duplicate
170
- // // antipodal points later
171
- // if (tsS[0] === tsE[1]) {
172
- // curvePieces[0]!.ts[0] = tsE[0];
173
-
174
- // if (curvePieces.length > 1) {
175
- // curvePieces.pop();
176
- // }
177
- // // console.log('was closed loop')
178
- // }
179
- // }
180
-
181
80
  return curvePieces;
182
81
  }
183
82
 
@@ -187,9 +86,9 @@ function getBoundaryPieceBeziers(
187
86
  * Adds pieces of skipped beziers
188
87
  */
189
88
  function addSkippedBeziers(
190
- curvePieces: (CurvePiece | undefined)[],
191
- curveStart: Curve,
192
- curveEnd: Curve,
89
+ curvePieces: CurvePiece[],
90
+ curveStart: Curve,
91
+ curveEnd: Curve,
193
92
  t1: number) {
194
93
 
195
94
  // Walk forward through the loop until the end curve is reached.
@@ -5,10 +5,12 @@ import type { MatMeta } from './mat-meta.js';
5
5
  import { distanceBetween, toUnitVector, fromTo, dot } from 'flo-vector2d';
6
6
  import { getCpNodeNeighbors } from './get-cp-node-neighbors.js';
7
7
 
8
+ const { cos, PI: π } = Math;
9
+
8
10
 
9
11
  /** @internal */
10
12
  const DEGREES = 1;
11
- const ANGLE_THRESHOLD = Math.cos(DEGREES * (Math.PI / 180));
13
+ const ANGLE_THRESHOLD = cos(DEGREES * (π/180));
12
14
 
13
15
 
14
16
  /**
@@ -1,21 +1,24 @@
1
1
  import type { CpNode } from '../cp-node/cp-node.js';
2
2
  import { getAllOnLoop } from '../cp-node/fs/get-all-on-loop.js';
3
3
  import { getRealProngCount } from '../cp-node/fs/get-real-prong-count.js';
4
+ import { getLargestOf } from './get-largest-vertex.js';
4
5
 
5
6
 
7
+ /**
8
+ * Returns the `CpNode` on a 3-prong (or higher) MAT vertex with the largest
9
+ * maximal disk radius, or `undefined` if there is none.
10
+ *
11
+ * @param cpNode any `CpNode` on the MAT
12
+ */
6
13
  function getLargest3Prong(
7
- cpNode: CpNode) {
14
+ cpNode: CpNode): CpNode | undefined {
8
15
 
9
16
  const cpNodes = getAllOnLoop(cpNode)
10
17
  .filter(cpNode => getRealProngCount(cpNode) >= 3);
11
18
 
12
19
  if (cpNodes.length === 0) { return undefined; }
13
20
 
14
- return cpNodes.reduce(function(maxCpNode: CpNode, cpNode: CpNode) {
15
- return maxCpNode.pointOnShape.circle.radius >= cpNode.pointOnShape.circle.radius
16
- ? maxCpNode
17
- : cpNode
18
- }, cpNodes[0]);
21
+ return getLargestOf(cpNodes);
19
22
  }
20
23
 
21
24
 
@@ -2,17 +2,33 @@ import type { CpNode } from '../cp-node/cp-node.js';
2
2
  import { getAllOnLoop } from '../cp-node/fs/get-all-on-loop.js';
3
3
 
4
4
 
5
- function getLargestVertex(
6
- cpNode: CpNode) {
7
-
8
- const cpNodes = getAllOnLoop(cpNode);
9
-
10
- return cpNodes.reduce(function(maxCpNode: CpNode, cpNode: CpNode) {
11
- return maxCpNode.pointOnShape.circle.radius >= cpNode.pointOnShape.circle.radius
5
+ /**
6
+ * Returns the `CpNode` (of the given ones) with the largest maximal disk
7
+ * radius (the first one in case of a tie).
8
+ *
9
+ * @param cpNodes a non-empty array of `CpNode`s
10
+ *
11
+ * @internal
12
+ */
13
+ function getLargestOf(cpNodes: CpNode[]): CpNode {
14
+ return cpNodes.reduce((maxCpNode, cpNode) =>
15
+ maxCpNode.pointOnShape.circle.radius >= cpNode.pointOnShape.circle.radius
12
16
  ? maxCpNode
13
17
  : cpNode
14
- }, cpNodes[0]);
18
+ );
19
+ }
20
+
21
+
22
+ /**
23
+ * Returns the `CpNode` on the MAT with the largest maximal disk radius.
24
+ *
25
+ * @param cpNode any `CpNode` on the MAT
26
+ */
27
+ function getLargestVertex(
28
+ cpNode: CpNode): CpNode {
29
+
30
+ return getLargestOf(getAllOnLoop(cpNode));
15
31
  }
16
32
 
17
33
 
18
- export { getLargestVertex }
34
+ export { getLargestVertex, getLargestOf }