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,214 +1,197 @@
1
- import type { CpNode } from '../cp-node/cp-node.js';
2
- import type { CurvePiece } from '../mat/curve-piece.js';
3
- import type { ThreeProngInfo } from './three-prong-info.js';
4
- import type { PrePointOnShape } from '../point-on-shape/point-on-shape.js';
5
- import { circumCenter as getCircumCenter, fromTo, len, distanceBetween, toUnitVector, rotate90Degrees, cross } from 'flo-vector2d';
6
- import { tangent } from 'flo-bezier3';
7
- import { calcInitial3ProngCenter } from './calc-initial-3-prong-center.js';
8
- import { getClosestPoints } from './get-closest-points.js';
9
- import { calcBetterX } from './calc-better-x.js';
10
- import { getCloseBoundaryPointsCertified } from '../closest-boundary-point/get-close-boundary-points-certified.js';
11
- import { getCorner } from '../corner/get-corner.js';
12
- import { isPosCorner } from '../point-on-shape/is-pos-corner.js';
13
- import { getPosCorner$ } from '../point-on-shape/get-pos-corner.js';
14
- import { isSharp } from '../cp-node/fs/is-sharp.js';
15
-
16
- const { min, abs, asin } = Math;
17
-
18
-
19
- /**
20
- * Finds a 3-prong using only the 3 given δs.
21
- *
22
- * @param δs the boundary pieces
23
- * @param idx δ identifier
24
- * @param k δs identifier
25
- * @param curvePiecess
26
- * @param maxCoordPowerOf2
27
- *
28
- * @internal
29
- */
30
- function find3ProngForDelta3s(
31
- δs: [CpNode, CpNode][],
32
- idx: number,
33
- k: number,
34
- curvePiecess: CurvePiece[][],
35
- maxCoordPowerOf2: number): { error: number, threeProngInfo: ThreeProngInfo } | undefined {
36
-
37
- const TOLERANCE = 2**(maxCoordPowerOf2 - 32);
38
- const MAX_ITERATIONS = 10;
39
-
40
- const δs_: [[CpNode,CpNode], [CpNode,CpNode], [CpNode,CpNode]] = [
41
- δs[0],
42
- δs[idx],
43
- δs[δs.length-1]
44
- ];
45
-
46
- const curvePieces_: [CurvePiece[], CurvePiece[], CurvePiece[]] = [
47
- curvePiecess[0],
48
- curvePiecess[idx],
49
- curvePiecess[δs.length - 1]
50
- ];
51
-
52
- const δ3ss: [
53
- [[CpNode, CpNode], [CpNode, CpNode], [CpNode, CpNode]],
54
- [[CpNode, CpNode], [CpNode, CpNode], [CpNode, CpNode]],
55
- [[CpNode, CpNode], [CpNode, CpNode], [CpNode, CpNode]]
56
- ] = [
57
- [δs_[0], δs_[1], δs_[2]],
58
- [δs_[1], δs_[2], δs_[0]],
59
- [δs_[2], δs_[0], δs_[1]],
60
- ];
61
-
62
- const curvePiecess_: [
63
- [CurvePiece[], CurvePiece[], CurvePiece[]],
64
- [CurvePiece[], CurvePiece[], CurvePiece[]],
65
- [CurvePiece[], CurvePiece[], CurvePiece[]]
66
- ] = [
67
- [curvePieces_[0], curvePieces_[1], curvePieces_[2]],
68
- [curvePieces_[1], curvePieces_[2], curvePieces_[0]],
69
- [curvePieces_[2], curvePieces_[0], curvePieces_[1]],
70
- ]
71
-
72
-
73
- const δ3s = δ3ss[k];
74
- const curvePiece3s = curvePiecess_[k];
75
-
76
- if (isSharp(δ3s[0][0])) { return undefined; }
77
-
78
- //----------------------------
79
- // const l1 = curvePiece3s[0].length;
80
- // const l2 = curvePiece3s[1].length;
81
- // const l3 = curvePiece3s[2].length;
82
- // if (l1 === 1 && l2 == 1 && l3 === 1) {
83
- // // console.log('aaa');
84
- // const A = curvePiece3s[0][0].curve.ps;
85
- // const B = curvePiece3s[1][0].curve.ps;
86
- // const C = curvePiece3s[2][0].curve.ps;
87
-
88
- // console.log(A.length, B.length, C.length);
89
- // } else {
90
- // // console.log('bbb');
91
- // }
92
- //----------------------------
93
-
94
-
95
- let poss: PrePointOnShape[] = undefined!;
96
- let j = 0; // Safeguard for slow convergence
97
- let x = calcInitial3ProngCenter(δ3s, curvePiece3s);
98
-
99
- let tolerance = Infinity;
100
- while (tolerance > TOLERANCE && j < MAX_ITERATIONS) {
101
- j++;
102
-
103
- poss = getClosestPoints(x, curvePiece3s);
104
- if (!Number.isFinite(x[0]) || !Number.isFinite(x[1])) {
105
-
106
- // FUTURE - the code can be cleaned up and sped up a lot if we don't
107
- // use this function as is but instead use δs[0] and δs[2] as is
108
- // and make δs[1] include all the rest of the beziers around the
109
- // loop. This check, for instance, would be eliminated completely.
110
- return undefined;
111
- }
112
-
113
- const circumCenter = getCircumCenter(poss.map(x => x.p));
114
- const vectorToZeroV = fromTo(x, circumCenter);
115
-
116
- if (!Number.isFinite(vectorToZeroV[0]) || !Number.isFinite(vectorToZeroV[1])) {
117
-
118
- // FUTURE - the code can be cleaned up and sped up a lot if we don't
119
- // use this function as is but instead use δs[0] and δs[2] as is
120
- // and make δs[1] include all the rest of the beziers around the
121
- // loop. This check, for instance, would be eliminated completely.
122
- return undefined;
123
- }
124
- const upds = calcBetterX(curvePiece3s, x, vectorToZeroV);
125
- x = upds.newX;
126
- poss = upds.newPoss;
127
-
128
- const V = len(vectorToZeroV); // The 'potential'
129
-
130
- tolerance = abs(V - upds.newV);
131
- }
132
-
133
- const radius = (distanceBetween(x, poss[0].p) +
134
- distanceBetween(x, poss[1].p) +
135
- distanceBetween(x, poss[2].p)) / 3;
136
-
137
- const circle = { center: x, radius };
138
-
139
- //-------------------------------------------------------------------------
140
- // Calculate the unit tangent vector at 3-prong circle points - they should
141
- // be very close to tangent to the boundary piece tangents at those points
142
- // (up to sign). Dull corners is a common special case.
143
- //-------------------------------------------------------------------------
144
- let totalAngleError = 0;
145
- for (let i=0; i<3; i++) {
146
- const pos = poss[i];
147
- //----------------------------
148
- // Tangent of circle at point
149
- //----------------------------
150
- const v = toUnitVector(fromTo(pos.p, x));
151
- const v1 = rotate90Degrees(v);
152
-
153
-
154
- //-----------------------------------
155
- // Check if point is on dull crorner
156
- //-----------------------------------
157
- if (isPosCorner(pos) && getPosCorner$(pos).isDull) {
158
- const corner = getCorner(pos.curve.ps, pos.curve.next.ps);
159
- const tans = corner.tangents;
160
- const perps = tans.map( rotate90Degrees );
161
-
162
- const angleError1 = asin( cross( perps[0], v ) );
163
- const angleError2 = asin( cross( v, perps[1] ) );
164
-
165
- let angleError = 0;
166
- if (angleError1 > 0) { angleError += angleError1; }
167
- if (angleError2 > 0) { angleError += angleError2; }
168
-
169
- totalAngleError += angleError;
170
- } else {
171
- //---------------------------
172
- // Tangent of curve at point
173
- //---------------------------
174
- const v2 = toUnitVector( tangent(pos.curve.ps, pos.t) );
175
-
176
- // Cross is more numerically stable than Vector.dot at angles a
177
- // multiple of π **and** is close to the actual angle value
178
- // and can thus just be added to cone method of looking at
179
- // tolerance.
180
-
181
- // Should be close to zero and is close to the actual angle.
182
- const cross_ = abs( asin( cross(v1, v2) ) );
183
-
184
- totalAngleError += cross_;
185
- }
186
- }
187
-
188
- //-------------------------------------------------------------------------
189
- // Calculate radiusDelta, the difference between the radius and the closest
190
- // point to the 3-prong. It should be around 0. If not, this is not a good
191
- // candidate for the 3-prong.
192
- //-------------------------------------------------------------------------
193
- const closestDs = [];
194
- for (let i=0; i<curvePiecess.length; i++) {
195
- const pos = getCloseBoundaryPointsCertified(
196
- curvePiecess[i],
197
- x
198
- )[0];
199
-
200
- closestDs.push( distanceBetween(pos.p, x) );
201
- }
202
- const closestD = min(...closestDs);
203
- const radiusDelta = abs(radius - closestD);
204
-
205
- // Weights below still need to be optimized.
206
- const W1 = 1;
207
- const W2 = 1;
208
- const error = W1*radiusDelta + W2*totalAngleError;
209
-
210
- return { threeProngInfo: { poss, circle, δ3s }, error };
211
- }
212
-
213
-
214
- export { find3ProngForDelta3s }
1
+ import type { CpNode } from '../cp-node/cp-node.js';
2
+ import type { CurvePiece } from '../mat/curve-piece.js';
3
+ import type { ThreeProngInfo } from './three-prong-info.js';
4
+ import type { PrePointOnShape } from '../point-on-shape/point-on-shape.js';
5
+ import { circumCenter as getCircumCenter, fromTo, len, distanceBetween, toUnitVector, rotate90Degrees, cross } from 'flo-vector2d';
6
+ import { tangent } from 'flo-bezier3';
7
+ import { calcInitial3ProngCenter } from './calc-initial-3-prong-center.js';
8
+ import { getClosestPoints } from './get-closest-points.js';
9
+ import { calcBetterX } from './calc-better-x.js';
10
+ import { getCloseBoundaryPointsCertified } from '../closest-boundary-point/get-close-boundary-points-certified.js';
11
+ import { cullCurvePieces } from '../closest-boundary-point/cull-curve-pieces.js';
12
+ import { getCorner$ } from '../corner/get-corner.js';
13
+ import { isPosCorner } from '../point-on-shape/is-pos-corner.js';
14
+ import { getPosCorner$ } from '../point-on-shape/get-pos-corner.js';
15
+ import { isSharp } from '../cp-node/fs/is-sharp.js';
16
+
17
+ const { abs, asin } = Math;
18
+
19
+
20
+ /**
21
+ * Finds a 3-prong using only the 3 given δs.
22
+ *
23
+ * @param δs the boundary pieces
24
+ * @param idx δ identifier
25
+ * @param k δs identifier
26
+ * @param curvePiecess the curve pieces of each boundary piece
27
+ * @param allCurvePieces all of the above flattened into one array
28
+ * @param maxCoordPowerOf2
29
+ *
30
+ * @internal
31
+ */
32
+
33
+ function find3ProngForDelta3s(
34
+ δs: [CpNode, CpNode][],
35
+ idx: number,
36
+ k: number,
37
+ curvePiecess: CurvePiece[][],
38
+ allCurvePieces: CurvePiece[],
39
+ maxCoordPowerOf2: number): { error: number, threeProngInfo: ThreeProngInfo } | undefined {
40
+
41
+ const TOLERANCE = 2**(maxCoordPowerOf2 - 32);
42
+ const MAX_ITERATIONS = 10;
43
+
44
+ // The three boundary pieces (and their curve pieces) with the first,
45
+ // the `idx`th and the last taken, rotated so that the one with index `k`
46
+ // comes first (the first one is treated specially below).
47
+ const δs_ = [δs[0], δs[idx], δs[δs.length-1]];
48
+ const curvePieces_ = [curvePiecess[0], curvePiecess[idx], curvePiecess[δs.length-1]];
49
+ const r = (i: number) => (k + i) % 3;
50
+ const δ3s: [[CpNode,CpNode], [CpNode,CpNode], [CpNode,CpNode]] =
51
+ [δs_[r(0)], δs_[r(1)], δs_[r(2)]];
52
+ const curvePiece3s: [CurvePiece[], CurvePiece[], CurvePiece[]] =
53
+ [curvePieces_[r(0)], curvePieces_[r(1)], curvePieces_[r(2)]];
54
+
55
+ if (isSharp(δ3s[0][0])) { return undefined; }
56
+
57
+ //----------------------------
58
+ // const l1 = curvePiece3s[0].length;
59
+ // const l2 = curvePiece3s[1].length;
60
+ // const l3 = curvePiece3s[2].length;
61
+ // if (l1 === 1 && l2 == 1 && l3 === 1) {
62
+ // // console.log('aaa');
63
+ // const A = curvePiece3s[0][0].curve.ps;
64
+ // const B = curvePiece3s[1][0].curve.ps;
65
+ // const C = curvePiece3s[2][0].curve.ps;
66
+
67
+ // console.log(A.length, B.length, C.length);
68
+ // } else {
69
+ // // console.log('bbb');
70
+ // }
71
+ //----------------------------
72
+
73
+
74
+ let poss: PrePointOnShape[] = undefined!;
75
+ let j = 0; // Safeguard for slow convergence
76
+ let x = calcInitial3ProngCenter(δ3s, curvePiece3s);
77
+
78
+ if (!Number.isFinite(x[0]) || !Number.isFinite(x[1])) {
79
+
80
+ // FUTURE - the code can be cleaned up and sped up a lot if we don't
81
+ // use this function as is but instead use δs[0] and δs[2] as is
82
+ // and make δs[1] include all the rest of the beziers around the
83
+ // loop. This check, for instance, would be eliminated completely.
84
+ return undefined;
85
+ }
86
+
87
+ // the closest points on the three boundary pieces to the current center
88
+ poss = getClosestPoints(x, curvePiece3s);
89
+
90
+ let tolerance = Infinity;
91
+ while (tolerance > TOLERANCE && j < MAX_ITERATIONS) {
92
+ j++;
93
+
94
+
95
+ const circumCenter = getCircumCenter(poss.map(x => x.p));
96
+ const vectorToZeroV = fromTo(x, circumCenter);
97
+
98
+ if (!Number.isFinite(vectorToZeroV[0]) || !Number.isFinite(vectorToZeroV[1])) {
99
+
100
+ // FUTURE - the code can be cleaned up and sped up a lot if we don't
101
+ // use this function as is but instead use δs[0] and δs[2] as is
102
+ // and make δs[1] include all the rest of the beziers around the
103
+ // loop. This check, for instance, would be eliminated completely.
104
+ return undefined;
105
+ }
106
+ const upds = calcBetterX(curvePiece3s, x, vectorToZeroV);
107
+ x = upds.newX;
108
+ // `calcBetterX` already found the closest points at the new center -
109
+ // use them for the next iteration instead of searching again
110
+ poss = upds.newPoss;
111
+
112
+ const V = len(vectorToZeroV); // The 'potential'
113
+
114
+ tolerance = abs(V - upds.newV);
115
+ }
116
+
117
+ const radius = (distanceBetween(x, poss[0].p) +
118
+ distanceBetween(x, poss[1].p) +
119
+ distanceBetween(x, poss[2].p)) / 3;
120
+
121
+ const circle = { center: x, radius };
122
+
123
+ //-------------------------------------------------------------------------
124
+ // Calculate the unit tangent vector at 3-prong circle points - they should
125
+ // be very close to tangent to the boundary piece tangents at those points
126
+ // (up to sign). Dull corners is a common special case.
127
+ //-------------------------------------------------------------------------
128
+ let totalAngleError = 0;
129
+ for (let i=0; i<3; i++) {
130
+ const pos = poss[i];
131
+ //----------------------------
132
+ // Tangent of circle at point
133
+ //----------------------------
134
+ const v = toUnitVector(fromTo(pos.p, x));
135
+ const v1 = rotate90Degrees(v);
136
+
137
+
138
+ //-----------------------------------
139
+ // Check if point is on dull crorner
140
+ //-----------------------------------
141
+ if (isPosCorner(pos) && getPosCorner$(pos).isDull) {
142
+ const corner = getCorner$(pos.curve.ps, pos.curve.next.ps);
143
+ const tans = corner.tangents;
144
+ const perps = tans.map( rotate90Degrees );
145
+
146
+ const angleError1 = asin( cross( perps[0], v ) );
147
+ const angleError2 = asin( cross( v, perps[1] ) );
148
+
149
+ let angleError = 0;
150
+ if (angleError1 > 0) { angleError += angleError1; }
151
+ if (angleError2 > 0) { angleError += angleError2; }
152
+
153
+ totalAngleError += angleError;
154
+ } else {
155
+ //---------------------------
156
+ // Tangent of curve at point
157
+ //---------------------------
158
+ const v2 = toUnitVector( tangent(pos.curve.ps, pos.t) );
159
+
160
+ // Cross is more numerically stable than Vector.dot at angles a
161
+ // multiple of π **and** is close to the actual angle value
162
+ // and can thus just be added to cone method of looking at
163
+ // tolerance.
164
+
165
+ // Should be close to zero and is close to the actual angle.
166
+ const cross_ = abs( asin( cross(v1, v2) ) );
167
+
168
+ totalAngleError += cross_;
169
+ }
170
+ }
171
+
172
+ //-------------------------------------------------------------------------
173
+ // Calculate radiusDelta, the difference between the radius and the closest
174
+ // point to the 3-prong. It should be around 0. If not, this is not a good
175
+ // candidate for the 3-prong.
176
+ //-------------------------------------------------------------------------
177
+ // Only boundary pieces that come within the radius of the center can be
178
+ // closer than the three touching pieces, so cull against the radius first
179
+ // (cheap, memoized bounding box tests) and run the (expensive) certified
180
+ // closest point search once on the survivors only. The touching pieces
181
+ // always survive (their distance is about the radius) so the result is
182
+ // the true closest distance over all the boundary pieces.
183
+ const nearCurvePieces = cullCurvePieces(allCurvePieces, x, (1 + 2**-20)*radius*radius);
184
+ const closestPos = getCloseBoundaryPointsCertified(nearCurvePieces, x)[0];
185
+ const closestD = closestPos === undefined ? radius : distanceBetween(closestPos.p, x);
186
+ const radiusDelta = abs(radius - closestD);
187
+
188
+ // Weights below still need to be optimized.
189
+ const W1 = 1;
190
+ const W2 = 1;
191
+ const error = W1*radiusDelta + W2*totalAngleError;
192
+
193
+ return { threeProngInfo: { poss, circle, δ3s }, error };
194
+ }
195
+
196
+
197
+ export { find3ProngForDelta3s }
@@ -1,51 +1,54 @@
1
- import type { CpNode } from '../cp-node/cp-node.js';
2
- import type { ThreeProngInfo } from './three-prong-info.js';
3
- import { find3ProngForDelta3s } from './find-3-prong-for-delta3s.js';
4
- import { getBoundaryPieceBeziers } from '../mat/get-boundary-piece-beziers.js';
5
-
6
-
7
- /**
8
- * Find and return a 3-prong from the given boundary piece.
9
- *
10
- * @param δs A boundary piece
11
- * @param maxCoordPowerOf2 The maximum coordinate power of 2 value used to
12
- * calculate floating point tolerances.
13
- *
14
- * @internal
15
- */
16
- function find3Prong(
17
- δs: [CpNode, CpNode][],
18
- maxCoordPowerOf2: number): ThreeProngInfo {
19
-
20
- // FUTURE if `δs.length > (some threshold (say 4 or 5))` then add two-prongs
21
- // to reduced the number of permutations required
22
- // if (δs.length > 3) { console.log(δs.length); }
23
-
24
- const curvePiecess = δs.map(getBoundaryPieceBeziers);
25
-
26
- // The best candidate amongst the different 'permutations' of the given δs.
27
- let threeProng: ThreeProngInfo;
28
-
29
- let smallestError = Infinity;
30
- for (let i=1; i<δs.length - 1; i++) {
31
- for (let k=0; k<3; k++) {
32
- const r = find3ProngForDelta3s(
33
- δs, i, k, curvePiecess, maxCoordPowerOf2
34
- );
35
-
36
- if (r === undefined) { continue; }
37
-
38
- const { error, threeProngInfo } = r;
39
-
40
- if (error < smallestError) {
41
- smallestError = error;
42
- threeProng = threeProngInfo;
43
- }
44
- }
45
- }
46
-
47
- return threeProng!;
48
- }
49
-
50
-
51
- export { find3Prong }
1
+ import type { CpNode } from '../cp-node/cp-node.js';
2
+ import type { ThreeProngInfo } from './three-prong-info.js';
3
+ import { find3ProngForDelta3s } from './find-3-prong-for-delta3s.js';
4
+ import { getBoundaryPieceBeziers } from '../mat/get-boundary-piece-beziers.js';
5
+
6
+
7
+ /**
8
+ * Find and return a 3-prong from the given boundary piece.
9
+ *
10
+ * @param δs A boundary piece
11
+ * @param maxCoordPowerOf2 The maximum coordinate power of 2 value used to
12
+ * calculate floating point tolerances.
13
+ *
14
+ * @internal
15
+ */
16
+
17
+ function find3Prong(
18
+ δs: [CpNode, CpNode][],
19
+ maxCoordPowerOf2: number): ThreeProngInfo {
20
+
21
+ // FUTURE if `δs.length > (some threshold (say 4 or 5))` then add two-prongs
22
+ // to reduced the number of permutations required
23
+ // if (δs.length > 3) { console.log(δs.length); }
24
+
25
+ const curvePiecess = δs.map(getBoundaryPieceBeziers);
26
+ // all the curve pieces of all the boundary pieces (for culling against)
27
+ const allCurvePieces = curvePiecess.flat();
28
+
29
+ // The best candidate amongst the different 'permutations' of the given δs.
30
+ let threeProng: ThreeProngInfo;
31
+
32
+ let smallestError = Infinity;
33
+ for (let i=1; i<δs.length - 1; i++) {
34
+ for (let k=0; k<3; k++) {
35
+ const r = find3ProngForDelta3s(
36
+ δs, i, k, curvePiecess, allCurvePieces, maxCoordPowerOf2
37
+ );
38
+
39
+ if (r === undefined) { continue; }
40
+
41
+ const { error, threeProngInfo } = r;
42
+
43
+ if (error < smallestError) {
44
+ smallestError = error;
45
+ threeProng = threeProngInfo;
46
+ }
47
+ }
48
+ }
49
+
50
+ return threeProng!;
51
+ }
52
+
53
+
54
+ export { find3Prong }
@@ -36,12 +36,31 @@ function findAndAdd3Prongs(
36
36
  }
