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
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.
@@ -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 }
@@ -0,0 +1,314 @@
1
+ import { closestPointOnBezier, controlPointLinesLength, evalDeCasteljau, fromTo } from 'flo-bezier3';
2
+
3
+ const { max, sqrt } = Math;
4
+
5
+
6
+ /**
7
+ * A point `q` on a piecewise bezier curve at parameter `t` of piece `k`
8
+ * together with its distance `d` to some other point.
9
+ *
10
+ * @internal
11
+ */
12
+ interface Foot {
13
+ d: number;
14
+ q: number[];
15
+ k: number;
16
+ t: number;
17
+ }
18
+
19
+
20
+ /**
21
+ * Returns the closest point on the piecewise bezier curve given by `curves`
22
+ * to the point `p` (as a `Foot`), i.e. the piece-wise minimum of the
23
+ * (certified) `closestPointOnBezier` of `flo-bezier3`.
24
+ *
25
+ * @param p the point
26
+ * @param curves the pieces of the piecewise bezier curve
27
+ *
28
+ * @internal
29
+ */
30
+ function closestPointOnCurves(
31
+ p: number[],
32
+ curves: number[][][]): Foot {
33
+
34
+ let best: Foot = { d: Infinity, q: p, k: 0, t: 0 };
35
+ for (let k=0; k<curves.length; k++) {
36
+ const c = closestPointOnBezier(curves[k], p);
37
+ if (c.d < best.d) {
38
+ best = { d: c.d, q: c.p, k, t: c.t };
39
+ }
40
+ }
41
+
42
+ return best;
43
+ }
44
+
45
+
46
+ /**
47
+ * Returns the distance from the point `p` to the piecewise bezier curve given
48
+ * by `curves` (i.e. the minimum over the pieces of the distance to the piece).
49
+ *
50
+ * @param p the point
51
+ * @param curves the pieces of the piecewise bezier curve
52
+ *
53
+ * @internal
54
+ */
55
+ function distanceToCurves(
56
+ p: number[],
57
+ curves: number[][][]): number {
58
+
59
+ return closestPointOnCurves(p, curves).d;
60
+ }
61
+
62
+
63
+ /**
64
+ * Evaluates the bezier curve `ps` (of order 1, 2 or 3) and its first two
65
+ * derivatives at `t`, returned as `[B, B', B'']`.
66
+ *
67
+ * @internal
68
+ */
69
+ function evalWithDerivatives(
70
+ ps: number[][],
71
+ t: number): [number[], number[], number[]] {
72
+
73
+ const [p0, p1] = ps;
74
+
75
+ if (ps.length === 2) {
76
+ return [
77
+ [p0[0] + t*(p1[0] - p0[0]), p0[1] + t*(p1[1] - p0[1])],
78
+ [p1[0] - p0[0], p1[1] - p0[1]],
79
+ [0, 0]
80
+ ];
81
+ }
82
+
83
+ const s = 1 - t;
84
+
85
+ if (ps.length === 3) {
86
+ const p2 = ps[2];
87
+ return [
88
+ [s*s*p0[0] + 2*s*t*p1[0] + t*t*p2[0],
89
+ s*s*p0[1] + 2*s*t*p1[1] + t*t*p2[1]],
90
+ [2*(s*(p1[0] - p0[0]) + t*(p2[0] - p1[0])),
91
+ 2*(s*(p1[1] - p0[1]) + t*(p2[1] - p1[1]))],
92
+ [2*(p2[0] - 2*p1[0] + p0[0]),
93
+ 2*(p2[1] - 2*p1[1] + p0[1])]
94
+ ];
95
+ }
96
+
97
+ const p2 = ps[2];
98
+ const p3 = ps[3];
99
+ return [
100
+ [s*s*s*p0[0] + 3*s*s*t*p1[0] + 3*s*t*t*p2[0] + t*t*t*p3[0],
101
+ s*s*s*p0[1] + 3*s*s*t*p1[1] + 3*s*t*t*p2[1] + t*t*t*p3[1]],
102
+ [3*(s*s*(p1[0] - p0[0]) + 2*s*t*(p2[0] - p1[0]) + t*t*(p3[0] - p2[0])),
103
+ 3*(s*s*(p1[1] - p0[1]) + 2*s*t*(p2[1] - p1[1]) + t*t*(p3[1] - p2[1]))],
104
+ [6*(s*(p2[0] - 2*p1[0] + p0[0]) + t*(p3[0] - 2*p2[0] + p1[0])),
105
+ 6*(s*(p2[1] - 2*p1[1] + p0[1]) + t*(p3[1] - 2*p2[1] + p1[1]))]
106
+ ];
107
+ }
108
+
109
+
110
+ /**
111
+ * Returns a point on piece `k` of `curves` close to `p` found by a few Newton
112
+ * iterations on the squared distance starting from parameter `t0`, as a
113
+ * `Foot`.
114
+ *
115
+ * * the returned distance is thus an *upper bound* on the distance from `p`
116
+ * to the piecewise curve (any point on the curve gives one) - it is not
117
+ * certified to be the minimum
118
+ *
119
+ * @internal
120
+ */
121
+ function newtonFoot(
122
+ p: number[],
123
+ curves: number[][][],
124
+ k: number,
125
+ t0: number): Foot {
126
+
127
+ const ps = curves[k];
128
+ if (ps.length === 1) {
129
+ const q = ps[0];
130
+ return { d: sqrt((q[0] - p[0])**2 + (q[1] - p[1])**2), q, k, t: 0 };
131
+ }
132
+
133
+ let t = t0;
134
+ let [q, dq, ddq] = evalWithDerivatives(ps, t);
135
+ let rx = q[0] - p[0];
136
+ let ry = q[1] - p[1];
137
+ let best: Foot = { d: sqrt(rx*rx + ry*ry), q, k, t };
138
+
139
+ for (let i=0; i<4; i++) {
140
+ // minimize g(t) = |B(t) - p|²/2: g' = r·B', g'' = B'·B' + r·B''
141
+ const g1 = rx*dq[0] + ry*dq[1];
142
+ const g2 = dq[0]*dq[0] + dq[1]*dq[1] + rx*ddq[0] + ry*ddq[1];
143
+ if (g2 <= 0) { break; }
144
+
145
+ let t_ = t - g1/g2;
146
+ if (t_ < 0) { t_ = 0; } else if (t_ > 1) { t_ = 1; }
147
+ if (t_ === t) { break; }
148
+ t = t_;
149
+
150
+ [q, dq, ddq] = evalWithDerivatives(ps, t);
151
+ rx = q[0] - p[0];
152
+ ry = q[1] - p[1];
153
+ const d = sqrt(rx*rx + ry*ry);
154
+ if (d < best.d) { best = { d, q, k, t }; }
155
+ }
156
+
157
+ return best;
158
+ }
159
+
160
+
161
+ /**
162
+ * Returns the maximum distance from the point `q` to the control points of
163
+ * `ps` - an upper bound on the distance from `q` to any point on the bezier
164
+ * curve `ps` (which lies within the convex hull of its control points).
165
+ *
166
+ * @internal
167
+ */
168
+ function maxDistanceToControlPoints(
169
+ ps: number[][],
170
+ q: number[]): number {
171
+
172
+ let m = 0;
173
+ for (let i=0; i<ps.length; i++) {
174
+ const c = ps[i];
175
+ const dd = (c[0] - q[0])**2 + (c[1] - q[1])**2;
176
+ if (dd > m) { m = dd; }
177
+ }
178
+
179
+ return sqrt(m);
180
+ }
181
+
182
+
183
+ /**
184
+ * An interval `[tS,tE]` of the parameter of the 'from' curve together with
185
+ * the feet (on the 'to' curve) of its endpoints.
186
+ *
187
+ * @internal
188
+ */
189
+ interface Interval {
190
+ tS: number;
191
+ tE: number;
192
+ fS: Foot;
193
+ fE: Foot;
194
+ }
195
+
196
+
197
+ /**
198
+ * Returns `true` if the one-sided Hausdorff distance from the bezier curve `A`
199
+ * to the piecewise bezier curve `B` exceeds `tolerance` and `false` otherwise.
200
+ *
201
+ * * this is a *decision procedure* and is thus much cheaper than computing the
202
+ * distance (e.g. via `hausdorffDistanceOneSided` from `flo-bezier3`) and then
203
+ * comparing it: it stops as soon as either a point on `A` further than
204
+ * `tolerance` from `B` is found (a certified *lower* bound exceeding the
205
+ * tolerance) or every piece of `A` is certified to be within `tolerance`
206
+ * (a certified *upper* bound)
207
+ * * `A` is bisected into parameter intervals; the upper bound on an interval
208
+ * `[tS,tE]` is the smaller of
209
+ * * `(hS + hE + L)/2` where `hS`, `hE` are (upper bounds on) the
210
+ * distances from its endpoints to `B` and `L` is the control polygon
211
+ * length of `A` restricted to the interval (an upper bound on its arc
212
+ * length): any point on the interval is within `L` of both endpoints so
213
+ * its distance to `B` is at most `min(hS + l, hE + (L - l))` with `l`
214
+ * the arc length from the start, maximized at `(hS + hE + L)/2`
215
+ * * the maximum distance from the foot (on `B`) of either endpoint to the
216
+ * control points of `A` restricted to the interval (the sub-curve lies
217
+ * within the convex hull of its control points, within which the
218
+ * distance to a fixed point is maximized at a vertex)
219
+ * * the distances from sample points on `A` to `B` are found cheaply by
220
+ * Newton iteration from the feet of the neighboring samples - these are upper
221
+ * bounds (any point on `B` gives one) which suffice for certifying the
222
+ * acceptance of an interval; only when such a bound exceeds the tolerance is
223
+ * the certified (and expensive) closest point computed to decide whether the
224
+ * tolerance is really exceeded
225
+ * * `B` need not be smooth, nor need its pieces be connected
226
+ * * the result is approximate only to the extent that the floating point
227
+ * evaluations are, i.e. a decision is only taken once it is certain up to
228
+ * roundoff
229
+ *
230
+ * @param A the 'from' bezier curve given by its control points
231
+ * @param B the 'to' piecewise bezier curve given as an array of bezier curves
232
+ * @param tolerance the distance to compare against
233
+ * @param maxIterations the maximum number of interval bisections (each
234
+ * costing one cheap closest point calculation) before giving up, in which
235
+ * case `true` is returned (the conservative answer for simplification
236
+ * purposes); defaults to `1000` (curves only just within tolerance may
237
+ * need many bisections, especially where they run nearly parallel to `B`)
238
+ *
239
+ * @internal
240
+ */
241
+ function hausdorffDistanceOneSidedExceeds(
242
+ A: number[][],
243
+ B: number[][][],
244
+ tolerance: number,
245
+ maxIterations = 1000): boolean {
246
+
247
+ const fS = closestPointOnCurves(A[0], B);
248
+ if (fS.d > tolerance) { return true; }
249
+ const fE = closestPointOnCurves(A[A.length - 1], B);
250
+ if (fE.d > tolerance) { return true; }
251
+
252
+ if (A.length <= 2) {
253
+ // A point or a line: if `B` is a single line (a convex set) the
254
+ // distance is convex along `A` and thus maximal at an endpoint.
255
+ if (A.length === 1 || (B.length === 1 && B[0].length <= 2)) {
256
+ return false;
257
+ }
258
+ }
259
+
260
+ // Depth first; the stack never holds more than about `2*log2(iterations)`
261
+ // intervals.
262
+ const stack: Interval[] = [{ tS: 0, tE: 1, fS, fE }];
263
+ let iterations = 0;
264
+ while (stack.length > 0) {
265
+ const { tS, tE, fS, fE } = stack.pop()!;
266
+
267
+ const ps = tS === 0 && tE === 1 ? A : fromTo(A, tS, tE);
268
+
269
+ // the entire interval is certified within tolerance if either upper
270
+ // bound says so
271
+ if ((fS.d + fE.d + controlPointLinesLength(ps))/2 <= tolerance) {
272
+ continue;
273
+ }
274
+ if (maxDistanceToControlPoints(ps, fS.q) <= tolerance ||
275
+ maxDistanceToControlPoints(ps, fE.q) <= tolerance) {
276
+ continue;
277
+ }
278
+
279
+ if (iterations++ >= maxIterations) {
280
+ return true; // undecided - be conservative
281
+ }
282
+
283
+ const tM = (tS + tE)/2;
284
+ const pM = evalDeCasteljau(A, tM);
285
+
286
+ // a cheap upper bound on the distance from `pM` to `B` - by Newton
287
+ // iteration from the feet of the endpoints
288
+ let fM = newtonFoot(pM, B, fS.k, fS.k === fE.k ? (fS.t + fE.t)/2 : fS.t);
289
+ if (fS.k !== fE.k) {
290
+ const fM_ = newtonFoot(pM, B, fE.k, fE.t);
291
+ if (fM_.d < fM.d) { fM = fM_; }
292
+ }
293
+
294
+ if (fM.d > tolerance) {
295
+ // possibly exceeds - now get the certified closest point
296
+ fM = closestPointOnCurves(pM, B);
297
+ if (fM.d > tolerance) { return true; }
298
+ }
299
+
300
+ // push the half with the larger lower bound last so it is tried first
301
+ if (max(fS.d, fM.d) >= max(fM.d, fE.d)) {
302
+ stack.push({ tS: tM, tE, fS: fM, fE });
303
+ stack.push({ tS, tE: tM, fS, fE: fM });
304
+ } else {
305
+ stack.push({ tS, tE: tM, fS, fE: fM });
306
+ stack.push({ tS: tM, tE, fS: fM, fE });
307
+ }
308
+ }
309
+
310
+ return false;
311
+ }
312
+
313
+
314
+ export { hausdorffDistanceOneSidedExceeds, distanceToCurves, closestPointOnCurves }
@@ -1,7 +1,5 @@
1
1
  import type { Loop } from 'flo-boolean';
2
2
  import type { CpNode } from '../cp-node/cp-node.js';
3
- import type { Curve } from 'flo-boolean';
4
- import type { TriMap } from '../utils/tri-map.js';
5
3
  import { RbTree } from 'flo-ll-rb-tree';
6
4
 
7
5
 
@@ -9,13 +7,6 @@ interface MatMeta {
9
7
  /** The minimum power of 2 such that `2**maxCoordPowerOf2 >= "the max coordinate"` */
10
8
  readonly maxCoordPowerOf2: number;
11
9
  readonly squaredDiagonalLength: number;
12
- readonly looseBoundingBoxes: number[][][];
13
- readonly tightBoundingBoxes: number[][][];
14
- readonly boundingHulls: number[][][];
15
-
16
- readonly sharpCorners: Curve[];
17
- readonly dullCorners: Curve[];
18
-
19
10
  readonly loops: Loop[];
20
11
 
21
12
  /**