flo-mat 4.0.2 → 4.1.0

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 (294) hide show
  1. package/__tests__/find-2-prong/get-medial/dd-get-medial-point-coeffs-same-curve.spec.ts +106 -0
  2. package/__tests__/find-2-prong/get-medial/dd-get-medial-point-coeffs.spec.ts +73 -0
  3. package/__tests__/find-2-prong/get-medial/get-closest-points.spec.ts +5 -2
  4. package/__tests__/helpers/close-to.ts +5 -5
  5. package/__tests__/specific-cases/load-svg/load-svg.ts +30 -0
  6. package/__tests__/specific-cases/specific-cases.spec.ts +170 -0
  7. package/__tests__/specific-cases/test-svgs/achispado.svg +5052 -0
  8. package/browser/index.js +5129 -8785
  9. package/browser/index.min.js +1 -1
  10. package/{jest.config.cjs → jest.config.ts} +8 -3
  11. package/node/closest-boundary-point/get-close-boundary-points-certified.js +3 -2
  12. package/node/closest-boundary-point/get-close-boundary-points-certified.js.map +1 -1
  13. package/node/corner/get-corner.js +1 -1
  14. package/node/corner/get-corner.js.map +1 -1
  15. package/node/cp-node/fs/get-all-on-loop-by-loop.d.ts +11 -0
  16. package/node/cp-node/fs/get-all-on-loop-by-loop.js +42 -0
  17. package/node/cp-node/fs/get-all-on-loop-by-loop.js.map +1 -0
  18. package/node/cp-node/fs/get-boundary-beziers-to-next.d.ts +1 -0
  19. package/node/cp-node/fs/get-boundary-beziers-to-next.js +1 -59
  20. package/node/cp-node/fs/get-boundary-beziers-to-next.js.map +1 -1
  21. package/node/cp-node/fs/get-edge-direction.d.ts +3 -1
  22. package/node/cp-node/fs/get-edge-direction.js +5 -3
  23. package/node/cp-node/fs/get-edge-direction.js.map +1 -1
  24. package/node/cp-node/fs/get-mat-curve-between.js +6 -6
  25. package/node/cp-node/fs/get-mat-curve-between.js.map +1 -1
  26. package/node/cp-node/fs/is-fully-terminating.js +12 -0
  27. package/node/cp-node/fs/is-fully-terminating.js.map +1 -1
  28. package/node/cp-node/fs/is-on-same-loop.d.ts +3 -0
  29. package/node/cp-node/fs/is-on-same-loop.js +6 -0
  30. package/node/cp-node/fs/is-on-same-loop.js.map +1 -0
  31. package/node/debug/debug.d.ts +8 -22
  32. package/node/debug/debug.js +12 -50
  33. package/node/debug/debug.js.map +1 -1
  34. package/node/find-2-prong/add-1-prong.js +1 -4
  35. package/node/find-2-prong/add-1-prong.js.map +1 -1
  36. package/node/find-2-prong/find-2-prong.js +24 -10
  37. package/node/find-2-prong/find-2-prong.js.map +1 -1
  38. package/node/find-2-prong/get-medial/get-antipodal-points.d.ts +1 -1
  39. package/node/find-2-prong/get-medial/get-antipodal-points.js +2 -2
  40. package/node/find-2-prong/get-medial/get-antipodal-points.js.map +1 -1
  41. package/node/find-2-prong/get-medial/get-closest-points.d.ts +7 -1
  42. package/node/find-2-prong/get-medial/get-closest-points.js +60 -14
  43. package/node/find-2-prong/get-medial/get-closest-points.js.map +1 -1
  44. package/node/find-2-prong/reduce-radius.d.ts +3 -1
  45. package/node/find-2-prong/reduce-radius.js +8 -6
  46. package/node/find-2-prong/reduce-radius.js.map +1 -1
  47. package/node/find-3-prong/calc-better-x.js +1 -3
  48. package/node/find-3-prong/calc-better-x.js.map +1 -1
  49. package/node/find-3-prong/calc-initial-3-prong-center.js +1 -2
  50. package/node/find-3-prong/calc-initial-3-prong-center.js.map +1 -1
  51. package/node/find-3-prong/find-3-prong-for-delta3s.js +1 -4
  52. package/node/find-3-prong/find-3-prong-for-delta3s.js.map +1 -1
  53. package/node/find-3-prong/find-3-prong.js.map +1 -1
  54. package/node/find-3-prong/find-and-add-3-prong.js +0 -14
  55. package/node/find-3-prong/find-and-add-3-prong.js.map +1 -1
  56. package/node/find-mat/find-mat.js +2 -2
  57. package/node/find-mat/find-mat.js.map +1 -1
  58. package/node/find-mat/find-mats.js.map +1 -1
  59. package/node/find-mat/get-dull-corners-on-loop.js +3 -2
  60. package/node/find-mat/get-dull-corners-on-loop.js.map +1 -1
  61. package/node/find-mat/get-for-1-prongs-on-loop.js +6 -3
  62. package/node/find-mat/get-for-1-prongs-on-loop.js.map +1 -1
  63. package/node/find-mat/get-for-2-prongs-on-loop.js +5 -1
  64. package/node/find-mat/get-for-2-prongs-on-loop.js.map +1 -1
  65. package/node/find-mat/get-meta.d.ts +4 -6
  66. package/node/find-mat/get-meta.js +12 -26
  67. package/node/find-mat/get-meta.js.map +1 -1
  68. package/node/find-mat/get-sharp-corners.js +4 -2
  69. package/node/find-mat/get-sharp-corners.js.map +1 -1
  70. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez0.d.ts +21 -0
  71. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez0.js +46 -0
  72. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez0.js.map +1 -0
  73. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez1.d.ts +28 -0
  74. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez1.js +97 -0
  75. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez1.js.map +1 -0
  76. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez2-same-curve.d.ts +28 -0
  77. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez2-same-curve.js +109 -0
  78. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez2-same-curve.js.map +1 -0
  79. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez2.d.ts +29 -0
  80. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez2.js +123 -0
  81. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez2.js.map +1 -0
  82. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3-same-curve.d.ts +30 -0
  83. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3-same-curve.js +177 -0
  84. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3-same-curve.js.map +1 -0
  85. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.d.ts +29 -0
  86. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.js +156 -0
  87. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.js.map +1 -0
  88. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs.d.ts +28 -0
  89. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs.js +40 -0
  90. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs.js.map +1 -0
  91. package/node/index.d.ts +6 -10
  92. package/node/index.js +5 -6
  93. package/node/index.js.map +1 -1
  94. package/node/point-on-shape/point-on-shape.d.ts +2 -0
  95. package/node/point-on-shape/to-p.d.ts +1 -1
  96. package/node/point-on-shape/to-p.js +1 -1
  97. package/node/point-on-shape/to-p.js.map +1 -1
  98. package/node/reconstruct-from-mat/get-cp-nodess-for-sat.d.ts +4 -0
  99. package/node/reconstruct-from-mat/get-cp-nodess-for-sat.js +15 -0
  100. package/node/reconstruct-from-mat/get-cp-nodess-for-sat.js.map +1 -0
  101. package/node/reconstruct-from-mat/reconstruct-from-mat.d.ts +10 -0
  102. package/node/reconstruct-from-mat/reconstruct-from-mat.js +160 -0
  103. package/node/reconstruct-from-mat/reconstruct-from-mat.js.map +1 -0
  104. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.d.ts +12 -0
  105. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js +46 -0
  106. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js.map +1 -0
  107. package/node/sat/add-debug-info.js +1 -2
  108. package/node/sat/add-debug-info.js.map +1 -1
  109. package/node/svg/get-loop-bounds.js +6 -2
  110. package/node/svg/get-loop-bounds.js.map +1 -1
  111. package/node/utils/map-deep.d.ts +15 -0
  112. package/node/utils/map-deep.js +34 -0
  113. package/node/utils/map-deep.js.map +1 -0
  114. package/package.json +14 -8
  115. package/src/closest-boundary-point/get-close-boundary-points-certified.ts +3 -2
  116. package/src/corner/get-corner.ts +1 -1
  117. package/src/cp-node/fs/get-all-on-loop-by-loop.ts +56 -0
  118. package/src/cp-node/fs/get-all-on-loop.ts +1 -1
  119. package/src/cp-node/fs/get-boundary-beziers-to-next.ts +1 -72
  120. package/src/cp-node/fs/get-edge-direction.ts +8 -4
  121. package/src/cp-node/fs/get-mat-curve-between.ts +6 -6
  122. package/src/cp-node/fs/is-fully-terminating.ts +16 -0
  123. package/src/cp-node/fs/is-on-same-loop.ts +15 -0
  124. package/src/debug/debug.ts +27 -87
  125. package/src/find-2-prong/add-1-prong.ts +1 -5
  126. package/src/find-2-prong/find-2-prong.ts +37 -14
  127. package/src/find-2-prong/get-medial/get-antipodal-points.ts +3 -2
  128. package/src/find-2-prong/get-medial/get-closest-points-d.ts +213 -0
  129. package/src/find-2-prong/get-medial/get-closest-points.ts +74 -13
  130. package/src/find-2-prong/reduce-radius.ts +8 -5
  131. package/src/find-3-prong/calc-better-x.ts +1 -3
  132. package/src/find-3-prong/calc-initial-3-prong-center.ts +1 -2
  133. package/src/find-3-prong/find-3-prong-for-delta3s.ts +1 -4
  134. package/src/find-3-prong/find-3-prong.ts +0 -1
  135. package/src/find-3-prong/find-and-add-3-prong.ts +1 -15
  136. package/src/find-mat/find-mat.ts +3 -2
  137. package/src/find-mat/find-mats.ts +0 -1
  138. package/src/find-mat/get-dull-corners-on-loop.ts +4 -3
  139. package/src/find-mat/get-for-1-prongs-on-loop.ts +8 -3
  140. package/src/find-mat/get-for-2-prongs-on-loop.ts +6 -1
  141. package/src/find-mat/get-meta.ts +14 -38
  142. package/src/find-mat/get-sharp-corners.ts +5 -1
  143. package/src/get-medial-curve/__pycache__/get-cubic-self-medial-curve.cpython-313.pyc +0 -0
  144. package/src/get-medial-curve/get-cubic-self-medial-curve.py +419 -0
  145. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez0-with-running-err.ts +76 -0
  146. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez0.ts +61 -0
  147. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez1.ts +116 -0
  148. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez2-same-curve.ts +129 -0
  149. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez2.ts +142 -0
  150. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3-same-curve.ts +199 -0
  151. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.ts +177 -0
  152. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs.ts +48 -0
  153. package/src/get-medial-points/double-double/error-bound-calc.txt +72 -0
  154. package/src/index.ts +7 -11
  155. package/src/point-on-shape/point-on-shape.ts +3 -0
  156. package/src/point-on-shape/to-p.ts +2 -2
  157. package/src/reconstruct-from-mat/get-cp-nodess-for-sat.ts +24 -0
  158. package/src/reconstruct-from-mat/reconstruct-from-mat.ts +226 -0
  159. package/src/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.ts +62 -0
  160. package/src/sat/add-debug-info.ts +1 -2
  161. package/src/svg/get-loop-bounds.ts +11 -3
  162. package/src/utils/clip.ts +13 -0
  163. package/src/utils/map-deep.ts +75 -0
  164. package/src/utils/map-map.ts +33 -0
  165. package/wallaby.mjs +4 -4
  166. package/node/debug/debug-elem-types.d.ts +0 -26
  167. package/node/debug/debug-elem-types.js +0 -22
  168. package/node/debug/debug-elem-types.js.map +0 -1
  169. package/node/debug/functions/draw/draw-beziers-as-single-path.d.ts +0 -2
  170. package/node/debug/functions/draw/draw-beziers-as-single-path.js +0 -30
  171. package/node/debug/functions/draw/draw-beziers-as-single-path.js.map +0 -1
  172. package/node/debug/functions/draw/xmlns.d.ts +0 -2
  173. package/node/debug/functions/draw/xmlns.js +0 -3
  174. package/node/debug/functions/draw/xmlns.js.map +0 -1
  175. package/node/debug/functions/draw-elem/bounding-hull.d.ts +0 -3
  176. package/node/debug/functions/draw-elem/bounding-hull.js +0 -8
  177. package/node/debug/functions/draw-elem/bounding-hull.js.map +0 -1
  178. package/node/debug/functions/draw-elem/draw-branch.d.ts +0 -4
  179. package/node/debug/functions/draw-elem/draw-branch.js +0 -26
  180. package/node/debug/functions/draw-elem/draw-branch.js.map +0 -1
  181. package/node/debug/functions/draw-elem/draw-circle-percent.d.ts +0 -3
  182. package/node/debug/functions/draw-elem/draw-circle-percent.js +0 -13
  183. package/node/debug/functions/draw-elem/draw-circle-percent.js.map +0 -1
  184. package/node/debug/functions/draw-elem/draw-cp-node.d.ts +0 -4
  185. package/node/debug/functions/draw-elem/draw-cp-node.js +0 -26
  186. package/node/debug/functions/draw-elem/draw-cp-node.js.map +0 -1
  187. package/node/debug/functions/draw-elem/draw-cull.d.ts +0 -3
  188. package/node/debug/functions/draw-elem/draw-cull.js +0 -9
  189. package/node/debug/functions/draw-elem/draw-cull.js.map +0 -1
  190. package/node/debug/functions/draw-elem/draw-dull-corner.d.ts +0 -4
  191. package/node/debug/functions/draw-elem/draw-dull-corner.js +0 -10
  192. package/node/debug/functions/draw-elem/draw-dull-corner.js.map +0 -1
  193. package/node/debug/functions/draw-elem/draw-elem.d.ts +0 -10
  194. package/node/debug/functions/draw-elem/draw-elem.js +0 -39
  195. package/node/debug/functions/draw-elem/draw-elem.js.map +0 -1
  196. package/node/debug/functions/draw-elem/draw-leaves.d.ts +0 -4
  197. package/node/debug/functions/draw-elem/draw-leaves.js +0 -34
  198. package/node/debug/functions/draw-elem/draw-leaves.js.map +0 -1
  199. package/node/debug/functions/draw-elem/draw-loop.d.ts +0 -4
  200. package/node/debug/functions/draw-elem/draw-loop.js +0 -11
  201. package/node/debug/functions/draw-elem/draw-loop.js.map +0 -1
  202. package/node/debug/functions/draw-elem/draw-loops.d.ts +0 -4
  203. package/node/debug/functions/draw-elem/draw-loops.js +0 -6
  204. package/node/debug/functions/draw-elem/draw-loops.js.map +0 -1
  205. package/node/debug/functions/draw-elem/draw-loose-bounding-box.d.ts +0 -3
  206. package/node/debug/functions/draw-elem/draw-loose-bounding-box.js +0 -10
  207. package/node/debug/functions/draw-elem/draw-loose-bounding-box.js.map +0 -1
  208. package/node/debug/functions/draw-elem/draw-mat.d.ts +0 -4
  209. package/node/debug/functions/draw-elem/draw-mat.js +0 -34
  210. package/node/debug/functions/draw-elem/draw-mat.js.map +0 -1
  211. package/node/debug/functions/draw-elem/draw-max-vertex.d.ts +0 -4
  212. package/node/debug/functions/draw-elem/draw-max-vertex.js +0 -9
  213. package/node/debug/functions/draw-elem/draw-max-vertex.js.map +0 -1
  214. package/node/debug/functions/draw-elem/draw-min-y.d.ts +0 -4
  215. package/node/debug/functions/draw-elem/draw-min-y.js +0 -10
  216. package/node/debug/functions/draw-elem/draw-min-y.js.map +0 -1
  217. package/node/debug/functions/draw-elem/draw-one-prong-at-dull-corner.d.ts +0 -4
  218. package/node/debug/functions/draw-elem/draw-one-prong-at-dull-corner.js +0 -22
  219. package/node/debug/functions/draw-elem/draw-one-prong-at-dull-corner.js.map +0 -1
  220. package/node/debug/functions/draw-elem/draw-one-prong.d.ts +0 -4
  221. package/node/debug/functions/draw-elem/draw-one-prong.js +0 -13
  222. package/node/debug/functions/draw-elem/draw-one-prong.js.map +0 -1
  223. package/node/debug/functions/draw-elem/draw-sharp-corner.d.ts +0 -4
  224. package/node/debug/functions/draw-elem/draw-sharp-corner.js +0 -10
  225. package/node/debug/functions/draw-elem/draw-sharp-corner.js.map +0 -1
  226. package/node/debug/functions/draw-elem/draw-three-prong.d.ts +0 -4
  227. package/node/debug/functions/draw-elem/draw-three-prong.js +0 -26
  228. package/node/debug/functions/draw-elem/draw-three-prong.js.map +0 -1
  229. package/node/debug/functions/draw-elem/draw-tight-bounding-box.d.ts +0 -3
  230. package/node/debug/functions/draw-elem/draw-tight-bounding-box.js +0 -8
  231. package/node/debug/functions/draw-elem/draw-tight-bounding-box.js.map +0 -1
  232. package/node/debug/functions/draw-elem/draw-two-prong.d.ts +0 -4
  233. package/node/debug/functions/draw-elem/draw-two-prong.js +0 -49
  234. package/node/debug/functions/draw-elem/draw-two-prong.js.map +0 -1
  235. package/node/debug/functions/draw-elem/draw-vertex.d.ts +0 -4
  236. package/node/debug/functions/draw-elem/draw-vertex.js +0 -13
  237. package/node/debug/functions/draw-elem/draw-vertex.js.map +0 -1
  238. package/node/debug/functions/general.d.ts +0 -48
  239. package/node/debug/functions/general.js +0 -53
  240. package/node/debug/functions/general.js.map +0 -1
  241. package/node/find-3-prong/timed-cc.d.ts +0 -3
  242. package/node/find-3-prong/timed-cc.js +0 -5
  243. package/node/find-3-prong/timed-cc.js.map +0 -1
  244. package/node/point-on-shape/pos-to-human-string.d.ts +0 -8
  245. package/node/point-on-shape/pos-to-human-string.js +0 -12
  246. package/node/point-on-shape/pos-to-human-string.js.map +0 -1
  247. package/node/utils/time-function-call.d.ts +0 -14
  248. package/node/utils/time-function-call.js +0 -32
  249. package/node/utils/time-function-call.js.map +0 -1
  250. package/src/debug/debug-elem-types.ts +0 -43
  251. package/src/debug/elem-type-two-prong.ts +0 -8
  252. package/src/debug/functions/cmp-cp-on-delta.ts +0 -54
  253. package/src/debug/functions/draw-elem/bounding-hull.ts +0 -18
  254. package/src/debug/functions/draw-elem/culls.ts +0 -39
  255. package/src/debug/functions/draw-elem/draw-branch.ts +0 -37
  256. package/src/debug/functions/draw-elem/draw-circle-percent.ts +0 -23
  257. package/src/debug/functions/draw-elem/draw-cp-node.ts +0 -46
  258. package/src/debug/functions/draw-elem/draw-cull.ts +0 -21
  259. package/src/debug/functions/draw-elem/draw-dull-corner.ts +0 -21
  260. package/src/debug/functions/draw-elem/draw-elem.ts +0 -64
  261. package/src/debug/functions/draw-elem/draw-leaves.ts +0 -51
  262. package/src/debug/functions/draw-elem/draw-loop.ts +0 -16
  263. package/src/debug/functions/draw-elem/draw-loops.ts +0 -10
  264. package/src/debug/functions/draw-elem/draw-loose-bounding-box.ts +0 -21
  265. package/src/debug/functions/draw-elem/draw-mat.ts +0 -43
  266. package/src/debug/functions/draw-elem/draw-max-vertex.ts +0 -15
  267. package/src/debug/functions/draw-elem/draw-min-y.ts +0 -18
  268. package/src/debug/functions/draw-elem/draw-one-prong-at-dull-corner.ts +0 -40
  269. package/src/debug/functions/draw-elem/draw-one-prong.ts +0 -25
  270. package/src/debug/functions/draw-elem/draw-sharp-corner.ts +0 -21
  271. package/src/debug/functions/draw-elem/draw-three-prong.ts +0 -44
  272. package/src/debug/functions/draw-elem/draw-tight-bounding-box.ts +0 -18
  273. package/src/debug/functions/draw-elem/draw-two-prong.ts +0 -68
  274. package/src/debug/functions/draw-elem/draw-vertex.ts +0 -27
  275. package/src/debug/functions/draw-elem/dull-corner.ts +0 -21
  276. package/src/debug/functions/draw-elem/leaves.ts +0 -20
  277. package/src/debug/functions/draw-elem/loop.ts +0 -16
  278. package/src/debug/functions/draw-elem/loops.ts +0 -10
  279. package/src/debug/functions/draw-elem/loose-bounding-box.ts +0 -21
  280. package/src/debug/functions/draw-elem/mat.ts +0 -47
  281. package/src/debug/functions/draw-elem/max-vertex.ts +0 -15
  282. package/src/debug/functions/draw-elem/min-y.ts +0 -18
  283. package/src/debug/functions/draw-elem/one-prong-at-dull-corner.ts +0 -26
  284. package/src/debug/functions/draw-elem/one-prong.ts +0 -23
  285. package/src/debug/functions/draw-elem/sharp-corner.ts +0 -20
  286. package/src/debug/functions/draw-elem/three-prong.ts +0 -30
  287. package/src/debug/functions/draw-elem/tight-bounding-box.ts +0 -18
  288. package/src/debug/functions/draw-elem/two-prong.ts +0 -50
  289. package/src/debug/functions/draw-elem/vertex.ts +0 -51
  290. package/src/debug/functions/general.ts +0 -79
  291. package/src/debug/functions/three-prong.ts +0 -249
  292. package/src/debug/functions/two-prong.ts +0 -203
  293. package/src/find-2-prong/add-debug-info.ts +0 -45
  294. package/src/find-3-prong/timed-cc.ts +0 -9
