flo-mat 4.1.4 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (379) hide show
  1. package/__tests__/closest-boundary-point/get-endpoint-info.spec.ts +140 -0
  2. package/__tests__/closest-boundary-point/root-interval-to-distance-squared-interval.spec.ts +87 -0
  3. package/__tests__/cp-node/circle-identity.spec.ts +56 -0
  4. package/__tests__/cp-node/fs/get-all-on-loop-by-loop.spec.ts +55 -0
  5. package/__tests__/cp-node/fs/get-angle-between-mat-curves.spec.ts +39 -3
  6. package/__tests__/cp-node/fs/get-boundary-bezier-parts-to-next.spec.ts +87 -3
  7. package/__tests__/cp-node/fs/get-boundary-beziers-between.spec.ts +68 -3
  8. package/__tests__/cp-node/fs/get-boundary-beziers-to-next.spec.ts +41 -3
  9. package/__tests__/cp-node/fs/get-boundary-distance-to-next.spec.ts +20 -3
  10. package/__tests__/cp-node/fs/get-branch-beziers.spec.ts +42 -3
  11. package/__tests__/cp-node/fs/get-branch.spec.ts +60 -3
  12. package/__tests__/cp-node/fs/get-cp-node-ordering.spec.ts +19 -3
  13. package/__tests__/cp-node/fs/get-distance-to-next.spec.ts +37 -4
  14. package/__tests__/cp-node/fs/get-edge-direction.spec.ts +50 -3
  15. package/__tests__/cp-node/fs/get-first-exit.spec.ts +78 -3
  16. package/__tests__/cp-node/fs/get-hole-closers.spec.ts +32 -3
  17. package/__tests__/cp-node/fs/get-implied-boundary-bezier-between.spec.ts +48 -3
  18. package/__tests__/cp-node/fs/get-mat-curve-between.spec.ts +77 -3
  19. package/__tests__/cp-node/fs/get-mat-curve-to-next.spec.ts +17 -4
  20. package/__tests__/cp-node/fs/get-mat-curves-between.spec.ts +38 -3
  21. package/__tests__/cp-node/fs/get-salience.spec.ts +68 -3
  22. package/__tests__/cp-node/fs/get-vertex-forward-children.spec.ts +40 -3
  23. package/__tests__/cp-node/fs/insert-cp-node.spec.ts +87 -3
  24. package/__tests__/cp-node/fs/is-special.spec.ts +1 -1
  25. package/__tests__/cp-node/fs/remove-cp-node.spec.ts +42 -3
  26. package/__tests__/find-2-prong/calc-seperation-tolerance.spec.ts +46 -0
  27. package/__tests__/find-2-prong/get-medial/dd-get-medial-point-coeffs-same-curve.spec.ts +7 -5
  28. package/__tests__/find-2-prong/get-medial/dd-get-medial-point-coeffs.spec.ts +4 -2
  29. package/__tests__/find-2-prong/get-medial/get-closest-points.spec.ts +1 -1
  30. package/__tests__/floyd-warshall/get-graph.spec.ts +100 -0
  31. package/__tests__/get-mats-with-hole.ts +28 -0
  32. package/__tests__/get-mats1.spec.ts +61 -0
  33. package/__tests__/get-mats1.ts +75 -67
  34. package/__tests__/helpers/cp-node-by-id.ts +27 -0
  35. package/__tests__/helpers/expect-point-close.ts +42 -0
  36. package/__tests__/mat/hausdorff-distance-one-sided-exceeds.spec.ts +129 -0
  37. package/__tests__/mat/simplify-mat.spec.ts +85 -0
  38. package/__tests__/reconstruct-from-mat/reconstruct-from-mat.spec.ts +39 -0
  39. package/__tests__/specific-cases/test-svgs/achispado.svg +14 -0
  40. package/__tests__/utils/get-beziers-from-tangents.spec.ts +142 -0
  41. package/browser/index.js +17882 -13800
  42. package/browser/index.min.js +1 -1
  43. package/node/add-n-prong.ts/join-spokes.js +3 -2
  44. package/node/add-n-prong.ts/join-spokes.js.map +1 -1
  45. package/node/closest-boundary-point/cull-curve-pieces.d.ts +21 -0
  46. package/node/closest-boundary-point/cull-curve-pieces.js +40 -0
  47. package/node/closest-boundary-point/cull-curve-pieces.js.map +1 -0
  48. package/node/closest-boundary-point/get-close-boundary-points-certified.js +5 -2
  49. package/node/closest-boundary-point/get-close-boundary-points-certified.js.map +1 -1
  50. package/node/closest-boundary-point/get-endpoint-info.d.ts +39 -0
  51. package/node/closest-boundary-point/get-endpoint-info.js +78 -0
  52. package/node/closest-boundary-point/get-endpoint-info.js.map +1 -0
  53. package/node/closest-boundary-point/get-potential-closest-points-on-curve-certified.js +5 -19
  54. package/node/closest-boundary-point/get-potential-closest-points-on-curve-certified.js.map +1 -1
  55. package/node/closest-boundary-point/root-interval-to-distance-squared-interval.d.ts +17 -5
  56. package/node/closest-boundary-point/root-interval-to-distance-squared-interval.js +37 -50
  57. package/node/closest-boundary-point/root-interval-to-distance-squared-interval.js.map +1 -1
  58. package/node/corner/get-corner.d.ts +18 -1
  59. package/node/corner/get-corner.js +8 -1
  60. package/node/corner/get-corner.js.map +1 -1
  61. package/node/corner/get-interface-ccw.js.map +1 -1
  62. package/node/cp-node/cp-node.d.ts +4 -3
  63. package/node/cp-node/fs/enhance-cp-node.d.ts +9 -9
  64. package/node/cp-node/fs/get-all-on-loop-by-loop.js +0 -4
  65. package/node/cp-node/fs/get-all-on-loop-by-loop.js.map +1 -1
  66. package/node/cp-node/fs/get-angle-between-mat-curves.d.ts +1 -1
  67. package/node/cp-node/fs/get-angle-between-mat-curves.js +7 -4
  68. package/node/cp-node/fs/get-angle-between-mat-curves.js.map +1 -1
  69. package/node/cp-node/fs/get-boundary-beziers-between.d.ts +6 -4
  70. package/node/cp-node/fs/get-boundary-beziers-between.js +6 -4
  71. package/node/cp-node/fs/get-boundary-beziers-between.js.map +1 -1
  72. package/node/cp-node/fs/get-branch-beziers.d.ts +2 -1
  73. package/node/cp-node/fs/get-branch-beziers.js +3 -2
  74. package/node/cp-node/fs/get-branch-beziers.js.map +1 -1
  75. package/node/cp-node/fs/get-branch.js +1 -2
  76. package/node/cp-node/fs/get-branch.js.map +1 -1
  77. package/node/cp-node/fs/get-distance-to-next.js +4 -2
  78. package/node/cp-node/fs/get-distance-to-next.js.map +1 -1
  79. package/node/cp-node/fs/get-edge-direction.js +3 -2
  80. package/node/cp-node/fs/get-edge-direction.js.map +1 -1
  81. package/node/cp-node/fs/get-first-exit.d.ts +7 -3
  82. package/node/cp-node/fs/get-first-exit.js +13 -11
  83. package/node/cp-node/fs/get-first-exit.js.map +1 -1
  84. package/node/cp-node/fs/get-implied-boundary-bezier-between.d.ts +10 -2
  85. package/node/cp-node/fs/get-implied-boundary-bezier-between.js +11 -54
  86. package/node/cp-node/fs/get-implied-boundary-bezier-between.js.map +1 -1
  87. package/node/cp-node/fs/get-mat-curve-between.d.ts +5 -3
  88. package/node/cp-node/fs/get-mat-curve-between.js +6 -49
  89. package/node/cp-node/fs/get-mat-curve-between.js.map +1 -1
  90. package/node/cp-node/fs/get-mat-curve-to-next.d.ts +1 -1
  91. package/node/cp-node/fs/get-mat-curves-between.d.ts +8 -0
  92. package/node/cp-node/fs/get-mat-curves-between.js +9 -2
  93. package/node/cp-node/fs/get-mat-curves-between.js.map +1 -1
  94. package/node/cp-node/fs/get-real-prong-count.d.ts +2 -1
  95. package/node/cp-node/fs/get-real-prong-count.js +11 -5
  96. package/node/cp-node/fs/get-real-prong-count.js.map +1 -1
  97. package/node/cp-node/fs/get-salience.d.ts +10 -0
  98. package/node/cp-node/fs/get-salience.js +17 -1
  99. package/node/cp-node/fs/get-salience.js.map +1 -1
  100. package/node/cp-node/fs/is-fully-terminating.d.ts +4 -2
  101. package/node/cp-node/fs/is-fully-terminating.js +6 -17
  102. package/node/cp-node/fs/is-fully-terminating.js.map +1 -1
  103. package/node/cp-node/fs/is-on-same-circle.d.ts +3 -0
  104. package/node/cp-node/fs/is-on-same-circle.js +4 -4
  105. package/node/cp-node/fs/is-on-same-circle.js.map +1 -1
  106. package/node/cp-node/fs/is-on-same-loop.d.ts +1 -1
  107. package/node/cp-node/fs/is-special.d.ts +7 -0
  108. package/node/cp-node/fs/is-special.js +9 -2
  109. package/node/cp-node/fs/is-special.js.map +1 -1
  110. package/node/cp-node/fs/is-vertex.d.ts +1 -1
  111. package/node/cp-node/fs/traverse-edges.d.ts +7 -3
  112. package/node/cp-node/fs/traverse-edges.js +7 -3
  113. package/node/cp-node/fs/traverse-edges.js.map +1 -1
  114. package/node/cp-node/stringification/from-stringifyable.d.ts +2 -2
  115. package/node/cp-node/stringification/from-stringifyable.js +17 -1
  116. package/node/cp-node/stringification/from-stringifyable.js.map +1 -1
  117. package/node/cp-node/stringification/to-stringifyable.d.ts +3 -3
  118. package/node/cp-node/stringification/to-stringifyable.js +3 -3
  119. package/node/debug/debug.d.ts +26 -3
  120. package/node/debug/debug.js +16 -5
  121. package/node/debug/debug.js.map +1 -1
  122. package/node/find-2-prong/add-2-prong.js +7 -9
  123. package/node/find-2-prong/add-2-prong.js.map +1 -1
  124. package/node/find-2-prong/calc-seperation-tolerance.d.ts +28 -5
  125. package/node/find-2-prong/calc-seperation-tolerance.js +32 -89
  126. package/node/find-2-prong/calc-seperation-tolerance.js.map +1 -1
  127. package/node/find-2-prong/find-2-prong.js +8 -10
  128. package/node/find-2-prong/find-2-prong.js.map +1 -1
  129. package/node/find-2-prong/find-and-add-2-prongs.js +2 -2
  130. package/node/find-2-prong/find-and-add-2-prongs.js.map +1 -1
  131. package/node/find-2-prong/get-medial/get-antipodal-points.d.ts +1 -2
  132. package/node/find-2-prong/get-medial/get-antipodal-points.js +2 -3
  133. package/node/find-2-prong/get-medial/get-antipodal-points.js.map +1 -1
  134. package/node/find-2-prong/get-medial/get-closest-points.d.ts +1 -8
  135. package/node/find-2-prong/get-medial/get-closest-points.js +4 -40
  136. package/node/find-2-prong/get-medial/get-closest-points.js.map +1 -1
  137. package/node/find-2-prong/reduce-radius.d.ts +1 -1
  138. package/node/find-2-prong/reduce-radius.js +6 -3
  139. package/node/find-2-prong/reduce-radius.js.map +1 -1
  140. package/node/find-3-prong/calc-better-x.js +1 -1
  141. package/node/find-3-prong/calc-better-x.js.map +1 -1
  142. package/node/find-3-prong/find-3-prong-for-delta3s.d.ts +3 -2
  143. package/node/find-3-prong/find-3-prong-for-delta3s.js +36 -42
  144. package/node/find-3-prong/find-3-prong-for-delta3s.js.map +1 -1
  145. package/node/find-3-prong/find-3-prong.js +3 -1
  146. package/node/find-3-prong/find-3-prong.js.map +1 -1
  147. package/node/find-3-prong/find-and-add-3-prongs.js +16 -0
  148. package/node/find-3-prong/find-and-add-3-prongs.js.map +1 -1
  149. package/node/find-mat/create-initial-cp-tree.js +2 -2
  150. package/node/find-mat/create-initial-cp-tree.js.map +1 -1
  151. package/node/find-mat/find-mat.js +3 -4
  152. package/node/find-mat/find-mat.js.map +1 -1
  153. package/node/find-mat/find-mats.d.ts +6 -12
  154. package/node/find-mat/find-mats.js +10 -27
  155. package/node/find-mat/find-mats.js.map +1 -1
  156. package/node/find-mat/get-dull-corners-on-loop.js +2 -2
  157. package/node/find-mat/get-dull-corners-on-loop.js.map +1 -1
  158. package/node/find-mat/get-for-1-prongs-on-loop.js +36 -8
  159. package/node/find-mat/get-for-1-prongs-on-loop.js.map +1 -1
  160. package/node/find-mat/get-meta.d.ts +14 -4
  161. package/node/find-mat/get-meta.js +30 -24
  162. package/node/find-mat/get-meta.js.map +1 -1
  163. package/node/find-mat/get-sharp-corners.js +2 -2
  164. package/node/find-mat/get-sharp-corners.js.map +1 -1
  165. package/node/find-mat/mat-options.d.ts +2 -2
  166. package/node/floyd-warshall/get-graph.d.ts +12 -1
  167. package/node/floyd-warshall/get-graph.js +41 -38
  168. package/node/floyd-warshall/get-graph.js.map +1 -1
  169. package/node/geometry/get-bounding-box-.d.ts +16 -2
  170. package/node/geometry/get-bounding-box-.js +5 -2
  171. package/node/geometry/get-bounding-box-.js.map +1 -1
  172. package/node/geometry/get-closest-square-distance-to-rect.d.ts +3 -0
  173. package/node/geometry/get-closest-square-distance-to-rect.js +7 -5
  174. package/node/geometry/get-closest-square-distance-to-rect.js.map +1 -1
  175. package/node/geometry/get-closest-squared-distance-to-rotated-rect.d.ts +4 -0
  176. package/node/geometry/get-closest-squared-distance-to-rotated-rect.js +12 -5
  177. package/node/geometry/get-closest-squared-distance-to-rotated-rect.js.map +1 -1
  178. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.js +1 -2
  179. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.js.map +1 -1
  180. package/node/index.d.ts +3 -2
  181. package/node/index.js +2 -1
  182. package/node/index.js.map +1 -1
  183. package/node/mat/clone-mat.d.ts +9 -0
  184. package/node/mat/clone-mat.js +17 -0
  185. package/node/mat/clone-mat.js.map +1 -0
  186. package/node/mat/clone-meta.d.ts +12 -0
  187. package/node/mat/clone-meta.js +24 -0
  188. package/node/mat/clone-meta.js.map +1 -0
  189. package/node/mat/get-boundary-piece-beziers.d.ts +5 -0
  190. package/node/mat/get-boundary-piece-beziers.js +7 -93
  191. package/node/mat/get-boundary-piece-beziers.js.map +1 -1
  192. package/node/mat/get-closeby-cp-if-exist.js +2 -1
  193. package/node/mat/get-closeby-cp-if-exist.js.map +1 -1
  194. package/node/mat/get-largest-3-prong.d.ts +6 -0
  195. package/node/mat/get-largest-3-prong.js +8 -5
  196. package/node/mat/get-largest-3-prong.js.map +1 -1
  197. package/node/mat/get-largest-vertex.d.ts +15 -1
  198. package/node/mat/get-largest-vertex.js +20 -7
  199. package/node/mat/get-largest-vertex.js.map +1 -1
  200. package/node/mat/hausdorff-distance-one-sided-exceeds.d.ts +79 -0
  201. package/node/mat/hausdorff-distance-one-sided-exceeds.js +251 -0
  202. package/node/mat/hausdorff-distance-one-sided-exceeds.js.map +1 -0
  203. package/node/mat/mat-meta.d.ts +0 -6
  204. package/node/mat/simplify-mat.d.ts +25 -8
  205. package/node/mat/simplify-mat.js +182 -53
  206. package/node/mat/simplify-mat.js.map +1 -1
  207. package/node/mat/trim-mat.d.ts +4 -2
  208. package/node/mat/trim-mat.js +3 -1
  209. package/node/mat/trim-mat.js.map +1 -1
  210. package/node/point-on-shape/get-boundary-tangent-line.d.ts +19 -0
  211. package/node/point-on-shape/get-boundary-tangent-line.js +33 -0
  212. package/node/point-on-shape/get-boundary-tangent-line.js.map +1 -0
  213. package/node/point-on-shape/get-osculating-circle.d.ts +6 -4
  214. package/node/point-on-shape/get-osculating-circle.js +6 -4
  215. package/node/point-on-shape/get-osculating-circle.js.map +1 -1
  216. package/node/point-on-shape/get-pos-corner.js +2 -2
  217. package/node/point-on-shape/get-pos-corner.js.map +1 -1
  218. package/node/point-on-shape/point-on-shape.d.ts +5 -0
  219. package/node/reconstruct-from-mat/reconstruct-from-mat.js +20 -80
  220. package/node/reconstruct-from-mat/reconstruct-from-mat.js.map +1 -1
  221. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.d.ts +4 -0
  222. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js +4 -0
  223. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js.map +1 -1
  224. package/node/sat/cull.d.ts +7 -6
  225. package/node/sat/cull.js +13 -16
  226. package/node/sat/cull.js.map +1 -1
  227. package/node/sat/get-sat-culls.d.ts +12 -2
  228. package/node/sat/get-sat-culls.js +21 -16
  229. package/node/sat/get-sat-culls.js.map +1 -1
  230. package/node/svg/get-shape-bounds.d.ts +1 -12
  231. package/node/svg/get-shape-bounds.js +2 -3
  232. package/node/svg/get-shape-bounds.js.map +1 -1
  233. package/node/sweep-line/sweep-line.js.map +1 -1
  234. package/node/utils/get-beziers-from-tangents.d.ts +28 -0
  235. package/node/utils/get-beziers-from-tangents.js +92 -0
  236. package/node/utils/get-beziers-from-tangents.js.map +1 -0
  237. package/node/vertex/remove-vertex.d.ts +5 -3
  238. package/node/vertex/remove-vertex.js +5 -3
  239. package/node/vertex/remove-vertex.js.map +1 -1
  240. package/package.json +16 -16
  241. package/qv-infinite-loop.md +120 -0
  242. package/src/add-n-prong.ts/join-spokes.ts +4 -2
  243. package/src/closest-boundary-point/cull-curve-pieces.ts +49 -0
  244. package/src/closest-boundary-point/get-close-boundary-points-certified.ts +5 -2
  245. package/src/closest-boundary-point/get-endpoint-info.ts +96 -0
  246. package/src/closest-boundary-point/get-potential-closest-points-on-curve-certified.ts +5 -23
  247. package/src/closest-boundary-point/root-interval-to-distance-squared-interval.ts +42 -60
  248. package/src/corner/get-corner.ts +10 -1
  249. package/src/corner/get-interface-ccw.ts +2 -2
  250. package/src/cp-node/cp-node.ts +4 -3
  251. package/src/cp-node/fs/get-all-on-loop-by-loop.ts +0 -4
  252. package/src/cp-node/fs/get-angle-between-mat-curves.ts +9 -5
  253. package/src/cp-node/fs/get-boundary-beziers-between.ts +10 -8
  254. package/src/cp-node/fs/get-branch-beziers.ts +3 -2
  255. package/src/cp-node/fs/get-branch.ts +1 -2
  256. package/src/cp-node/fs/get-distance-to-next.ts +4 -2
  257. package/src/cp-node/fs/get-edge-direction.ts +4 -2
  258. package/src/cp-node/fs/get-first-exit.ts +15 -14
  259. package/src/cp-node/fs/get-implied-boundary-bezier-between.ts +18 -70
  260. package/src/cp-node/fs/get-mat-curve-between.ts +10 -67
  261. package/src/cp-node/fs/get-mat-curves-between.ts +9 -2
  262. package/src/cp-node/fs/get-real-prong-count.ts +11 -7
  263. package/src/cp-node/fs/get-salience.ts +15 -2
  264. package/src/cp-node/fs/is-fully-terminating.ts +6 -22
  265. package/src/cp-node/fs/is-on-same-circle.ts +6 -7
  266. package/src/cp-node/fs/is-on-same-loop.ts +2 -2
  267. package/src/cp-node/fs/is-special.ts +11 -6
  268. package/src/cp-node/fs/is-vertex.ts +1 -1
  269. package/src/cp-node/fs/traverse-edges.ts +8 -4
  270. package/src/cp-node/stringification/from-stringifyable.ts +75 -58
  271. package/src/cp-node/stringification/to-stringifyable.ts +3 -3
  272. package/src/debug/debug.ts +44 -8
  273. package/src/find-2-prong/add-2-prong.ts +9 -11
  274. package/src/find-2-prong/calc-seperation-tolerance.ts +34 -115
  275. package/src/find-2-prong/find-2-prong.ts +9 -11
  276. package/src/find-2-prong/find-and-add-2-prongs.ts +2 -2
  277. package/src/find-2-prong/get-medial/get-antipodal-points.ts +1 -3
  278. package/src/find-2-prong/get-medial/get-closest-points.ts +6 -51
  279. package/src/find-2-prong/reduce-radius.ts +6 -4
  280. package/src/find-3-prong/calc-better-x.ts +2 -2
  281. package/src/find-3-prong/find-3-prong-for-delta3s.ts +197 -214
  282. package/src/find-3-prong/find-3-prong.ts +54 -51
  283. package/src/find-3-prong/find-and-add-3-prongs.ts +20 -1
  284. package/src/find-mat/create-initial-cp-tree.ts +2 -2
  285. package/src/find-mat/find-mat.ts +4 -6
  286. package/src/find-mat/find-mats.ts +83 -105
  287. package/src/find-mat/get-dull-corners-on-loop.ts +2 -2
  288. package/src/find-mat/get-for-1-prongs-on-loop.ts +40 -8
  289. package/src/find-mat/get-meta.ts +34 -39
  290. package/src/find-mat/get-sharp-corners.ts +2 -2
  291. package/src/find-mat/mat-options.ts +2 -2
  292. package/src/floyd-warshall/get-graph.ts +46 -47
  293. package/src/geometry/get-bounding-box-.ts +5 -2
  294. package/src/geometry/get-closest-square-distance-to-rect.ts +7 -7
  295. package/src/geometry/get-closest-squared-distance-to-rotated-rect.ts +15 -13
  296. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.ts +1 -2
  297. package/src/index.ts +3 -2
  298. package/src/mat/clone-mat.ts +9 -3
  299. package/src/mat/clone-meta.ts +8 -0
  300. package/src/mat/get-boundary-piece-beziers.ts +16 -117
  301. package/src/mat/get-closeby-cp-if-exist.ts +3 -1
  302. package/src/mat/get-largest-3-prong.ts +9 -6
  303. package/src/mat/get-largest-vertex.ts +25 -9
  304. package/src/mat/hausdorff-distance-one-sided-exceeds.ts +314 -0
  305. package/src/mat/mat-meta.ts +0 -9
  306. package/src/mat/simplify-mat.ts +254 -116
  307. package/src/mat/trim-mat.ts +6 -4
  308. package/src/point-on-shape/get-boundary-tangent-line.ts +36 -0
  309. package/src/point-on-shape/get-osculating-circle.ts +7 -5
  310. package/src/point-on-shape/get-pos-corner.ts +2 -2
  311. package/src/point-on-shape/point-on-shape.ts +5 -0
  312. package/src/reconstruct-from-mat/reconstruct-from-mat.ts +22 -111
  313. package/src/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.ts +4 -0
  314. package/src/sat/cull.ts +16 -20
  315. package/src/sat/get-sat-culls.ts +28 -23
  316. package/src/svg/get-shape-bounds.ts +2 -3
  317. package/src/sweep-line/sweep-line.ts +1 -1
  318. package/src/utils/deg-to-rad.ts +4 -2
  319. package/src/utils/get-beziers-from-tangents.ts +110 -0
  320. package/src/utils/map-map.ts +1 -1
  321. package/src/utils/rad-to-deg.ts +4 -1
  322. package/src/vertex/remove-vertex.ts +5 -3
  323. package/webpack.config.cjs +7 -2
  324. package/__tests__/cp-node/fs/get-distance-between.spec.ts +0 -7
  325. package/__tests__/cp-node/fs/get-terminating-on-circle.spec.ts +0 -24
  326. package/__tests__/cp-node/fs/is-single-3-prong.spec.ts +0 -17
  327. package/__tests__/cp-node/fs/iterate-all-on-loop.spec.ts +0 -17
  328. package/__tests__/cp-node/fs/traverse-all-forward.spec.ts +0 -14
  329. package/node/closest-boundary-point/cull-bezier-pieces-1.d.ts +0 -9
  330. package/node/closest-boundary-point/cull-bezier-pieces-1.js +0 -17
  331. package/node/closest-boundary-point/cull-bezier-pieces-1.js.map +0 -1
  332. package/node/closest-boundary-point/cull-by-loose-bounding-box.d.ts +0 -13
  333. package/node/closest-boundary-point/cull-by-loose-bounding-box.js +0 -27
  334. package/node/closest-boundary-point/cull-by-loose-bounding-box.js.map +0 -1
  335. package/node/closest-boundary-point/cull-by-tight-boundary-box.d.ts +0 -11
  336. package/node/closest-boundary-point/cull-by-tight-boundary-box.js +0 -27
  337. package/node/closest-boundary-point/cull-by-tight-boundary-box.js.map +0 -1
  338. package/node/cp-node/fs/find-first.d.ts +0 -10
  339. package/node/cp-node/fs/find-first.js +0 -19
  340. package/node/cp-node/fs/find-first.js.map +0 -1
  341. package/node/debug/functions/check-ordering.d.ts +0 -4
  342. package/node/debug/functions/check-ordering.js +0 -43
  343. package/node/debug/functions/check-ordering.js.map +0 -1
  344. package/node/find-2-prong/cull-bezier-pieces.d.ts +0 -13
  345. package/node/find-2-prong/cull-bezier-pieces.js +0 -43
  346. package/node/find-2-prong/cull-bezier-pieces.js.map +0 -1
  347. package/node/floyd-warshall/get-hole-closer-pairs.d.ts +0 -8
  348. package/node/floyd-warshall/get-hole-closer-pairs.js +0 -27
  349. package/node/floyd-warshall/get-hole-closer-pairs.js.map +0 -1
  350. package/node/utils/dual-set.d.ts +0 -27
  351. package/node/utils/dual-set.js +0 -55
  352. package/node/utils/dual-set.js.map +0 -1
  353. package/node/utils/tri-map.d.ts +0 -27
  354. package/node/utils/tri-map.js +0 -49
  355. package/node/utils/tri-map.js.map +0 -1
  356. package/src/closest-boundary-point/cull-bezier-pieces-1.ts +0 -36
  357. package/src/closest-boundary-point/cull-by-loose-bounding-box.ts +0 -42
  358. package/src/closest-boundary-point/cull-by-tight-boundary-box.ts +0 -43
  359. package/src/closest-boundary-point/get-p-from-box.ts +0 -14
  360. package/src/cp-node/fs/add-distance-from.ts +0 -49
  361. package/src/cp-node/fs/get-distance-between.ts +0 -16
  362. package/src/cp-node/fs/get-terminating-on-circle.ts +0 -24
  363. package/src/cp-node/fs/is-single-3-prong.ts +0 -15
  364. package/src/cp-node/fs/iterate-all-on-loop.ts +0 -15
  365. package/src/cp-node/fs/traverse-all-forward.ts +0 -24
  366. package/src/debug/functions/draw/draw-beziers-as-single-path.ts +0 -40
  367. package/src/debug/functions/draw/draw-disk.ts +0 -34
  368. package/src/debug/functions/draw/xmlns.ts +0 -5
  369. package/src/find-2-prong/cull-bezier-pieces.ts +0 -61
  370. package/src/find-2-prong/find-and-add-2-prong.ts +0 -30
  371. package/src/find-2-prong/get-medial/get-closest-points-d.ts +0 -213
  372. package/src/find-2-prong/x-for-debugging.ts +0 -13
  373. package/src/floyd-warshall/get-hole-closer-pairs.ts +0 -35
  374. package/src/mat/get-two-prong-type.ts +0 -13
  375. package/src/point-on-shape/is-pos-dull-corner.ts +0 -18
  376. package/src/point-on-shape/is-pos-quite-dull-corner.ts +0 -18
  377. package/src/point-on-shape/is-pos-quite-sharp-corner.ts +0 -18
  378. package/src/point-on-shape/pos-to-human-string.ts +0 -18
  379. package/src/sweep-line/are-boxes-intersecting.ts +0 -37