37
37
 
38
38
  const addedCpNodes: CpNode[][] = [];
39
+ let maxIterations: number | undefined = undefined;
40
+ let iterations = 0;
39
41
  do {
40
42
  if (cpStart === undefined) { continue; }
41
43
  const visitedCps = traverseCp(cpStart);
42
-
44
+
43
45
  if (visitedCps.length <= 2) { break; }
44
46
 
47
+ // Each added 3-prong splits off a part of the traversed face so the
48
+ // number of iterations is bounded by the initial face size. If the
49
+ // face does not shrink (e.g. a geometrically invalid vertex causing the
50
+ // same 3-prong to be re-inserted again and again) fail loudly instead
51
+ // of looping forever.
52
+ if (maxIterations === undefined) {
53
+ maxIterations = 2*visitedCps.length + 16;
54
+ }
55
+ if (++iterations > maxIterations) {
56
+ const pos = cpStart.pointOnShape;
57
+ throw new Error(
58
+ `findAndAdd3Prongs: no convergence after ${iterations} iterations ` +
59
+ `(face with ${visitedCps.length} vertices, start CpNode id ${cpStart.id} ` +
60
+ `on curve ${pos.curve.idx} at t = ${pos.t}, radius ${pos.circle.radius})`
61
+ );
62
+ }
63
+
45
64
  const { closeBysFor3Prong, cpNodes } = findAndAdd3Prong(meta, visitedCps);
46
65
 
47
66
  addedCpNodes.push(cpNodes);
@@ -41,8 +41,8 @@ function createInitialCpTree(
41
41
  const pos1: PointOnShape = { ...ppos, curve, t: 1, circle, order: -1, order2: 0 };
42
42
  const pos2: PointOnShape = { ...ppos, curve: curve.next, t: 0, circle, order: +1, order2: 0 };
43
43
 
44
- cpNode1 = insertCpNode(true, false, false, cpTree, pos1, cpNode2, undefined, /* unused */ lastInsertId)!;
45
- cpNode2 = insertCpNode(true, false, false, cpTree, pos2, cpNode1, undefined, /* unused */ lastInsertId)!;
44
+ cpNode1 = insertCpNode(true, false, false, cpTree, pos1, cpNode2, undefined, lastInsertId)!;
45
+ cpNode2 = insertCpNode(true, false, false, cpTree, pos2, cpNode1, undefined, lastInsertId)!;
46
46
 
47
47
  cpNode1.prevOnCircle = cpNode2;
48
48
  cpNode2.prevOnCircle = cpNode1;
@@ -8,7 +8,7 @@ import type { MatOptions } from './mat-options.js';
8
8
  import type { MatMeta } from '../mat/mat-meta.js';
9
9
  import { findAndAdd3ProngsOnLoop } from '../find-3-prong/find-and-add-3-prongs-on-loop.js';
10
10
  import { createInitialCpTree } from './create-initial-cp-tree.js';
11
- import { getPartialMeta, addDebugInfo1, addDebugInfo2, addDebugInfo3, addDebugInfo4 } from './get-meta.js';
11
+ import { addDebugElems, addDebugInfo1, addDebugInfo2, addDebugInfo3, addDebugInfo4 } from './get-meta.js';
12
12
  import { getSharpCornersOnLoop } from './get-sharp-corners.js';
13
13
  import { getDullCornersOnLoop } from './get-dull-corners-on-loop.js';
14
14
  import { findAndAdd2ProngsOnAllLoops } from '../find-2-prong/find-and-add-2-prongs-on-all-loops.js';
@@ -16,7 +16,6 @@ import { getFor2ProngsOnLoop } from './get-for-2-prongs-on-loop.js';
16
16
  import { getFor1ProngsOnLoop } from './get-for-1-prongs-on-loop.js';
17
17
  import { findAndAddHoleClosing2Prongs } from '../find-2-prong/find-and-add-hole-closing-2-prongs.js';
18
18
  import { getShapeBounds } from '../svg/get-shape-bounds.js';
19
- import { checkOrdering } from '../debug/functions/check-ordering.js';
20
19
 
21
20
 
22
21
  /**
@@ -34,6 +33,7 @@ function findMat(
34
33
  } {
35
34
 
36
35
  addDebugInfo1();
36
+ addDebugElems(loops);
37
37
 
38
38
  const { minBezLength, maxCurviness, maxLength, angleIncrement } = options;
39
39
 
@@ -51,10 +51,9 @@ function findMat(
51
51
  const lastInsertId = { id: 0 };
52
52
  const cpTrees = createInitialCpTree(loops, sharpCornersPerLoop, lastInsertId);
53
53
 
54
- const _meta = getPartialMeta(loops);
55
54
  const meta: MatMeta = {
56
55
  maxCoordPowerOf2, squaredDiagonalLength, loops, cpTrees,// pointToCpNode,
57
- lastInsertId, ..._meta
56
+ lastInsertId
58
57
  };
59
58
 
60
59
  let cpNode: CpNode | undefined;
@@ -89,7 +88,6 @@ function findMat(
89
88
  if (_debug_.directives.stopAfterThreeProngs) { return { cpNode, meta }; }
90
89
  }
91
90
 
92
- // if (cpNode !== undefined) { checkOrdering(meta, cpNode); }
93
91
 
94
92
  const mat = { cpNode, meta };
95
93
 
@@ -105,4 +103,4 @@ export { findMat }
105
103
 
106
104
  /** Curvilinear Shape Features (CSFs) */
107
105
  // const csfs = getCsfs(meta, minBezLength, loops);
108
- // const ligatures = getLigatures(meta, csfs);
106
+ // const ligatures = getLigatures(meta, csfs);