@@ -1,6 +1,6 @@
1
1
  import type { CpNode } from '../cp-node.js';
2
2
  import {
3
- fromTo, dot, cross, rotate90Degrees, interpolate, translate,
3
+ fromTo as fromToVec, dot, cross, rotate90Degrees, interpolate, translate,
4
4
  lineLineIntersection
5
5
  } from 'flo-vector2d';
6
6
  import { getEdgeDirection } from './get-edge-direction.js';
@@ -32,14 +32,14 @@ function getMatCurveBetween(
32
32
 
33
33
  const mid = lineLineIntersection(fromL, toL);
34
34
 
35
- const c = fromTo(fromCc,toCc);
35
+ const c = fromToVec(fromCc,toCc);
36
36
 
37
37
  let twisted: boolean;
38
38
  if (!mid) {
39
39
  twisted = true;
40
40
  } else {
41
- const a = fromTo(fromCc, mid);
42
- const b = fromTo(toCc, mid);
41
+ const a = fromToVec(fromCc, mid);
42
+ const b = fromToVec(toCc, mid);
43
43
 
44
44
  twisted = dot(a,c) < 0 || dot(b,c) > 0;
45
45
  }
@@ -49,8 +49,8 @@ function getMatCurveBetween(
49
49
  }
50
50
 
51
51
  const r = rotate90Degrees(c);
52
- const w1 = fromTo(fromL[0], fromL[1]); // This is a unit vector
53
- const w2 = fromTo(toL[0], toL[1]); // This is a unit vector
52
+ const w1 = fromToVec(fromL[0], fromL[1]); // This is a unit vector
53
+ const w2 = fromToVec(toL[0], toL[1]); // This is a unit vector
54
54
 
55
55
  const d1 = abs(cross(c, w1)) / (3*3);
56
56
  const d2 = abs(cross(c, w2)) / (3*3);
@@ -1,6 +1,7 @@
1
1
  import type { CpNode } from "../cp-node.js";
2
2
  import { getAllOnCircle } from "./get-all-on-circle.js";
3
3
  import { isTerminating } from "./is-terminating.js";
4
+ import { isTrivial } from "./is-trivial.js";
4
5
 
5
6
 
6
7
  /**
@@ -8,6 +9,21 @@ import { isTerminating } from "./is-terminating.js";
8
9
  * (except this.prevOnCircle) is terminating.
9
10
  */
10
11
  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
+
11
27
  const otherOnCircle = getAllOnCircle(cpNode.prevOnCircle, true);
12
28
 
13
29
  return otherOnCircle.every(isTerminating);
@@ -0,0 +1,15 @@
1
+ import type { CpNode } from "flo-mat";
2
+
3
+
4
+ function isOnSameLoop(
5
+ cpNode1: CpNode,
6
+ cpNode2: CpNode): boolean {
7
+
8
+ return (
9
+ cpNode1.pointOnShape.curve.loop ===
10
+ cpNode2.pointOnShape.curve.loop
11
+ );
12
+ }
13
+
14
+
15
+ export { isOnSameLoop }
@@ -1,54 +1,31 @@
1
- import { generalDebugFunctions } from './functions/general.js';
2
- import { IGeneralDebugFunctions } from './functions/general.js';
3
- import { DrawElemFunctions } from './functions/draw-elem/draw-elem.js';
4
- import { DebugElems } from './debug-elem-types.js';
5
- import { drawElemFs } from './functions/draw-elem/draw-elem.js';
6
-
7
1
 
8
2
  /** @internal */
9
3
  interface Debug {
10
4
  /** Generated by debug object for later inspection */
11
- generated: Generated;
5
+ elems: {};
6
+ timing: Timing;
7
+
12
8
  /**
13
9
  * These functions are meant to be used in the console, e.g. in the
14
10
  * console try typing d.fs.twoProng.traceConvergence(0);
15
11
  */
16
- fs: IDebugFunctions;
17
- directives: IDirectives;
18
- }
19
-
20
-
21
- /** @internal */
22
- type GeneratedElems = { [T in keyof DebugElems]: DebugElems[T][] };
23
-
24
-
25
- /** @internal */
26
- interface ITiming {
27
- //normalize : number;
28
- //simplifyPaths : number;
29
- holeClosers : number;
30
- oneAnd2Prongs : number;
31
- threeProngs : number;
32
- sats : number;
33
- simplifyMat : number;
34
- }
35
-
36
-
37
- /** @internal */
38
- interface Generated {
39
- elems: GeneratedElems;
40
- timing: ITiming;
12
+ fs: {};
13
+ directives: Directives;
41
14
  }
42
15
 
43
16
 
44
17
  /** @internal */
45
- interface IDebugFunctions extends IGeneralDebugFunctions {
46
- drawElem : DrawElemFunctions,
18
+ interface Timing {
19
+ holeClosers: number;
20
+ oneAnd2Prongs: number;
21
+ threeProngs: number;
22
+ sats: number;
23
+ simplifyMat: number;
47
24
  }
48
25
 
49
26
 
50
27
  /** @internal */
51
- interface IDirectives {
28
+ interface Directives {
52
29
  stopAfterHoleClosers: boolean,
53
30
  stopAfterHoleClosersNum: number,
54
31
  stopAfterTwoProngs: boolean,
@@ -68,59 +45,23 @@ function enableDebugForMat(debugOn: boolean) {
68
45
 
69
46
  debug = {
70
47
  ...debug,
71
- generated: {
72
- //...debug?.generated,
73
- ...(!debug ? {} : !debug.generated ? {} : debug.generated),
74
- // @ts-ignore
75
- elems: {
76
- //...debug?.generated?.elems,
77
- ...(!debug ? {} : !debug.generated ? {} : !debug.generated.elems ? {} : debug.generated.elems),
78
- oneProng : [],
79
- // oneProngAtDullCorner : [],
80
- twoProng : [],
81
- // twoProng_regular : [],
82
- // twoProng_failed : [],
83
- // twoProng_notAdded : [],
84
- // twoProng_deleted : [],
85
- // twoProng_holeClosing : [],
86
- looseBoundingBox : [],
87
- tightBoundingBox : [],
88
- // sharpCorner : [],
89
- // dullCorner : [],
90
- vertex : [],
91
- threeProng : [],
92
- boundingHull : [],
93
- mat : [],
94
- // sat : [],
95
- cpNode : [],
96
- maxVertex : [],
97
- leaves : [],
98
- // culls : [],
99
- },
100
- timing: {
101
- //...debug?.generated?.timing,
102
- ...(!debug ? {} : !debug.generated ? {} : !debug.generated.timing ? {} : debug.generated.timing),
103
- holeClosers : 0,
104
- oneAnd2Prongs : 0,
105
- threeProngs : 0,
106
- sats : 0,
107
- simplifyMat : 0,
108
- }
48
+ elems: {
49
+ ...debug?.elems
50
+ },
51
+ timing: {
52
+ ...debug?.timing,
53
+ holeClosers: 0,
54
+ oneAnd2Prongs: 0,
55
+ threeProngs: 0,
56
+ sats: 0,
57
+ simplifyMat: 0
109
58
  },
110
59
  fs: {
111
- //...debug?.fs,
112
- ...(!debug ? {} : !debug.fs ? {} : debug.fs),
113
- // @ts-ignore
114
- drawElem: {
115
- //...debug?.fs?.drawElem,
116
- ...(!debug ? {} : !debug.fs ? {} : !debug.fs.drawElem ? {} : debug.fs.drawElem),
117
- ...drawElemFs
118
- },
119
- ...generalDebugFunctions
60
+ ...debug?.fs
120
61
  },
121
62
  directives: {
122
63
  //...debug?.directives,
123
- ...(!debug ? {} : !debug.directives ? {} : debug.directives),
64
+ ...debug?.directives,
124
65
  stopAfterHoleClosers: false,
125
66
  stopAfterHoleClosersNum: undefined!,
126
67
  stopAfterTwoProngs: false,
@@ -134,7 +75,6 @@ function enableDebugForMat(debugOn: boolean) {
134
75
  }
135
76
 
136
77
 
137
- export {
138
- Debug, GeneratedElems, ITiming, Generated,
139
- IDebugFunctions, IDirectives, enableDebugForMat
140
- }
78
+ export type { Debug, Timing, Directives }
79
+ export { enableDebugForMat }
80
+
@@ -50,11 +50,7 @@ function add1Prong(
50
50
  return;
51
51
  }
52
52
 
53
- const { anyFailed, cpNodes } = addToCpTree(false, false, circle, [-0.5, +0.5], meta, [pos, pos]);
54
-
55
- // if (typeof _debug_ !== 'undefined') {
56
- // _debug_.generated.elems.oneProng.push(cpNodes);
57
- // }
53
+ addToCpTree(false, false, circle, [-0.5, +0.5], meta, [pos, pos]);
58
54
  }
59
55
 
60
56
 
@@ -15,7 +15,7 @@ import { ddNormal } from 'flo-bezier3';
15
15
  import { rotate } from 'flo-vector2d';
16
16
 
17
17
 
18
- const { sin, cos, max, sqrt } = Math;
18
+ const { abs, sin, cos, max, sqrt } = Math;
19
19
 
20
20
 
21
21
  /**
@@ -60,6 +60,7 @@ function find2Prong(
60
60
  angle: number,
61
61
  yPos: PrePointOnShape): { circle: Circle, z: PrePointOnShape } | undefined {
62
62
 
63
+
63
64
  const { curve: { loop, ps }, t, p: y } = yPos;
64
65
  const normDd = ddNormal(ps, t);
65
66
  const _nnorm = [-normDd[0][1], -normDd[1][1]]; // Left-handed system (sorry)
@@ -67,6 +68,10 @@ function find2Prong(
67
68
  ? [0, -maxOsculatingCircleRadius]
68
69
  : (angle !== 0 ? rotate(sin(angle), cos(angle))(_nnorm) : _nnorm);
69
70
 
71
+ const nnormDd = isHoleClosing || angle !== 0
72
+ ? [[0, nnorm[0]], [0, nnorm[1]]]
73
+ : [[-normDd[0][0], -normDd[0][1]], [-normDd[1][0], -normDd[1][1]]];
74
+
70
75
  // Get initial kissing circle guess
71
76
  let [xO,rO] = getInitialX(
72
77
  angle, isHoleClosing, maxOsculatingCircleRadius, yPos, nnorm
@@ -80,7 +85,7 @@ function find2Prong(
80
85
  );
81
86
 
82
87
  // The lines below is an optimization.
83
- const xy2 = reduceRadius(maxCoordPowerOf2, curvePieces, y, nnorm);
88
+ const xy2 = reduceRadius(maxCoordPowerOf2, rO, curvePieces, y, nnorm);
84
89
  const xy = sqrt(xy2);
85
90
 
86
91
  const l = sqrt(nnorm[0]**2 + nnorm[1]**2);
@@ -89,17 +94,24 @@ function find2Prong(
89
94
  cullCurvePieces(curvePieces, xO, xy2);
90
95
 
91
96
  const antipodalPoints = getAntipodalPoints(
92
- maxCoordPowerOf2, nnorm, yPos,
97
+ maxCoordPowerOf2, nnorm, nnormDd, yPos,
93
98
  for1Prong, angle,
94
99
  curvePieces
95
100
  );
96
101
 
102
+ // FUTURE - if antipodalPoints.length > 1 let's just add an n-prong;
97
103
  if (antipodalPoints.length !== 1) {
98
- if (antipodalPoints.length === 0) { return undefined; }
99
- if (!areAllAntipodesSame(antipodalPoints)) {
104
+ if (antipodalPoints.length === 0) {
105
+ if (isHoleClosing) {
106
+ console.log(yPos)
107
+ }
108
+ return undefined;
109
+ }
110
+ if (!isHoleClosing && !areAllAntipodesSame(antipodalPoints, maxCoordPowerOf2)) {
100
111
  // At this point there is multiple antipodal points (zs) for the given
101
112
  // source point so do not add the 2-prong, it will be caught when
102
113
  // adding 3+-prongs.
114
+
103
115
  return undefined;
104
116
  }
105
117
  }
@@ -111,9 +123,12 @@ function find2Prong(
111
123
  return undefined;
112
124
  }
113
125
 
126
+ const pDd = toP(curve.ps, s);
127
+ const p = pDd.map(c => c[0] + c[1]);
128
+
114
129
  const z: PrePointOnShape = {
115
130
  curve, t: s, isSource: false,
116
- p: toP(curve.ps, s)
131
+ p, pDd
117
132
  };
118
133
 
119
134
  const circle = { center: x, radius: d };
@@ -122,7 +137,9 @@ function find2Prong(
122
137
  const xz = squaredDistanceBetweenDd(x, z.p);
123
138
 
124
139
  if (!isHoleClosing) {
125
- if (yz === 0) { return undefined; }
140
+ if (yz === 0) {
141
+ return undefined;
142
+ }
126
143
 
127
144
  // The lines below eliminate cases where the found 2-prong is too
128
145
  // close to a one-prong
@@ -142,13 +159,19 @@ function find2Prong(
142
159
 
143
160
  /** @internal */
144
161
  function areAllAntipodesSame(
145
- app: AntipodalPoint[]): boolean {
146
-
147
- const { curve, s: t } = app[0];
148
- for (let i=1; i<app.length; i++) {
149
- const { curve: curve_, s: t_ } = app[i];
150
-
151
- if (curve !== curve_ || t !== t_) {
162
+ point: AntipodalPoint[],
163
+ maxCoordPowerOf2: number): boolean {
164
+
165
+ const { curve, s: t, x } = point[0];
166
+ const tol = 2**(maxCoordPowerOf2 - 40);
167
+ for (let i=1; i<point.length; i++) {
168
+ // const { curve: curve_, s: t_ } = point[i];
169
+ // if (curve !== curve_ || t !== t_) {
170
+ // return false;
171
+ // }
172
+
173
+ const { x: x_ } = point[i];
174
+ if (abs(x[0] - x_[0]) > tol || abs(x[0] - x_[0]) > tol) {
152
175
  return false;
153
176
  }
154
177
  }
@@ -19,7 +19,8 @@ import { getClosestPoint } from './get-closest-points.js';
19
19
  */
20
20
  function getAntipodalPoints(
21
21
  maxCoordPowerOf2: number,
22
- nnorm: number[],
22
+ nnorm: number[],
23
+ nnormDd: number[][],
23
24
  yPos: PrePointOnShape,
24
25
  for1Prong: boolean,
25
26
  angle: number,
@@ -30,7 +31,7 @@ function getAntipodalPoints(
30
31
  const curvePiece = curvePieces[i];
31
32
 
32
33
  const pInfos = getClosestPoint(
33
- maxCoordPowerOf2, nnorm, yPos, for1Prong, angle,
34
+ maxCoordPowerOf2, nnorm, nnormDd, yPos, for1Prong, angle,
34
35
  curvePiece
35
36
  );
36
37
 
@@ -0,0 +1,213 @@
1
+ import type { RootInterval } from 'flo-poly';
2
+ import type { CurvePiece } from "../../mat/curve-piece.js";
3
+ import type { PrePointOnShape } from "../../point-on-shape/point-on-shape.js";
4
+ import type { AntipodalPoint } from './antipodal-point.js';
5
+ import { lengthSquared } from "flo-vector2d";
6
+ import { roots, Horner } from 'flo-poly';
7
+ import { evalDeCasteljau, getMedialPointCoeffs, getMedialPointCoeffsBez0, getMedialPointCoeffsBez2_SameCurve, getMedialPointCoeffsBez3_SameCurve } from 'flo-bezier3';
8
+
9
+ const { sqrt, abs, max } = Math;
10
+
11
+
12
+ /**
13
+ * @param maxCoordPowerOf2
14
+ * @param nnorm
15
+ * @param yPos The point on the shape
16
+ * @param for1Prong defaults to `false`;
17
+ * @param angle defaults to `0`;
18
+ * @param curvePiece The curve piece
19
+ *
20
+ * @internal
21
+ */
22
+ function getClosestPoint(
23
+ maxCoordPowerOf2: number,
24
+ nnorm: number[],
25
+ nnormDd: number[][],
26
+ yPos: PrePointOnShape,
27
+ for1Prong: boolean,
28
+ angle: number,
29
+ curvePiece: CurvePiece): AntipodalPoint[] {
30
+
31
+ const { curve, ts: [tS,tE] } = curvePiece;
32
+ const { ps } = curve;
33
+ const { curve: touchedCurve, t, p: y, pDd: yDd } = yPos;
34
+
35
+ const isTouched = curve === touchedCurve;
36
+ const shouldDeflate = angle === 0 && isTouched;
37
+
38
+ const infos: AntipodalPoint[] = [];
39
+ let startPushed = false;
40
+ let endPushed = false;
41
+
42
+ let ss: RootInterval[];
43
+ if (tS !== tE &&
44
+ !(shouldDeflate && ps.length === 2) &&
45
+ !(isTouched && ps.length === 3 && for1Prong)) {
46
+
47
+ const { A, B, H } = shouldDeflate
48
+ ? ps.length === 3
49
+ ? getMedialPointCoeffsBez2_SameCurve(t, nnorm, ps)
50
+ : getMedialPointCoeffsBez3_SameCurve(t, nnorm, ps)
51
+ : getMedialPointCoeffs(y, nnorm, ps);
52
+
53
+ ss = roots(H, tS, tE) || [];
54
+ //-----------------------
55
+
56
+ for (let i=0; i<ss.length; i++) {
57
+ const ri = ss[i];
58
+ const { tS: sS, tE: sE, t: _s } = ri;
59
+ if (ri.multiplicity > 1) {
60
+ continue;
61
+ }
62
+
63
+ if (sE < tS || sS > tE) { continue; } // outside curve piece
64
+ if (sS < 0) { continue; } // outside curve piece
65
+
66
+ // clip to [0,1]
67
+ const s = sE > 1 ? 1 : _s;
68
+
69
+ //-----------------------
70
+ const AS = Horner(A, s);
71
+ const BS = Horner(B, s);
72
+ // const CS = Horner(C, s);
73
+ // const DS = Horner(D, s);
74
+
75
+ const _AS = abs(AS);
76
+ // const _CS = abs(CS);
77
+
78
+ // if (max(_AS, _CS) < 2**-40) { continue; }
79
+ if (max(_AS) < 2**-40) { continue; }
80
+
81
+ // const w = _AS > _CS
82
+ // ? -BS / AS
83
+ // : -DS / CS; // alternative
84
+ const w = -BS / AS;
85
+
86
+ if (w <= 0) {
87
+ // If `w` is negative the circle radius is negative -> discard
88
+ continue;
89
+ }
90
+
91
+ const V = [w*nnorm[0], w*nnorm[1]];
92
+ const d = sqrt(lengthSquared(V));
93
+
94
+ if (d <= 2**(maxCoordPowerOf2 - 40)) {
95
+ // If `w` <= 2**-40 -> discard
96
+ continue;
97
+ }
98
+
99
+ const x = [y[0] + V[0], y[1] + V[1]];
100
+ //-----------------------
101
+
102
+ if (ri.tS <= tS && ri.tE >= tS) {
103
+ startPushed = true;
104
+ }
105
+ if (ri.tS <= tE && ri.tE >= tE) {
106
+ endPushed = true;
107
+ }
108
+
109
+
110
+ // If the point is the first control point of the curve then we
111
+ // ensure the point becomes the last control point of the prior
112
+ // curve to induce some symmetery and simplify the algorithm.
113
+ const s_ = s === 0 ? 1 : s;
114
+ const curve_ = s === 0 ? curve.prev : curve;
115
+
116
+ const info: AntipodalPoint = {
117
+ curve: curve_,
118
+ s: s_,
119
+ d, x
120
+ };
121
+
122
+ infos.push(info);
123
+ }
124
+ }
125
+
126
+
127
+
128
+ //------------------------------------------
129
+ const pLast = ps[ps.length - 1];
130
+
131
+ let dontPush1 = (
132
+ (t === 0 && curve === touchedCurve!.prev) ||
133
+ (t === 1 && curve === touchedCurve)
134
+ );
135
+
136
+
137
+ //--------------------------------------
138
+ // Also check curve start control point
139
+ //--------------------------------------
140
+ const PS: { P: number[], t: number }[] = [];
141
+ if (tS === 0) {
142
+ // We never check points at `t === 0` since they are covered by the previous curve's endpoint
143
+ // which cannot be culled if this curve`s `t === 0` is included
144
+ } else if (tS === 1) {
145
+ if (!dontPush1 && !startPushed) {
146
+ PS.push({ P: pLast, t: 1 });
147
+ }
148
+ } else {
149
+ if (!startPushed) {
150
+ const pp = evalDeCasteljau(ps, tS);
151
+ PS.push({ P: pp, t: tS });
152
+ }
153
+ }
154
+
155
+ //--------------------------------------
156
+ // Also check curve end control point
157
+ //--------------------------------------
158
+ if (tS !== tE) {
159
+ if (tE === 0) {
160
+ // We never check points at `t === 0` since they are covered by the previous curve's endpoint
161
+ // which cannot be culled if this curve`s `t === 0` is included
162
+ } else if (tE === 1) {
163
+ if (!dontPush1 && !endPushed) {
164
+ PS.push({ P: pLast, t: 1 }); dontPush1 = true;
165
+ }
166
+ } else {
167
+ if (!endPushed) {
168
+ const pp = evalDeCasteljau(ps, tE);
169
+ PS.push({ P: pp, t: tE });
170
+ }
171
+ }
172
+ }
173
+ //------------------------------------------
174
+
175
+
176
+ for (let i=0; i<PS.length; i++) {
177
+ //-----------------------
178
+ const { P, t: s } = PS[i];
179
+ const { a0, b0 } = getMedialPointCoeffsBez0(y,nnorm,P);
180
+
181
+ if (abs(a0) <= 2**-40 || abs(b0) <= 2**-40) {
182
+ continue;
183
+ }
184
+
185
+ const w = -b0 / a0;
186
+
187
+ // too close to point of origin *or* negative;
188
+ if (w < 2**-40) {
189
+ continue;
190
+ }
191
+
192
+ const V = [w*nnorm[0], w*nnorm[1]];
193
+ const d = sqrt(lengthSquared(V));
194
+
195
+ const x = [y[0] + V[0], y[1] + V[1]];
196
+
197
+ const s_ = s === 0 ? 1 : s;
198
+ const curve_ = s === 0 ? curve.prev : curve;
199
+
200
+ const info: AntipodalPoint = {
201
+ curve: curve_,
202
+ s: s_,
203
+ d, x
204
+ };
205
+
206
+ infos.push(info);
207
+ }
208
+
209
+ return infos;
210
+ }
211
+
212
+
213
+ export { getClosestPoint }