@@ -1,32 +1,16 @@
1
1
  import type { CpNode } from "../cp-node.js";
2
- import { getAllOnCircle } from "./get-all-on-circle.js";
2
+ import { getRealProngCount } from "./get-real-prong-count.js";
3
3
  import { isTerminating } from "./is-terminating.js";
4
- import { isTrivial } from "./is-trivial.js";
5
4
 
6
5
 
7
6
  /**
8
- * Like isTerminating() but only returns true if all cpNodes on the circle
9
- * (except this.prevOnCircle) is terminating.
7
+ * Like `isTerminating` but only returns `true` if all `CpNode`s on the circle
8
+ * (except possibly the one leading back, i.e. `this.prevOnCircle`) are
9
+ * terminating - i.e. the `CpNode` is terminating and its vertex has at most
10
+ * one real prong.
10
11
  */
11
12
  function isFullyTerminating(cpNode: CpNode) {
12
- // const otherOnCircle = getAllOnCircle(cpNode.prevOnCircle, true);
13
-
14
- // return otherOnCircle.every(isTerminating);
15
- if (!isTerminating(cpNode)) {
16
- return false;
17
- }
18
-
19
- if (isTrivial(cpNode)) {
20
- return true;
21
- }
22
-
23
- while (cpNode.prev === cpNode.prevOnCircle) {
24
- cpNode = cpNode.prev;
25
- }
26
-
27
- const otherOnCircle = getAllOnCircle(cpNode.prevOnCircle, true);
28
-
29
- return otherOnCircle.every(isTerminating);
13
+ return isTerminating(cpNode) && getRealProngCount(cpNode) <= 1;
30
14
  }
31
15
 
32
16
 
@@ -1,11 +1,13 @@
1
1
  import { CpNode } from "../cp-node.js";
2
- import { getAllOnCircle } from "./get-all-on-circle.js";
3
2
 
4
3
 
5
4
  /**
6
- * Returns true if the 2 given `CpNode`s are on the same maximal disk
5
+ * Returns true if the 2 given `CpNode`s are on the same maximal disk
7
6
  * circle.
8
- *
7
+ *
8
+ * * O(1): all `CpNode`s on the same on-circle ring share the same `Circle`
9
+ * object, and no other ring does (see `PointOnShape.circle`)
10
+ *
9
11
  * @param cpNode1 A `CpNode`.
10
12
  * @param cpNode2 Another `CpNode`
11
13
  */
@@ -13,10 +15,7 @@ function isOnSameCircle(
13
15
  cpNode1: CpNode,
14
16
  cpNode2: CpNode) {
15
17
 
16
- // const cpNodes = getAllOnCircle(cpNode1, true);
17
- const cpNodes = getAllOnCircle(cpNode1);
18
-
19
- return cpNodes.indexOf(cpNode2) >= 0;
18
+ return cpNode1.pointOnShape.circle === cpNode2.pointOnShape.circle;
20
19
  }
21
20
 
22
21
 
@@ -1,4 +1,4 @@
1
- import type { CpNode } from "flo-mat";
1
+ import { CpNode } from "../cp-node.js";
2
2
 
3
3
 
4
4
  function isOnSameLoop(
@@ -12,4 +12,4 @@ function isOnSameLoop(
12
12
  }
13
13
 
14
14
 
15
- export { isOnSameLoop }
15
+ export { isOnSameLoop }
@@ -2,13 +2,18 @@ import type { CpNode } from "../cp-node.js";
2
2
  import { getRealProngCount } from "./get-real-prong-count.js";
3
3
 
4
4
 
5
- function isSpecial(
6
- cpNode: CpNode) {
7
-
5
+ /**
6
+ * Returns `true` if the given `CpNode` is on a 'special' MAT vertex, i.e. one
7
+ * that is not a plain 2-prong: a leaf, a 3-prong (or higher) or a hole-closer.
8
+ *
9
+ * * these are the vertices that must be kept when simplifying the MAT and
10
+ * the vertices of the MAT seen as a graph
11
+ */
12
+ function isSpecial(cpNode: CpNode) {
8
13
  return (
9
- (getRealProngCount(cpNode) !== 2) &&
10
- !cpNode.isHoleClosing
11
- )
14
+ getRealProngCount(cpNode) !== 2 ||
15
+ cpNode.isHoleClosing
16
+ );
12
17
  }
13
18
 
14
19
 
@@ -1,4 +1,4 @@
1
- import { CpNode } from "../cp-node.js";
1
+ import type { CpNode } from "../cp-node.js";
2
2
  import { getAllOnCircle } from "./get-all-on-circle.js";
3
3
 
4
4
 
@@ -4,10 +4,14 @@ import { getAllOnLoop } from './get-all-on-loop.js';
4
4
 
5
5
 
6
6
  /**
7
- * Traverses all edges (depth first) of the given MAT tree starting at the given
8
- * vertex (represented by a `CpNode`).
9
- * @param cpNode Any `CpNode` representing the start vertex.
10
- * @param traverseEdgesCallback A callback function for each CpNode representing the vertex at the
7
+ * Traverses all edges of the given MAT tree exactly once each, calling the
8
+ * callback for one of the two `CpNode`s representing each edge.
9
+ *
10
+ * * the edges are visited in boundary order starting from the given `CpNode`
11
+ * (not depth first)
12
+ *
13
+ * @param cpNode Any `CpNode` on the MAT.
14
+ * @param traverseEdgesCallback A callback function for each CpNode representing the vertex at the
11
15
  * start of an edge.
12
16
  */
13
17
  function traverseEdges(
@@ -1,58 +1,75 @@
1
- import type { PointOnShape } from "../../point-on-shape/point-on-shape.js";
2
- import type { CpNode } from "../cp-node";
3
- import type { CpNodeStringifyable } from "./cp-node-stringifyable";
4
- import { EDGES } from "./cp-node-stringifyable";
5
- import { loopFromStringifyable } from './loop-from-stringifyable.js';
6
-
7
-
8
- function fromStringifyable(
9
- cpNodesStringifyable: CpNodeStringifyable) {
10
-
11
- const { cpNodes: _cpNodes, loops: _loops } = cpNodesStringifyable;
12
- const loops = _loops.map(loopFromStringifyable);
13
- const loopsByIdx = new Map(loops.map(loop => [loop.idx, loop]));
14
-
15
- //--------------------------------------------------------------------------
16
- // First pass: build all CpNode objects with proper `cp`.
17
- // Edges still hold number ids at this point.
18
- //--------------------------------------------------------------------------
19
- const cpNodes: CpNode[] = _cpNodes.map(cpNode_ => {
20
- const { id, pointOnShape, isHoleClosing, isIntersection } = cpNode_;
21
- const { circle, order, order2 } = pointOnShape;
22
- const { curveIdx, loopIdx, p, pDd, t, isSource } = pointOnShape;
23
-
24
- const curve = loopsByIdx.get(loopIdx)!.curves[curveIdx];
25
-
26
- const pointOnShape_: PointOnShape = {
27
- circle,
28
- curve, p, pDd, t, isSource,
29
- order, order2
30
- };
31
-
32
- return {
33
- ...cpNode_,
34
- id, isHoleClosing, isIntersection,
35
- pointOnShape: pointOnShape_
36
- } as CpNode;
37
- });
38
-
39
- //--------------------------------------------------------------------------
40
- // Second pass: replace number id edges with real CpNode references.
41
- //--------------------------------------------------------------------------
42
- const nodeMap = new Map<number, CpNode>(cpNodes.map(n => [n.id, n]));
43
-
44
- for (const cpNode of cpNodes) {
45
- for (const edge of EDGES) {
46
- const id = cpNode[edge] as unknown as number | undefined;
47
- if (id === undefined) { continue; }
48
-
49
- // @ts-ignore
50
- cpNode[edge] = nodeMap.get(id)!;
51
- }
52
- }
53
-
54
- return cpNodes[0];
55
- }
56
-
57
-
58
- export { fromStringifyable }
1
+ import type { PointOnShape } from "../../point-on-shape/point-on-shape.js";
2
+ import type { CpNode } from "../cp-node.js";
3
+ import type { CpNodeStringifyable } from "./cp-node-stringifyable.js";
4
+ import type { Mutable } from "../../utils/mutable.js";
5
+ import { EDGES } from "./cp-node-stringifyable.js";
6
+ import { getAllOnCircle } from "../fs/get-all-on-circle.js";
7
+ import { loopFromStringifyable } from './loop-from-stringifyable.js';
8
+
9
+
10
+ function fromStringifyable(
11
+ cpNodesStringifyable: CpNodeStringifyable) {
12
+
13
+ const { cpNodes: _cpNodes, loops: _loops } = cpNodesStringifyable;
14
+ const loops = _loops.map(loopFromStringifyable);
15
+ const loopsByIdx = new Map(loops.map(loop => [loop.idx, loop]));
16
+
17
+ //--------------------------------------------------------------------------
18
+ // First pass: build all CpNode objects with proper `cp`.
19
+ // Edges still hold number ids at this point.
20
+ //--------------------------------------------------------------------------
21
+ const cpNodes: CpNode[] = _cpNodes.map(cpNode_ => {
22
+ const { id, pointOnShape, isHoleClosing, isIntersection } = cpNode_;
23
+ const { circle, order, order2 } = pointOnShape;
24
+ const { curveIdx, loopIdx, p, pDd, t, isSource } = pointOnShape;
25
+
26
+ const curve = loopsByIdx.get(loopIdx)!.curves[curveIdx];
27
+
28
+ const pointOnShape_: PointOnShape = {
29
+ circle,
30
+ curve, p, pDd, t, isSource,
31
+ order, order2
32
+ };
33
+
34
+ return {
35
+ ...cpNode_,
36
+ id, isHoleClosing, isIntersection,
37
+ pointOnShape: pointOnShape_
38
+ } as CpNode;
39
+ });
40
+
41
+ //--------------------------------------------------------------------------
42
+ // Second pass: replace number id edges with real CpNode references.
43
+ //--------------------------------------------------------------------------
44
+ const nodeMap = new Map<number, CpNode>(cpNodes.map(n => [n.id, n]));
45
+
46
+ for (const cpNode of cpNodes) {
47
+ for (const edge of EDGES) {
48
+ const id = cpNode[edge] as unknown as number | undefined;
49
+ if (id === undefined) { continue; }
50
+
51
+ // @ts-ignore
52
+ cpNode[edge] = nodeMap.get(id)!;
53
+ }
54
+ }
55
+
56
+ //--------------------------------------------------------------------------
57
+ // Third pass: one shared `Circle` object per on-circle ring, as when the
58
+ // MAT was built (the JSON gave every contact point its own copy).
59
+ //--------------------------------------------------------------------------
60
+ const done = new Set<CpNode>();
61
+ for (const cpNode of cpNodes) {
62
+ if (done.has(cpNode)) { continue; }
63
+
64
+ const { circle } = cpNode.pointOnShape;
65
+ for (const cp of getAllOnCircle(cpNode)) {
66
+ done.add(cp);
67
+ (cp.pointOnShape as Mutable<PointOnShape>).circle = circle;
68
+ }
69
+ }
70
+
71
+ return cpNodes[0];
72
+ }
73
+
74
+
75
+ export { fromStringifyable }
@@ -5,9 +5,9 @@ import { loopToStringifyable } from "./loop-to-stringifyable.js";
5
5
 
6
6
 
7
7
  /**
8
- * Returns a deep clone of this `CpNode`. Can be used to copy the MAT
9
- * since cloning a single `CpNode` necessarily implies cloning all
10
- * `CpNode`s on the same MAT tree.
8
+ * Returns a plain, acyclic representation of the entire MAT the given `CpNode`
9
+ * is part of (the `CpNode` edges replaced by ids and the boundary loops
10
+ * included) suitable for `JSON.stringify`; `fromStringifyable` reverses it.
11
11
  */
12
12
  function toStringifyable(
13
13
  cpNode: CpNode): CpNodeStringifyable {
@@ -1,8 +1,10 @@
1
+ import type { Curve } from 'flo-boolean';
2
+
1
3
 
2
4
  /** @internal */
3
5
  interface Debug {
4
6
  /** Generated by debug object for later inspection */
5
- elems: {};
7
+ elems: Elems;
6
8
  timing: Timing;
7
9
 
8
10
  /**
@@ -14,6 +16,28 @@ interface Debug {
14
16
  }
15
17
 
16
18
 
19
+ /**
20
+ * Elements generated during `findMats` for later inspection (only available
21
+ * if debug has been enabled via `enableDebugForMat(true)`).
22
+ *
23
+ * The arrays are reset at the start of each `findMats` call and accumulate
24
+ * over all MATs found in that call, one entry per boundary bezier curve in the
25
+ * order the curves are encountered.
26
+ */
27
+ interface Elems {
28
+ /** The loose (axis-aligned) bounding box of each boundary bezier curve */
29
+ readonly looseBoundingBoxes: number[][][];
30
+ /** The tight (rotated) bounding box of each boundary bezier curve */
31
+ readonly tightBoundingBoxes: number[][][];
32
+ /** The bounding hull of each boundary bezier curve */
33
+ readonly boundingHulls: number[][][];
34
+ /** The curves whose end point forms a quite sharp corner with the next curve */
35
+ readonly sharpCorners: Curve[];
36
+ /** The curves whose end point forms a quite dull corner with the next curve */
37
+ readonly dullCorners: Curve[];
38
+ }
39
+
40
+
17
41
  /** @internal */
18
42
  interface Timing {
19
43
  holeClosers: number;
@@ -35,18 +59,31 @@ interface Directives {
35
59
  }
36
60
 
37
61
 
62
+ /** Returns a fresh (empty) set of debug `Elems`. */
63
+ function createEmptyElems(): Elems {
64
+ return {
65
+ looseBoundingBoxes: [],
66
+ tightBoundingBoxes: [],
67
+ boundingHulls: [],
68
+ sharpCorners: [],
69
+ dullCorners: []
70
+ };
71
+ }
72
+
73
+
38
74
  function enableDebugForMat(debugOn: boolean) {
39
75
  if (!debugOn) {
40
- (window as any)._debug_ = undefined;
76
+ (globalThis as any)._debug_ = undefined;
41
77
  return;
42
78
  }
43
79
 
44
- let debug: Debug = (window as any)._debug_;
80
+ let debug: Debug = (globalThis as any)._debug_;
45
81
 
46
82
  debug = {
47
83
  ...debug,
48
84
  elems: {
49
- ...debug?.elems
85
+ ...debug?.elems,
86
+ ...createEmptyElems()
50
87
  },
51
88
  timing: {
52
89
  ...debug?.timing,
@@ -71,10 +108,9 @@ function enableDebugForMat(debugOn: boolean) {
71
108
  }
72
109
  };
73
110
 
74
- (window as any)._debug_ = debug;
111
+ (globalThis as any)._debug_ = debug;
75
112
  }
76
113
 
77
114
 
78
- export type { Debug, Timing, Directives }
79
- export { enableDebugForMat }
80
-
115
+ export type { Debug, Elems, Timing, Directives }
116
+ export { enableDebugForMat, createEmptyElems }
@@ -1,6 +1,6 @@
1
1
  import type { CpNode } from '../cp-node/cp-node.js';
2
2
  import type { Circle } from '../geometry/circle.js';
3
- import type { PointOnShape, PrePointOnShape } from '../point-on-shape/point-on-shape.js';
3
+ import type { PrePointOnShape } from '../point-on-shape/point-on-shape.js';
4
4
  import type { MatMeta } from '../mat/mat-meta.js';
5
5
  import type { Mutable } from '../utils/mutable.js';
6
6
  import { calcPosOrder } from '../point-on-shape/calc-pos-order.js';
@@ -35,13 +35,6 @@ function add2Prong(
35
35
  const orderSource = calcPosOrder(circle.center, pposSource);
36
36
  const orderAntipode = calcPosOrder(circle.center, pposAntipode);
37
37
 
38
- const posAntipode: PointOnShape = {
39
- ...pposAntipode, circle, order: orderAntipode, order2: 0
40
- };
41
- const posSource: PointOnShape = {
42
- ...pposSource, circle, order: orderSource, order2: 0
43
- }
44
-
45
38
  // Make sure there isn't already a ContactPoint close by - it can cause
46
39
  // floating point stability issues.
47
40
  if (!!getCloseByCpIfExist(meta, pposSource, circle, orderSource, 0, 2)) {
@@ -55,7 +48,7 @@ function add2Prong(
55
48
  isHoleClosing, isHoleClosing, circle,
56
49
  [orderSource, orderAntipode],
57
50
  meta,
58
- [posSource, posAntipode]
51
+ [pposSource, pposAntipode]
59
52
  );
60
53
 
61
54
  if (anyFailed) {
@@ -83,12 +76,17 @@ function closeHole(
83
76
 
84
77
  const [cpNodeSource, cpNodeAntipode] = cpNodes as Mutable<CpNode>[];
85
78
 
79
+ // The twins form their own on-circle ring (a separate MAT vertex - that
80
+ // is what cuts the hole), so they get their own (equal) `Circle` object:
81
+ // one `Circle` object per ring.
82
+ const twinCircle: Circle = { ...cpNodeSource.pointOnShape.circle };
83
+
86
84
  // Antipode - create and insert twin
87
85
  const posAntipode = cpNodeAntipode.pointOnShape;
88
86
  const cpNodeAntipodeTwin = insertCpNode(
89
87
  true, true, false,
90
88
  cpTrees.get(posAntipode.curve.loop)!,
91
- { ...posAntipode, order2: +1 },
89
+ { ...posAntipode, circle: twinCircle, order2: +1 },
92
90
  cpNodeAntipode,
93
91
  undefined, // unused
94
92
  meta.lastInsertId
@@ -101,7 +99,7 @@ function closeHole(
101
99
  const cpNodeSourceTwin = insertCpNode(
102
100
  true, true, false,
103
101
  cpTrees.get(posSource.curve.loop)!,
104
- { ...posSource!, order2: -1 },
102
+ { ...posSource!, circle: twinCircle, order2: -1 },
105
103
  cpNodeSource.prev,
106
104
  undefined, // unused
107
105
  meta.lastInsertId
@@ -1,127 +1,46 @@
1
- import { ddAddDd, twoProduct, ddDiffDd, ddDivDd, twoDiff, ddMultDouble1 } from 'double-double';
2
-
3
- const tp = twoProduct;
4
- const qaq = ddAddDd;
5
- const qdq = ddDiffDd;
6
- const qmd = ddMultDouble1;
7
-
8
- const { acos } = Math;
9
-
10
-
11
1
  /**
12
- * Calculates and returns an appropriate seperation tolerance between `CpNode`s.
13
- *
14
- * @param R radius of the circle implied by the curvature at the boundary
2
+ * Returns the *squared* separation tolerance between the two contact points
3
+ * `y` (the source point) and `z` (the antipode) of a candidate 2-prong: if
4
+ * `|yz|²` is below it the antipode is indistinguishable (to within the error
5
+ * tolerance `δ`) from the circle merely grazing the boundary at `y` - the
6
+ * near-1-prong case - and the 2-prong should be rejected.
7
+ *
8
+ * Derivation: the MAT circle (radius `r`) is tangent to the boundary at `y`
9
+ * and so is the osculating circle there (radius `R`), both centers lying on
10
+ * the inward normal at `y`. Approximating the boundary near `y` by the
11
+ * osculating circle, the MAT circle enlarged by `δ` crosses it at the angle
12
+ * `θ` (at the MAT center, measured from `y`) given by the law of cosines:
13
+ *
14
+ * cos θ = (r(R-r) - rδ - δ²/2) / ((R-r)(r+δ))
15
+ *
16
+ * Points of the MAT circle within that angle of `y` are within `δ` of the
17
+ * boundary. The chord `|yz|` subtending `θ` is `2r·sin(θ/2)`, and since
18
+ * `2sin²(θ/2) = 1 - cos θ = (Rδ + δ²/2) / ((R-r)(r+δ))` the squared chord is
19
+ *
20
+ * |yz|² = r²(2Rδ + δ²) / ((R-r)(r+δ))
21
+ *
22
+ * which is what is returned - in closed form, without the cancellation that
23
+ * recovering a tiny `θ` from `cos θ` suffers from.
24
+ *
25
+ * @param R radius of the osculating circle of the boundary at `y`
15
26
  * @param r radius of the MAT circle
16
- * @param θ angle between point...
27
+ * @param δ the error tolerance on distances
28
+ *
29
+ * @internal
17
30
  */
18
- function calcSeperationTolerance(
31
+ function calcSquaredSeperationTolerance(
19
32
  R: number,
20
33
  r: number,
21
- δ: number) {
34
+ δ: number): number {
22
35
 
23
- const a = r + δ;
24
- if (a >= R) {
36
+ if (r + δ >= R) {
37
+ // The enlarged MAT circle is at least as large as the osculating
38
+ // circle: every point on it is within tolerance of the boundary.
25
39
  return Infinity;
26
40
  }
27
41
 
28
- const R_r_ = twoDiff(R,r);
29
- const A_ = qmd(r,R_r_);
30
- const N_ = qdq(qdq(A_, tp(r,δ)), tp(δ,δ/2));
31
- const D_ = qaq(A_,qmd(δ,R_r_));
32
-
33
- const R_r = R - r;
34
- const A = r*R_r;
35
- const N = A - r*δ - (δ*δ)/2;
36
- const D = A + R_r*δ;
37
- const cosC = N/D;
38
- const Q = ddDivDd(N_,D_)[1];
39
- // const Q = N_[1]/D_[1];
40
- const C = acos(cosC);
41
- const CC = acos(Q)
42
-
43
- const θ = CC;
44
-
45
- // return r*θ;
46
- return r*θ;
42
+ return r*r*(2*R*δ + δ*δ) / ((R - r)*(r + δ));
47
43
  }
48
44
 
49
45
 
50
- export { calcSeperationTolerance }
51
-
52
-
53
- // Quokka tests
54
-
55
- // /**
56
- // * Calculates and returns an appropriate seperation tolerance between `CpNode`s.
57
- // *
58
- // * @param R radius of the circle implied by the curvature at the boundary
59
- // * @param r radius of the MAT circle
60
- // * @param θ angle between point...
61
- // */
62
- // function calcSeperationTolerance2(
63
- // R: number,
64
- // r: number,
65
- // δ: number) {
66
-
67
- // const a = r + δ;
68
- // if (a >= R) {
69
- // return Infinity;
70
- // }
71
-
72
- // const b = R - r;
73
- // const c = R;
74
-
75
- // const N = c*c - a*a - b*b;
76
- // const N_ = qdq(qdq(tp(c,c), tp(a,a)), tp(b,b));
77
- // const D = 2*a*b;
78
- // const D_ = tp(-2*a,b);
79
- // const Q = ddDivDd(N_,D_)[1];
80
- // const cosC = -N/D;
81
- // const C = acos(cosC);
82
- // const CC = acos(Q);
83
-
84
- // const θ = π - CC;
85
-
86
- // return θ;
87
- // // return r*θ; // approximate arc with line
88
- // }
89
-
90
-
91
- // function degToRad(degrees: number) {
92
- // return degrees/360*2*Math.PI;
93
- // }
94
- // function radToDeg(rad: number) {
95
- // return rad*360/2/Math.PI;
96
- // }
97
-
98
-
99
- // const R = 699;
100
- // const r = 698;
101
- // const δ = 1000*2**-46;
102
- // calcSeperationTolerance(R,r,δ);
103
- // calcSeperationTolerance2(R,r,δ);
104
- // calcSeperationTolerance3(R,r,δ);
105
-
106
- // // * see https://en.wikipedia.org/wiki/Law_of_cosines, Version suited to small angles
107
- // function calcSeperationTolerance3(
108
- // R: number,
109
- // r: number,
110
- // δ: number) {
111
-
112
- // const a = r + δ;
113
- // const c = R - r;
114
- // const b = R;
115
-
116
- // // c² = (a - b)² + 4ab*sin²(θ/2) OR
117
- // // (c² - (a - b)²)/4ab = sin²(θ/2)
118
- // const cc = c*c;
119
- // const abc = a*a + b*b - 2*a*b;
120
- // const A = cc - abc;
121
- // const B = sqrt(A/(4*a*b));
122
-
123
- // const θ = 2*asin(B);
124
-
125
- // return θ;
126
- // // return r*θ; // approximate arc with line
127
- // }
46
+ export { calcSquaredSeperationTolerance }
@@ -6,10 +6,10 @@ import { getInitialCurvePieces } from './get-initial-bezier-pieces.js';
6
6
  import { getAntipodalPoints } from './get-medial/get-antipodal-points.js';
7
7
  import { reduceRadius } from './reduce-radius.js';
8
8
  import { squaredDistanceBetweenDd } from './squared-distance-between-dd.js';
9
- import { cullCurvePieces } from './cull-bezier-pieces.js';
9
+ import { cullCurvePieces } from '../closest-boundary-point/cull-curve-pieces.js';
10
10
  import { add1Prong } from './add-1-prong.js';
11
11
  import { toP } from '../point-on-shape/to-p.js';
12
- import { calcSeperationTolerance } from './calc-seperation-tolerance.js';
12
+ import { calcSquaredSeperationTolerance } from './calc-seperation-tolerance.js';
13
13
  import { getInitialX } from './get-initial-x.js';
14
14
  import { ddNormal } from 'flo-bezier3';
15
15
  import { rotate } from 'flo-vector2d';
@@ -85,26 +85,24 @@ function find2Prong(
85
85
  );
86
86
 
87
87
  // The lines below is an optimization.
88
- const xy2 = reduceRadius(maxCoordPowerOf2, rO, curvePieces, y, nnorm);
88
+ const xy2 = reduceRadius(rO, curvePieces, y, nnorm);
89
89
  const xy = sqrt(xy2);
90
90
 
91
91
  const l = sqrt(nnorm[0]**2 + nnorm[1]**2);
92
92
  xO = [y[0] + nnorm[0]/l*xy, y[1] + nnorm[1]/l*xy];
93
93
 
94
- cullCurvePieces(curvePieces, xO, xy2);
94
+ // (the extra multiplier accounts for floating point error)
95
+ const culledCurvePieces = cullCurvePieces(curvePieces, xO, (1 + 2**-20)*xy2);
95
96
 
96
97
  const antipodalPoints = getAntipodalPoints(
97
- maxCoordPowerOf2, nnorm, nnormDd, yPos,
98
+ maxCoordPowerOf2, nnormDd, yPos,
98
99
  for1Prong, angle,
99
- curvePieces
100
+ culledCurvePieces
100
101
  );
101
102
 
102
103
  // FUTURE - if antipodalPoints.length > 1 let's just add an n-prong;
103
104
  if (antipodalPoints.length !== 1) {
104
105
  if (antipodalPoints.length === 0) {
105
- if (isHoleClosing) {
106
- console.log(yPos)
107
- }
108
106
  return undefined;
109
107
  }
110
108
  if (!isHoleClosing && !areAllAntipodesSame(antipodalPoints, maxCoordPowerOf2)) {
@@ -144,7 +142,7 @@ function find2Prong(
144
142
  // The lines below eliminate cases where the found 2-prong is too
145
143
  // close to a one-prong
146
144
  const squaredSeperationTolerance = max(
147
- calcSeperationTolerance(rO, sqrt(xz), (2**2)*errorTolerance),
145
+ calcSquaredSeperationTolerance(rO, sqrt(xz), (2**2)*errorTolerance),
148
146
  minSquaredSeperationTolerance
149
147
  );
150
148
  if (yz <= squaredSeperationTolerance) {
@@ -171,7 +169,7 @@ function areAllAntipodesSame(
171
169
  // }
172
170
 
173
171
  const { x: x_ } = point[i];
174
- if (abs(x[0] - x_[0]) > tol || abs(x[0] - x_[0]) > tol) {
172
+ if (abs(x[0] - x_[0]) > tol || abs(x[1] - x_[1]) > tol) {
175
173
  return false;
176
174
  }
177
175
  }