flo-mat 4.0.3 → 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 (313) 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 +168 -4
  7. package/__tests__/specific-cases/test-svgs/achispado.svg +5052 -0
  8. package/browser/index.js +1686 -2738
  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/{reconstruct-from-mat → cp-node/fs}/get-all-on-loop-by-loop.d.ts +6 -2
  16. package/node/{reconstruct-from-mat → cp-node/fs}/get-all-on-loop-by-loop.js +5 -1
  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/debug/debug.d.ts +4 -13
  29. package/node/debug/debug.js +3 -30
  30. package/node/debug/debug.js.map +1 -1
  31. package/node/find-2-prong/find-2-prong.js +24 -10
  32. package/node/find-2-prong/find-2-prong.js.map +1 -1
  33. package/node/find-2-prong/get-medial/get-antipodal-points.d.ts +1 -1
  34. package/node/find-2-prong/get-medial/get-antipodal-points.js +2 -2
  35. package/node/find-2-prong/get-medial/get-antipodal-points.js.map +1 -1
  36. package/node/find-2-prong/get-medial/get-closest-points.d.ts +7 -1
  37. package/node/find-2-prong/get-medial/get-closest-points.js +60 -14
  38. package/node/find-2-prong/get-medial/get-closest-points.js.map +1 -1
  39. package/node/find-2-prong/reduce-radius.d.ts +3 -1
  40. package/node/find-2-prong/reduce-radius.js +8 -6
  41. package/node/find-2-prong/reduce-radius.js.map +1 -1
  42. package/node/find-3-prong/calc-better-x.js +1 -3
  43. package/node/find-3-prong/calc-better-x.js.map +1 -1
  44. package/node/find-3-prong/calc-initial-3-prong-center.js +1 -2
  45. package/node/find-3-prong/calc-initial-3-prong-center.js.map +1 -1
  46. package/node/find-3-prong/find-3-prong-for-delta3s.js +1 -4
  47. package/node/find-3-prong/find-3-prong-for-delta3s.js.map +1 -1
  48. package/node/find-3-prong/find-3-prong.js.map +1 -1
  49. package/node/find-3-prong/find-and-add-3-prong.js +0 -14
  50. package/node/find-3-prong/find-and-add-3-prong.js.map +1 -1
  51. package/node/find-mat/find-mat.js +2 -1
  52. package/node/find-mat/find-mat.js.map +1 -1
  53. package/node/find-mat/find-mats.js.map +1 -1
  54. package/node/find-mat/get-dull-corners-on-loop.js +3 -2
  55. package/node/find-mat/get-dull-corners-on-loop.js.map +1 -1
  56. package/node/find-mat/get-for-1-prongs-on-loop.js +6 -3
  57. package/node/find-mat/get-for-1-prongs-on-loop.js.map +1 -1
  58. package/node/find-mat/get-for-2-prongs-on-loop.js +5 -1
  59. package/node/find-mat/get-for-2-prongs-on-loop.js.map +1 -1
  60. package/node/find-mat/get-meta.d.ts +4 -1
  61. package/node/find-mat/get-meta.js +9 -1
  62. package/node/find-mat/get-meta.js.map +1 -1
  63. package/node/find-mat/get-sharp-corners.js +4 -2
  64. package/node/find-mat/get-sharp-corners.js.map +1 -1
  65. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez0.d.ts +21 -0
  66. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez0.js +46 -0
  67. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez0.js.map +1 -0
  68. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez1.d.ts +28 -0
  69. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez1.js +97 -0
  70. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez1.js.map +1 -0
  71. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez2-same-curve.d.ts +28 -0
  72. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez2-same-curve.js +109 -0
  73. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez2-same-curve.js.map +1 -0
  74. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez2.d.ts +29 -0
  75. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez2.js +123 -0
  76. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez2.js.map +1 -0
  77. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3-same-curve.d.ts +30 -0
  78. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3-same-curve.js +177 -0
  79. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3-same-curve.js.map +1 -0
  80. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.d.ts +29 -0
  81. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.js +156 -0
  82. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.js.map +1 -0
  83. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs.d.ts +28 -0
  84. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs.js +40 -0
  85. package/node/get-medial-points/double-double/dd-get-medial-point-coeffs.js.map +1 -0
  86. package/node/index.d.ts +4 -10
  87. package/node/index.js +3 -6
  88. package/node/index.js.map +1 -1
  89. package/node/point-on-shape/point-on-shape.d.ts +2 -0
  90. package/node/point-on-shape/to-p.d.ts +1 -1
  91. package/node/point-on-shape/to-p.js +1 -1
  92. package/node/point-on-shape/to-p.js.map +1 -1
  93. package/node/reconstruct-from-mat/get-cp-nodess-for-sat.js +2 -2
  94. package/node/reconstruct-from-mat/get-cp-nodess-for-sat.js.map +1 -1
  95. package/node/reconstruct-from-mat/reconstruct-from-mat.d.ts +8 -2
  96. package/node/reconstruct-from-mat/reconstruct-from-mat.js +154 -22
  97. package/node/reconstruct-from-mat/reconstruct-from-mat.js.map +1 -1
  98. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js +1 -1
  99. package/node/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.js.map +1 -1
  100. package/node/svg/get-loop-bounds.js +6 -2
  101. package/node/svg/get-loop-bounds.js.map +1 -1
  102. package/node/utils/map-deep.d.ts +15 -0
  103. package/node/utils/map-deep.js +34 -0
  104. package/node/utils/map-deep.js.map +1 -0
  105. package/package.json +14 -8
  106. package/src/closest-boundary-point/get-close-boundary-points-certified.ts +3 -2
  107. package/src/corner/get-corner.ts +1 -1
  108. package/src/{reconstruct-from-mat → cp-node/fs}/get-all-on-loop-by-loop.ts +7 -3
  109. package/src/cp-node/fs/get-all-on-loop.ts +1 -1
  110. package/src/cp-node/fs/get-boundary-beziers-to-next.ts +1 -72
  111. package/src/cp-node/fs/get-edge-direction.ts +8 -4
  112. package/src/cp-node/fs/get-mat-curve-between.ts +6 -6
  113. package/src/cp-node/fs/is-fully-terminating.ts +16 -0
  114. package/src/debug/debug.ts +8 -50
  115. package/src/find-2-prong/find-2-prong.ts +37 -14
  116. package/src/find-2-prong/get-medial/get-antipodal-points.ts +3 -2
  117. package/src/find-2-prong/get-medial/get-closest-points-d.ts +213 -0
  118. package/src/find-2-prong/get-medial/get-closest-points.ts +74 -13
  119. package/src/find-2-prong/reduce-radius.ts +8 -5
  120. package/src/find-3-prong/calc-better-x.ts +1 -3
  121. package/src/find-3-prong/calc-initial-3-prong-center.ts +1 -2
  122. package/src/find-3-prong/find-3-prong-for-delta3s.ts +1 -4
  123. package/src/find-3-prong/find-3-prong.ts +0 -1
  124. package/src/find-3-prong/find-and-add-3-prong.ts +1 -15
  125. package/src/find-mat/find-mat.ts +3 -1
  126. package/src/find-mat/find-mats.ts +0 -1
  127. package/src/find-mat/get-dull-corners-on-loop.ts +4 -3
  128. package/src/find-mat/get-for-1-prongs-on-loop.ts +8 -3
  129. package/src/find-mat/get-for-2-prongs-on-loop.ts +6 -1
  130. package/src/find-mat/get-meta.ts +11 -0
  131. package/src/find-mat/get-sharp-corners.ts +5 -1
  132. package/src/get-medial-curve/__pycache__/get-cubic-self-medial-curve.cpython-313.pyc +0 -0
  133. package/src/get-medial-curve/get-cubic-self-medial-curve.py +419 -0
  134. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez0-with-running-err.ts +76 -0
  135. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez0.ts +61 -0
  136. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez1.ts +116 -0
  137. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez2-same-curve.ts +129 -0
  138. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez2.ts +142 -0
  139. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3-same-curve.ts +199 -0
  140. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs-bez3.ts +177 -0
  141. package/src/get-medial-points/double-double/dd-get-medial-point-coeffs.ts +48 -0
  142. package/src/get-medial-points/double-double/error-bound-calc.txt +72 -0
  143. package/src/index.ts +4 -10
  144. package/src/point-on-shape/point-on-shape.ts +3 -0
  145. package/src/point-on-shape/to-p.ts +2 -2
  146. package/src/reconstruct-from-mat/get-cp-nodess-for-sat.ts +2 -2
  147. package/src/reconstruct-from-mat/reconstruct-from-mat.ts +202 -21
  148. package/src/reconstruct-from-mat/remove-sat-induced-trivial-3prongs.ts +1 -1
  149. package/src/svg/get-loop-bounds.ts +11 -3
  150. package/src/utils/map-deep.ts +75 -0
  151. package/src/utils/map-map.ts +33 -0
  152. package/wallaby.mjs +4 -4
  153. package/node/debug/debug-elem-types.d.ts +0 -26
  154. package/node/debug/debug-elem-types.js +0 -22
  155. package/node/debug/debug-elem-types.js.map +0 -1
  156. package/node/debug/functions/draw/draw-beziers-as-single-path.d.ts +0 -2
  157. package/node/debug/functions/draw/draw-beziers-as-single-path.js +0 -30
  158. package/node/debug/functions/draw/draw-beziers-as-single-path.js.map +0 -1
  159. package/node/debug/functions/draw/xmlns.d.ts +0 -2
  160. package/node/debug/functions/draw/xmlns.js +0 -3
  161. package/node/debug/functions/draw/xmlns.js.map +0 -1
  162. package/node/debug/functions/draw-elem/bounding-hull.d.ts +0 -3
  163. package/node/debug/functions/draw-elem/bounding-hull.js +0 -8
  164. package/node/debug/functions/draw-elem/bounding-hull.js.map +0 -1
  165. package/node/debug/functions/draw-elem/draw-branch.d.ts +0 -4
  166. package/node/debug/functions/draw-elem/draw-branch.js +0 -26
  167. package/node/debug/functions/draw-elem/draw-branch.js.map +0 -1
  168. package/node/debug/functions/draw-elem/draw-circle-percent.d.ts +0 -3
  169. package/node/debug/functions/draw-elem/draw-circle-percent.js +0 -13
  170. package/node/debug/functions/draw-elem/draw-circle-percent.js.map +0 -1
  171. package/node/debug/functions/draw-elem/draw-cp-node.d.ts +0 -4
  172. package/node/debug/functions/draw-elem/draw-cp-node.js +0 -26
  173. package/node/debug/functions/draw-elem/draw-cp-node.js.map +0 -1
  174. package/node/debug/functions/draw-elem/draw-cull.d.ts +0 -3
  175. package/node/debug/functions/draw-elem/draw-cull.js +0 -9
  176. package/node/debug/functions/draw-elem/draw-cull.js.map +0 -1
  177. package/node/debug/functions/draw-elem/draw-dull-corner.d.ts +0 -4
  178. package/node/debug/functions/draw-elem/draw-dull-corner.js +0 -10
  179. package/node/debug/functions/draw-elem/draw-dull-corner.js.map +0 -1
  180. package/node/debug/functions/draw-elem/draw-elem.d.ts +0 -10
  181. package/node/debug/functions/draw-elem/draw-elem.js +0 -39
  182. package/node/debug/functions/draw-elem/draw-elem.js.map +0 -1
  183. package/node/debug/functions/draw-elem/draw-leaves.d.ts +0 -4
  184. package/node/debug/functions/draw-elem/draw-leaves.js +0 -34
  185. package/node/debug/functions/draw-elem/draw-leaves.js.map +0 -1
  186. package/node/debug/functions/draw-elem/draw-loop.d.ts +0 -4
  187. package/node/debug/functions/draw-elem/draw-loop.js +0 -11
  188. package/node/debug/functions/draw-elem/draw-loop.js.map +0 -1
  189. package/node/debug/functions/draw-elem/draw-loops.d.ts +0 -4
  190. package/node/debug/functions/draw-elem/draw-loops.js +0 -6
  191. package/node/debug/functions/draw-elem/draw-loops.js.map +0 -1
  192. package/node/debug/functions/draw-elem/draw-loose-bounding-box.d.ts +0 -3
  193. package/node/debug/functions/draw-elem/draw-loose-bounding-box.js +0 -10
  194. package/node/debug/functions/draw-elem/draw-loose-bounding-box.js.map +0 -1
  195. package/node/debug/functions/draw-elem/draw-mat.d.ts +0 -4
  196. package/node/debug/functions/draw-elem/draw-mat.js +0 -34
  197. package/node/debug/functions/draw-elem/draw-mat.js.map +0 -1
  198. package/node/debug/functions/draw-elem/draw-max-vertex.d.ts +0 -4
  199. package/node/debug/functions/draw-elem/draw-max-vertex.js +0 -9
  200. package/node/debug/functions/draw-elem/draw-max-vertex.js.map +0 -1
  201. package/node/debug/functions/draw-elem/draw-min-y.d.ts +0 -4
  202. package/node/debug/functions/draw-elem/draw-min-y.js +0 -10
  203. package/node/debug/functions/draw-elem/draw-min-y.js.map +0 -1
  204. package/node/debug/functions/draw-elem/draw-one-prong-at-dull-corner.d.ts +0 -4
  205. package/node/debug/functions/draw-elem/draw-one-prong-at-dull-corner.js +0 -22
  206. package/node/debug/functions/draw-elem/draw-one-prong-at-dull-corner.js.map +0 -1
  207. package/node/debug/functions/draw-elem/draw-one-prong.d.ts +0 -4
  208. package/node/debug/functions/draw-elem/draw-one-prong.js +0 -13
  209. package/node/debug/functions/draw-elem/draw-one-prong.js.map +0 -1
  210. package/node/debug/functions/draw-elem/draw-sharp-corner.d.ts +0 -4
  211. package/node/debug/functions/draw-elem/draw-sharp-corner.js +0 -10
  212. package/node/debug/functions/draw-elem/draw-sharp-corner.js.map +0 -1
  213. package/node/debug/functions/draw-elem/draw-three-prong.d.ts +0 -4
  214. package/node/debug/functions/draw-elem/draw-three-prong.js +0 -26
  215. package/node/debug/functions/draw-elem/draw-three-prong.js.map +0 -1
  216. package/node/debug/functions/draw-elem/draw-tight-bounding-box.d.ts +0 -3
  217. package/node/debug/functions/draw-elem/draw-tight-bounding-box.js +0 -8
  218. package/node/debug/functions/draw-elem/draw-tight-bounding-box.js.map +0 -1
  219. package/node/debug/functions/draw-elem/draw-two-prong.d.ts +0 -4
  220. package/node/debug/functions/draw-elem/draw-two-prong.js +0 -49
  221. package/node/debug/functions/draw-elem/draw-two-prong.js.map +0 -1
  222. package/node/debug/functions/draw-elem/draw-vertex.d.ts +0 -4
  223. package/node/debug/functions/draw-elem/draw-vertex.js +0 -13
  224. package/node/debug/functions/draw-elem/draw-vertex.js.map +0 -1
  225. package/node/find-3-prong/timed-cc.d.ts +0 -3
  226. package/node/find-3-prong/timed-cc.js +0 -5
  227. package/node/find-3-prong/timed-cc.js.map +0 -1
  228. package/node/reconstruct-from-mat/filter-zero-length.d.ts +0 -10
  229. package/node/reconstruct-from-mat/filter-zero-length.js +0 -14
  230. package/node/reconstruct-from-mat/filter-zero-length.js.map +0 -1
  231. package/node/reconstruct-from-mat/get-all-on-loop-by-loop.js.map +0 -1
  232. package/node/reconstruct-from-mat/get-bezier-piece-length.d.ts +0 -3
  233. package/node/reconstruct-from-mat/get-bezier-piece-length.js +0 -6
  234. package/node/reconstruct-from-mat/get-bezier-piece-length.js.map +0 -1
  235. package/node/reconstruct-from-mat/get-boundary.d.ts +0 -7
  236. package/node/reconstruct-from-mat/get-boundary.js +0 -18
  237. package/node/reconstruct-from-mat/get-boundary.js.map +0 -1
  238. package/node/reconstruct-from-mat/get-matching-beziers.d.ts +0 -10
  239. package/node/reconstruct-from-mat/get-matching-beziers.js +0 -29
  240. package/node/reconstruct-from-mat/get-matching-beziers.js.map +0 -1
  241. package/node/reconstruct-from-mat/get-mbss-by-loop-per-sat.d.ts +0 -6
  242. package/node/reconstruct-from-mat/get-mbss-by-loop-per-sat.js +0 -10
  243. package/node/reconstruct-from-mat/get-mbss-by-loop-per-sat.js.map +0 -1
  244. package/node/reconstruct-from-mat/get-mbss-by-loop-with-opp-arr.d.ts +0 -7
  245. package/node/reconstruct-from-mat/get-mbss-by-loop-with-opp-arr.js +0 -47
  246. package/node/reconstruct-from-mat/get-mbss-by-loop-with-opp-arr.js.map +0 -1
  247. package/node/reconstruct-from-mat/get-sats2.d.ts +0 -10
  248. package/node/reconstruct-from-mat/get-sats2.js +0 -16
  249. package/node/reconstruct-from-mat/get-sats2.js.map +0 -1
  250. package/node/reconstruct-from-mat/is-fully-terminating.d.ts +0 -3
  251. package/node/reconstruct-from-mat/is-fully-terminating.js +0 -19
  252. package/node/reconstruct-from-mat/is-fully-terminating.js.map +0 -1
  253. package/node/reconstruct-from-mat/matched-beziers.d.ts +0 -10
  254. package/node/reconstruct-from-mat/matched-beziers.js +0 -2
  255. package/node/reconstruct-from-mat/matched-beziers.js.map +0 -1
  256. package/node/reconstruct-from-mat/split-tri-path.d.ts +0 -5
  257. package/node/reconstruct-from-mat/split-tri-path.js +0 -209
  258. package/node/reconstruct-from-mat/split-tri-path.js.map +0 -1
  259. package/node/utils/clip.d.ts +0 -2
  260. package/node/utils/clip.js +0 -6
  261. package/node/utils/clip.js.map +0 -1
  262. package/node/utils/time-function-call.d.ts +0 -14
  263. package/node/utils/time-function-call.js +0 -32
  264. package/node/utils/time-function-call.js.map +0 -1
  265. package/src/debug/debug-elem-types.ts +0 -43
  266. package/src/debug/functions/draw-elem/bounding-hull.ts +0 -18
  267. package/src/debug/functions/draw-elem/culls.ts +0 -39
  268. package/src/debug/functions/draw-elem/draw-branch.ts +0 -37
  269. package/src/debug/functions/draw-elem/draw-circle-percent.ts +0 -23
  270. package/src/debug/functions/draw-elem/draw-cp-node.ts +0 -46
  271. package/src/debug/functions/draw-elem/draw-cull.ts +0 -21
  272. package/src/debug/functions/draw-elem/draw-dull-corner.ts +0 -21
  273. package/src/debug/functions/draw-elem/draw-elem.ts +0 -64
  274. package/src/debug/functions/draw-elem/draw-leaves.ts +0 -51
  275. package/src/debug/functions/draw-elem/draw-loop.ts +0 -16
  276. package/src/debug/functions/draw-elem/draw-loops.ts +0 -10
  277. package/src/debug/functions/draw-elem/draw-loose-bounding-box.ts +0 -21
  278. package/src/debug/functions/draw-elem/draw-mat.ts +0 -43
  279. package/src/debug/functions/draw-elem/draw-max-vertex.ts +0 -15
  280. package/src/debug/functions/draw-elem/draw-min-y.ts +0 -18
  281. package/src/debug/functions/draw-elem/draw-one-prong-at-dull-corner.ts +0 -40
  282. package/src/debug/functions/draw-elem/draw-one-prong.ts +0 -25
  283. package/src/debug/functions/draw-elem/draw-sharp-corner.ts +0 -21
  284. package/src/debug/functions/draw-elem/draw-three-prong.ts +0 -44
  285. package/src/debug/functions/draw-elem/draw-tight-bounding-box.ts +0 -18
  286. package/src/debug/functions/draw-elem/draw-two-prong.ts +0 -68
  287. package/src/debug/functions/draw-elem/draw-vertex.ts +0 -27
  288. package/src/debug/functions/draw-elem/dull-corner.ts +0 -21
  289. package/src/debug/functions/draw-elem/leaves.ts +0 -20
  290. package/src/debug/functions/draw-elem/loop.ts +0 -16
  291. package/src/debug/functions/draw-elem/loops.ts +0 -10
  292. package/src/debug/functions/draw-elem/loose-bounding-box.ts +0 -21
  293. package/src/debug/functions/draw-elem/mat.ts +0 -47
  294. package/src/debug/functions/draw-elem/max-vertex.ts +0 -15
  295. package/src/debug/functions/draw-elem/min-y.ts +0 -18
  296. package/src/debug/functions/draw-elem/one-prong-at-dull-corner.ts +0 -26
  297. package/src/debug/functions/draw-elem/one-prong.ts +0 -23
  298. package/src/debug/functions/draw-elem/sharp-corner.ts +0 -20
  299. package/src/debug/functions/draw-elem/three-prong.ts +0 -30
  300. package/src/debug/functions/draw-elem/tight-bounding-box.ts +0 -18
  301. package/src/debug/functions/draw-elem/two-prong.ts +0 -50
  302. package/src/debug/functions/draw-elem/vertex.ts +0 -51
  303. package/src/find-3-prong/timed-cc.ts +0 -9
  304. package/src/reconstruct-from-mat/filter-zero-length.ts +0 -23
  305. package/src/reconstruct-from-mat/get-bezier-piece-length.ts +0 -12
  306. package/src/reconstruct-from-mat/get-boundary.ts +0 -32
  307. package/src/reconstruct-from-mat/get-matching-beziers.ts +0 -46
  308. package/src/reconstruct-from-mat/get-mbss-by-loop-per-sat.ts +0 -19
  309. package/src/reconstruct-from-mat/get-mbss-by-loop-with-opp-arr.ts +0 -69
  310. package/src/reconstruct-from-mat/get-sats2.ts +0 -25
  311. package/src/reconstruct-from-mat/is-fully-terminating.ts +0 -27
  312. package/src/reconstruct-from-mat/matched-beziers.ts +0 -14
  313. package/src/reconstruct-from-mat/split-tri-path.ts +0 -280
@@ -0,0 +1,61 @@
1
+ import { ddAddDd, ddMultDd, ddMultBy2, ddDiffDouble } from 'double-double';
2
+
3
+ const qaq = ddAddDd;
4
+ const qmq = ddMultDd;
5
+ const qm2 = ddMultBy2;
6
+ const qdd = ddDiffDouble;
7
+
8
+
9
+ // TODO - move all these upstream to flo-bezier3
10
+
11
+ /**
12
+ * Returns the coefficients `a0` and `b0` for the linear equation
13
+ * `a0⋅t + b0 = 0`, so the ray parameter can be recovered as `t = -b0/a0`.
14
+ * That parameter value makes `q(t) = p + t⋅v` equidistant from `p` and `P`.
15
+ *
16
+ * Let `p` be a fixed point in the plane.\
17
+ * Let `v` be a direction vector defining the ray `q(t) = p + t⋅v`.\
18
+ * Let `P` be another point.\
19
+ *
20
+ * In other words, this function returns the coefficients needed to solve for
21
+ * the ray parameter of the medial point on the ray.
22
+ *
23
+ * @param p base point
24
+ * @param v ray direction from `p`
25
+ * @param P another "target" point, e.g. `[1,2]`
26
+ */
27
+ function ddGetMedialPointCoeffsBez0(
28
+ p: number[][],
29
+ v: number[][],
30
+ P: number[]) {
31
+
32
+ // -----------------------------------------------------
33
+ // See get-medial-points.md for implementation details.
34
+ // -----------------------------------------------------
35
+
36
+ const [px, py] = p;
37
+ const [vx, vy] = v;
38
+ const [x0, y0] = P;
39
+
40
+ // Constant bezier in power basis: b(s) = c
41
+ // u(s) = p - b(s) = u0
42
+
43
+ // const u0x = px - x0;
44
+ // const u0y = py - y0;
45
+ const u0x = qdd(px,x0);
46
+ const u0y = qdd(py,y0);
47
+
48
+ // E2(s,t): |t⋅v|² - |u(s) + t⋅v|² = 0
49
+ // => 2⋅(v⋅u(s))⋅t + |u(s)|² = 0
50
+ // => A(s)⋅t + B(s) = 0
51
+
52
+ // const a0 = 2*(vx*u0x + vy*u0y);
53
+ // const b0 = u0x*u0x + u0y*u0y;
54
+ const a0 = qaq(qmq(qm2(vx),u0x),qmq(qm2(vy),u0y));
55
+ const b0 = qaq(qmq(u0x,u0x), qmq(u0y,u0y));
56
+
57
+ return { a0, b0 };
58
+ }
59
+
60
+
61
+ export { ddGetMedialPointCoeffsBez0 }
@@ -0,0 +1,116 @@
1
+ import { twoDiff, ddAddDd, ddMultDd, ddNegativeOf, ddMultByNeg2, ddDiffDouble, ddMultBy2 } from 'double-double';
2
+
3
+ const td = twoDiff;
4
+ const qaq = ddAddDd;
5
+ const qmq = ddMultDd;
6
+ const qno = ddNegativeOf;
7
+ const qmn2 = ddMultByNeg2;
8
+ const qm2 = ddMultBy2;
9
+ const qdd = ddDiffDouble;
10
+
11
+
12
+ /**
13
+ * Returns the polynomial coefficients used to recover ray parameter values `t`
14
+ * for a ray `q(t) = p + t⋅v` and an order-1 bezier curve `ps`.
15
+ *
16
+ * The returned polynomials encode the medial-condition equations in `s` and
17
+ * `t`. For any valid solution, `t` is recovered by eliminating `s` and solving
18
+ * the resulting ray equation, or equivalently by using the linear form
19
+ * `A(s)⋅t + B(s) = 0`, which gives `t = -B(s)/A(s)`.
20
+ *
21
+ * More specifically, the returned values represent:
22
+ * * `A` and `B`: the coefficients of `E2(s,t) = A(s)⋅t + B(s)`
23
+ * * `C` and `D`: the coefficients of `E1(s,t) = C(s)⋅t + D(s)`
24
+ * * `H`: the eliminated polynomial `A(s)⋅D(s) - B(s)⋅C(s)` whose roots are
25
+ * candidate `s` values for medial points
26
+ *
27
+ * @param p base point
28
+ * @param v ray direction vector starting from `p`
29
+ * @param ps order 1 bezier control points, i.e. a line segment
30
+ * given as an array of control points, e.g. `[[0,0],[2,1]]`
31
+ */
32
+ function ddGetMedialPointCoeffsBez1(
33
+ p: number[][],
34
+ v: number[][],
35
+ ps: number[][]) {
36
+
37
+ // -----------------------------------------------------
38
+ // See get-medial-points.md for implementation details.
39
+ // -----------------------------------------------------
40
+ const [px, py] = p;
41
+ const [vx, vy] = v;
42
+ const [[x0, y0], [x1, y1]] = ps;
43
+
44
+ // Linear bezier in power basis: b(s) = b*s + c
45
+ // We can also use: `const [[bx,by], [cx,cy]] = toPowerBasis1(ps)`
46
+ // const bx = x1 - x0;
47
+ // const by = y1 - y0;
48
+ const bx = td(x1,x0);
49
+ const by = td(y1,y0);
50
+
51
+ // u(s) = p - b(s) = u1*s + u0
52
+ // const u0x = px - x0;
53
+ // const u0y = py - y0;
54
+ const u0x = qdd(px,x0);
55
+ const u0y = qdd(py,y0);
56
+
57
+ // b'(s) = w(s) = w0
58
+
59
+ // -----------------------------------------------------
60
+ // E1(s,t): (u(s) + t⋅v) ⋅ b'(s) = 0
61
+ // => C(s)⋅t + D(s) = 0
62
+ // const c0 = vx*bx + vy*by;
63
+ const c0 = qaq(qmq(vx,bx),qmq(vy,by));
64
+ // -----------------------------------------------------
65
+
66
+ // -----------------------------------------------------
67
+ // const d1 = -(bx*bx + by*by);
68
+ // const d0 = bx*u0x + by*u0y;
69
+ // const d1 = qmd(-1,qaq(qmq(bx,bx),qmq(by,by)));
70
+ const d1 = qno(qaq(qmq(bx,bx), qmq(by,by)));
71
+ const d0 = qaq(qmq(bx,u0x), qmq(by,u0y));
72
+ // -----------------------------------------------------
73
+
74
+ // -----------------------------------------------------
75
+ // E2(s,t): |t⋅v|² - |u(s) + t⋅v|² = 0
76
+ // => 2⋅(v⋅u(s))⋅t + |u(s)|² = 0
77
+ // => A(s)⋅t + B(s) = 0
78
+ // const a1 = -2*c0;
79
+ // const a0 = 2*(vx*u0x + vy*u0y);
80
+ const a1 = qmn2(c0);
81
+ const a0 = qaq(qmq(qm2(vx),u0x), qmq(qm2(vy),u0y));
82
+ // -----------------------------------------------------
83
+
84
+ // -----------------------------------------------------
85
+ // const b2 = -d1;
86
+ // const b1 = -2*d0;
87
+ // const b0 = u0x*u0x + u0y*u0y;
88
+ const b2 = qno(d1);
89
+ const b1 = qmn2(d0);
90
+ const b0 = qaq(qmq(u0x,u0x), qmq(u0y,u0y));
91
+ // -----------------------------------------------------
92
+
93
+
94
+ // Eliminate t from:
95
+ // A(s)⋅t + B(s) = 0
96
+ // C(s)⋅t + D(s) = 0
97
+ // by taking A(s)⋅D(s) - B(s)⋅C(s) = 0 (degree ≤ 2 in s)
98
+
99
+ // const H2 = b2*c0;
100
+ // const H1 = a0*d1;
101
+ // const H0 = a0*d0 - b0*c0;
102
+ const H2 = qmq(b2,c0);
103
+ const H1 = qmq(a0,d1);
104
+ const H0 = qaq(qmq(a0,d0), qno(qmq(b0,c0)));
105
+
106
+ return {
107
+ A: [a1, a0],
108
+ B: [b2, b1, b0],
109
+ C: [c0],
110
+ D: [d1, d0],
111
+ H: [H2, H1, H0]
112
+ };
113
+ }
114
+
115
+
116
+ export { ddGetMedialPointCoeffsBez1 }
@@ -0,0 +1,129 @@
1
+ import { toPowerBasisDd } from 'flo-bezier3';
2
+ import { ddMultDouble2, ddAddDd, ddMultDd, ddNegativeOf, ddMultBy2 } from 'double-double';
3
+
4
+ const qmd = ddMultDouble2;
5
+ const qaq = ddAddDd;
6
+ const qmq = ddMultDd;
7
+ const qno = ddNegativeOf;
8
+ const qm2 = ddMultBy2;
9
+
10
+
11
+ /**
12
+ * Returns polynomial coefficients for the same-curve quadratic medial-point
13
+ * case, where `p = b(t)` on the same quadratic bezier `ps` and `v` is normal
14
+ * to the curve at that parameter `t`.
15
+ *
16
+ * The returned coefficients encode:
17
+ * * `A`, `B`: `E2(s, τ) = (s - t)^2⋅(A(s)⋅τ + B(s))`
18
+ // * * `C`, `D`: `E1(s, τ) = C(s)⋅τ + D(s)`
19
+ * * `H`: the reduced eliminant in `s`
20
+ *
21
+ * Here `τ` is the ray parameter in `q(τ) = p + τ⋅v`.
22
+ * For a candidate root `s` of `H`, recover `τ` from
23
+ * `A(s)⋅τ + B(s) = 0`, i.e. `τ = -B(s)/A(s)` when `A(s) ≠ 0`.
24
+ *
25
+ * In this same-curve setup, the full eliminant has the form
26
+ * `H_full(s) = (s - t)^4*(l1*s + l0)`. This function returns only the reduced
27
+ * factor `H(s) = l1*s + l0` (the repeated `(s - t)^4` factor is omitted).
28
+ *
29
+ * @param t parameter on `ps` where `p = b(t)`
30
+ * @param v ray direction from `p`; assumed normal to `ps` at `t`
31
+ * @param ps order 2 bezier control points, e.g. `[[0,0],[1,1],[2,1]]`
32
+ */
33
+ function ddGetMedialPointCoeffsBez2_SameCurve(
34
+ t: number,
35
+ v: number[][],
36
+ ps: number[][]) {
37
+
38
+ // -----------------------------------------------------
39
+ // See get-medial-points.md for implementation details.
40
+ // -----------------------------------------------------
41
+ // Quadratic bezier in power basis: b(s) = a⋅s² + b⋅s + c
42
+ const [[ax,bx], [ay,by]] = toPowerBasisDd(ps);
43
+
44
+ const [vx,vy] = v;
45
+
46
+ // Same-curve assumption with explicit parameter `t`:
47
+ // p = b(t) => u0 = p - c = t*(a*t + b).
48
+ // const g0x = ax*t + bx;
49
+ // const g0y = ay*t + by;
50
+ const g0x = qaq(qmd(t,ax),bx);
51
+ const g0y = qaq(qmd(t,ay),by);
52
+
53
+ // Reuse core quadratic-form terms to reduce repeated multiplications.
54
+ // const br2 = ax*ax + ay*ay;
55
+ // const ab = ax*bx + ay*by;
56
+ // const bb = bx*bx + by*by;
57
+ // const ag = ax*g0x + ay*g0y;
58
+ const br2 = qaq(qmq(ax,ax),qmq(ay,ay));
59
+ const ab = qaq(qmq(ax,bx),qmq(ay,by));
60
+ const ag = qaq(qmq(ax,g0x),qmq(ay,g0y));
61
+
62
+ // -----------------------------------------------------
63
+ // E1(s,t): (u(s) + t⋅v) ⋅ b'(s) = 0
64
+ // => C(s)⋅t + D(s) = 0
65
+ // const c1 = 2*(vx*ax + vy*ay);
66
+ const c1 = qm2(qaq(qmq(vx,ax),qmq(vy,ay)));
67
+ // v is normal at parameter t, so C(t) = v⋅w(t) = 0.
68
+ // Since C(s) = c1*s + c0, enforce c0 = -c1*t exactly.
69
+ // const c0 = -c1*t;
70
+
71
+ // const d3 = -2*br2;
72
+ // const d2 = -3*ab;
73
+ // const d1 = 2*t*ag - bb;
74
+ // p = b(t) => D(t) = u(t)⋅w(t) = 0.
75
+ // const d0 = -t*(t*(d3*t + d2) + d1);
76
+ // -----------------------------------------------------
77
+
78
+ // -----------------------------------------------------
79
+ // E2(s,t): |t⋅v|² - |u(s) + t⋅v|² = 0
80
+ // => 2⋅(v⋅u(s))⋅t + |u(s)|² = 0
81
+ // => (s - t)^2⋅(A(s)⋅t + B(s)) = 0
82
+ // Return only the reduced constant A(s) = ar0.
83
+ // const ar0 = -c1;
84
+ const ar0 = qno(c1);
85
+
86
+ // Full B(s) factorizes as: B_full(s) = (s - t)^2*B_reduced(s).
87
+ // Return only B_reduced(s) = br2*s^2 + br1*s + br0.
88
+ // const br1 = 2*ag;
89
+ // const br0 = g0x*g0x + g0y*g0y;
90
+ const br1 = qm2(ag);
91
+ const br0 = qaq(qmq(g0x,g0x),qmq(g0y,g0y));
92
+ // -----------------------------------------------------
93
+
94
+
95
+ // Eliminate t from:
96
+ // A(s)⋅t + B(s) = 0
97
+ // C(s)⋅t + D(s) = 0
98
+ // by taking A(s)⋅D(s) - B(s)⋅C(s) = 0 (degree ≤ 5 in s)
99
+
100
+ // For this same-curve quadratic case:
101
+ // d3 = -2*b4, d2 = -(3/2)*b3, a2 = -c1, a1 = -2*c0.
102
+ // Therefore H5 and H4 reduce to:
103
+ // H5 = b4*c1
104
+ // H4 = 3*b4*c0 + (1/2)*b3*c1
105
+ // const H5 = br2*c1;
106
+ const H5 = qmq(br2,c1);
107
+
108
+ // In the same-curve quadratic case the full eliminant has the form
109
+ // H_full(s) = (s - t)^4*(l1*s + l0).
110
+ // Match the leading coefficients of H_full(s):
111
+ // H5 = l1
112
+ // H4 = l0 - 4*t*l1
113
+ // const l1 = H5;
114
+ // const l0 = H4 + 4*t*l1;
115
+ // Using c0 = -c1*t and b3 = 2*ab, this simplifies to l0 = c1*(br2*t + ab).
116
+ // const l0 = c1*(br2*t + ab);
117
+ const l0 = qmq(c1,qaq(qmd(t,br2),ab));
118
+
119
+ return {
120
+ A: [ar0],
121
+ B: [br2, br1, br0],
122
+ // C: [c1, c0],
123
+ // D: [d3, d2, d1, d0],
124
+ H: [H5, l0]
125
+ };
126
+ }
127
+
128
+
129
+ export { ddGetMedialPointCoeffsBez2_SameCurve }
@@ -0,0 +1,142 @@
1
+ import { toPowerBasisDd } from 'flo-bezier3';
2
+ import { ddMultDouble2, ddAddDd, ddMultDd, ddNegativeOf, ddMultByNeg2, ddMultBy2, ddDiffDouble } from 'double-double';
3
+
4
+ const qmd = ddMultDouble2;
5
+ const qaq = ddAddDd;
6
+ const qmq = ddMultDd;
7
+ const qno = ddNegativeOf;
8
+ const qmn2 = ddMultByNeg2;
9
+ const qm2 = ddMultBy2;
10
+ const qdd = ddDiffDouble;
11
+
12
+
13
+ /**
14
+ * Returns the polynomial coefficients for the ray parameter `t` and the
15
+ * curve parameter `s` that encode the medial condition for `q(t) = p + t⋅v`
16
+ * and a quadratic bezier curve `ps`.
17
+ *
18
+ * The returned coefficients describe the equations whose common solutions
19
+ * satisfy:
20
+ * * `q(t)` is equidistant from `p` and the nearest point on `ps`
21
+ * * that common distance is locally minimal among such candidates
22
+ *
23
+ * More specifically, this function returns:
24
+ * * `A` and `B`: the coefficients of `E2(s,t) = A(s)⋅t + B(s)`
25
+ * * `C` and `D`: the coefficients of `E1(s,t) = C(s)⋅t + D(s)`
26
+ * * `H`: the eliminated polynomial `A(s)⋅D(s) - B(s)⋅C(s)` whose roots are
27
+ * candidate `s` values for medial points
28
+ *
29
+ * @param p base point
30
+ * @param v ray direction from `p`
31
+ * @param ps quadratic bezier control points, i.e. an order 2 bezier curve
32
+ * given as an array of control points, e.g. `[[0,0],[1,1],[2,1]]`
33
+ */
34
+ function ddGetMedialPointCoeffsBez2(
35
+ p: number[][],
36
+ v: number[][],
37
+ ps: number[][]) {
38
+
39
+ // -----------------------------------------------------
40
+ // See get-medial-points.md for implementation details.
41
+ // -----------------------------------------------------
42
+ const [px, py] = p;
43
+ const [vx, vy] = v;
44
+ const [[x0, y0]] = ps;
45
+
46
+ // Quadratic bezier in power basis: b(s) = a⋅s² + b⋅s + c
47
+ const [[ax, bx], [ay, by]] = toPowerBasisDd(ps);
48
+
49
+ // u(s) = p - b(s) = u2⋅s² + u1⋅s + u0
50
+ // const u0x = px - x0;
51
+ // const u0y = py - y0;
52
+ const u0x = qdd(px,x0);
53
+ const u0y = qdd(py,y0);
54
+
55
+ // Shared dot products.
56
+ // const c1 = 2*(vx*ax + vy*ay);
57
+ // const c0 = vx*bx + vy*by;
58
+ // const vu0 = vx*u0x + vy*u0y;
59
+ // const b4 = ax*ax + ay*ay;
60
+ // const ab = ax*bx + ay*by;
61
+ // const bb = bx*bx + by*by;
62
+ // const u0a = u0x*ax + u0y*ay;
63
+ // const d0 = u0x*bx + u0y*by;
64
+ // const b0 = u0x*u0x + u0y*u0y;
65
+ const c1 = qm2(qaq(qmq(vx,ax),qmq(vy,ay)));
66
+ const c0 = qaq(qmq(vx,bx),qmq(vy,by));
67
+ const vu0 = qaq(qmq(vx,u0x),qmq(vy,u0y));
68
+ const b4 = qaq(qmq(ax,ax),qmq(ay,ay));
69
+ const ab = qaq(qmq(bx,ax),qmq(by,ay));
70
+ const bb = qaq(qmq(bx,bx),qmq(by,by));
71
+ const u0a = qaq(qmq(u0x,ax),qmq(u0y,ay));
72
+ const d0 = qaq(qmq(bx,u0x),qmq(by,u0y));
73
+ const b0 = qaq(qmq(u0x,u0x),qmq(u0y,u0y));
74
+
75
+ // -----------------------------------------------------
76
+ // E1(s,t): (u(s) + t⋅v) ⋅ b'(s) = 0
77
+ // => C(s)⋅t + D(s) = 0
78
+ // -----------------------------------------------------
79
+
80
+ // -----------------------------------------------------
81
+ // const d3 = -2*b4;
82
+ // const d2 = -3*ab;
83
+ // const d1 = 2*u0a - bb;
84
+ const d3 = qmn2(b4);
85
+ const d2 = qmd(-3,ab);
86
+ const d1 = qaq(qm2(u0a),qno(bb));
87
+ // -----------------------------------------------------
88
+
89
+ // -----------------------------------------------------
90
+ // E2(s,t): |t⋅v|² - |u(s) + t⋅v|² = 0
91
+ // => 2⋅(v⋅u(s))⋅t + |u(s)|² = 0
92
+ // => A(s)⋅t + B(s) = 0
93
+ // const a2 = -c1;
94
+ // const a1 = -2*c0;
95
+ // const a0 = 2*vu0;
96
+ const a2 = qno(c1);
97
+ const a1 = qmn2(c0);
98
+ const a0 = qm2(vu0);
99
+ // -----------------------------------------------------
100
+
101
+ // -----------------------------------------------------
102
+ // const b3 = 2*ab;
103
+ // const b2 = -d1;
104
+ // const b1 = -2*d0;
105
+ const b3 = qm2(ab);
106
+ const b2 = qno(d1);
107
+ const b1 = qmn2(d0);
108
+ // -----------------------------------------------------
109
+
110
+
111
+ // Eliminate t from:
112
+ // A(s)⋅t + B(s) = 0
113
+ // C(s)⋅t + D(s) = 0
114
+ // by taking A(s)⋅D(s) - B(s)⋅C(s) = 0 (degree ≤ 5 in s)
115
+
116
+ // Using:
117
+ // a2 = -c1, d3 = -2*b4, d1 = -b2, b1 = -2*d0
118
+ // we can compute H = A⋅D - B⋅C directly.
119
+ // const H5 = b4*c1;
120
+ // const H4 = ab*c1 + 3*b4*c0;
121
+ // const H3 = 4*(ab*c0 - vu0*b4);
122
+ // const H2 = c1*d0 + c0*b2 - 6*vu0*ab;
123
+ // const H1 = -2*vu0*b2 - c1*b0;
124
+ // const H0 = 2*vu0*d0 - c0*b0;
125
+ const H5 = qmq(b4,c1);
126
+ const H4 = qaq(qmq(ab,c1),qmd(3,qmq(b4,c0)));
127
+ const H3 = qm2(qm2(qaq(qmq(ab,c0),qno(qmq(vu0,b4)))));
128
+ const H2 = qaq(qaq(qmq(c1,d0),qmq(c0,b2)),qno(qmd(6,qmq(vu0,ab))));
129
+ const H1 = qaq(qmn2(qmq(vu0,b2)),qno(qmq(c1,b0)));
130
+ const H0 = qaq(qm2(qmq(vu0,d0)),qno(qmq(c0,b0)));
131
+
132
+ return {
133
+ A: [a2, a1, a0],
134
+ B: [b4, b3, b2, b1, b0],
135
+ C: [c1, c0],
136
+ D: [d3, d2, d1, d0],
137
+ H: [H5, H4, H3, H2, H1, H0]
138
+ };
139
+ }
140
+
141
+
142
+ export { ddGetMedialPointCoeffsBez2 }
@@ -0,0 +1,199 @@
1
+ import { toPowerBasisDd } from 'flo-bezier3';
2
+ import { ddMultDouble2, ddAddDd, ddMultDd, ddNegativeOf, ddMultByNeg2, ddMultBy2 } from 'double-double';
3
+
4
+ const qmd = ddMultDouble2;
5
+ const qaq = ddAddDd;
6
+ const qmq = ddMultDd;
7
+ const qno = ddNegativeOf;
8
+ const qmn2 = ddMultByNeg2;
9
+ const qm2 = ddMultBy2;
10
+
11
+
12
+ /**
13
+ * Returns polynomial coefficients for the same-curve cubic medial-point case,
14
+ * where `p = b(t)` on the same cubic bezier `ps` and `v` is normal to the
15
+ * curve at that parameter `t`.
16
+ *
17
+ * The returned coefficients encode:
18
+ * * `A`, `B`: `E2(s, τ) = (s - t)^2⋅(A(s)⋅τ + B(s))`
19
+ * * `C`, `D`: `E1(s, τ) = (s - t)⋅(C(s)⋅τ + D(s))`
20
+ * * `H`: the reduced eliminant in `s`
21
+ *
22
+ * Here `τ` is the ray parameter in `q(τ) = p + τ⋅v`.
23
+ * For a candidate root `s` of `H`, recover `τ` from `A(s)⋅τ + B(s) = 0`, i.e.
24
+ * `τ = -B(s)/A(s)` when `A(s) ≠ 0`.
25
+ *
26
+ * In this same-curve setup, the full eliminant has the form
27
+ * `H_full(s) = (s - t)^4*H(s)`. This function returns only the reduced factor
28
+ * `H(s)` (the repeated `(s - t)^4` factor is omitted).
29
+ *
30
+ * @param t parameter on `ps` where `p = b(t)`
31
+ * @param v ray direction from `p`; assumed normal to `ps` at `t`
32
+ * @param ps order 3 bezier control points, e.g. `[[0,0],[1,1],[2,1],[3,0]]`
33
+ */
34
+ function ddGetMedialPointCoeffsBez3_SameCurve(
35
+ t: number,
36
+ v: number[][],
37
+ ps: number[][]) {
38
+
39
+ // -----------------------------------------------------
40
+ // See get-medial-points.md for implementation details.
41
+ // -----------------------------------------------------
42
+ const [vx, vy] = v;
43
+ // Cubic bezier in power basis: b(s) = a*s^3 + b*s^2 + c*s + d
44
+ const [[ax, bx, cx], [ay, by, cy]] = toPowerBasisDd(ps);
45
+
46
+ // Shared dot products to reduce repeated multiplications.
47
+ // const va = vx*ax + vy*ay;
48
+ // const vb = vx*bx + vy*by;
49
+ // const vc = vx*cx + vy*cy;
50
+ // const aa = ax*ax + ay*ay;
51
+ // const ab = ax*bx + ay*by;
52
+ // const ac = ax*cx + ay*cy;
53
+ // const bb = bx*bx + by*by;
54
+ // const bc = bx*cx + by*cy;
55
+ // const cc = cx*cx + cy*cy;
56
+ // const vu0 = t*(t*(t*va + vb) + vc);
57
+ // const u0a = t*(t*(t*aa + ab) + ac);
58
+ // const u0b = t*(t*(t*ab + bb) + bc);
59
+ const va = qaq(qmq(vx,ax),qmq(vy,ay));
60
+ const vb = qaq(qmq(vx,bx),qmq(vy,by));
61
+ const vc = qaq(qmq(vx,cx),qmq(vy,cy));
62
+ const aa = qaq(qmq(ax,ax),qmq(ay,ay));
63
+ const ab = qaq(qmq(ax,bx),qmq(ay,by));
64
+ const ac = qaq(qmq(ax,cx),qmq(ay,cy));
65
+ const bb = qaq(qmq(bx,bx),qmq(by,by));
66
+ const bc = qaq(qmq(bx,cx),qmq(by,cy));
67
+ const cc = qaq(qmq(cx,cx),qmq(cy,cy));
68
+ const vu0 = qmd(t,qaq(qmd(t,qaq(qmd(t,va),vb)),vc));
69
+ const u0a = qmd(t,qaq(qmd(t,qaq(qmd(t,aa),ab)),ac));
70
+ const u0b = qmd(t,qaq(qmd(t,qaq(qmd(t,ab),bb)),bc));
71
+
72
+ // -----------------------------------------------------
73
+ // E1(s,t): (u(s) + t*v) * b'(s) = 0
74
+ // => C(s)*t + D(s) = 0
75
+ // const c2 = 3*va;
76
+ // const c1 = 2*vb;
77
+ const c2 = qmd(3,va);
78
+ const c1 = qm2(vb);
79
+ // v is normal at parameter t, so C(t) = 0.
80
+ // const c0 = -t*(c2*t + c1);
81
+
82
+ // Return reduced C such that C_full(s) = (s - t)*C(s).
83
+ // const cr0 = c1 + t*c2;
84
+ const cr0 = qaq(c1,qmd(t,c2));
85
+ // -----------------------------------------------------
86
+
87
+ // -----------------------------------------------------
88
+ // const d5 = -3*aa;
89
+ // const d4 = -5*ab;
90
+ // const d3 = -4*ac - 2*bb;
91
+ // const d2 = -3*bc + 3*u0a;
92
+ // const d1 = -cc + 2*u0b;
93
+ const d5 = qmd(-3,aa);
94
+ const d4 = qmd(-5,ab);
95
+ const d3 = qaq(qmd(-4,ac),qmn2(bb));
96
+ const d2 = qaq(qmd(-3,bc),qmd(3,u0a));
97
+ const d1 = qaq(qno(cc),qm2(u0b));
98
+ // p = b(t) => D(t) = u(t)⋅w(t) = 0.
99
+
100
+ // Return reduced D such that D_full(s) = (s - t)*D(s).
101
+ const dr4 = d5;
102
+ // const dr3 = d4 + t*dr4;
103
+ // const dr2 = d3 + t*dr3;
104
+ // const dr1 = d2 + t*dr2;
105
+ // const dr0 = d1 + t*dr1;
106
+ const dr3 = qaq(d4,qmd(t,dr4));
107
+ const dr2 = qaq(d3,qmd(t,dr3));
108
+ const dr1 = qaq(d2,qmd(t,dr2));
109
+ const dr0 = qaq(d1,qmd(t,dr1));
110
+ // -----------------------------------------------------
111
+
112
+ // -----------------------------------------------------
113
+ // E2(s,t): |t*v|^2 - |u(s) + t*v|^2 = 0
114
+ // => 2*(v*u(s))*t + |u(s)|^2 = 0
115
+ // => A(s)*t + B(s) = 0
116
+ // A'(s) = -2*C(s) identically for bezier curves, hence:
117
+ // const a3 = -2*va;
118
+ // const a2 = -2*vb;
119
+ const a3 = qmn2(va);
120
+ const a2 = qmn2(vb);
121
+ // const a1 = -2*vc;
122
+ // p = b(t) => A(t) = 0.
123
+ // const a0 = 2*vu0;
124
+ // -----------------------------------------------------
125
+
126
+ // -----------------------------------------------------
127
+ const b6 = aa;
128
+ // const b5 = 2*ab;
129
+ // const b4 = 2*ac + bb;
130
+ // const b3 = 2*bc - 2*u0a;
131
+ // const b2 = cc - 2*u0b;
132
+ const b5 = qm2(ab);
133
+ const b4 = qaq(qm2(ac),bb);
134
+ const b3 = qaq(qm2(bc),qmn2(u0a));
135
+ const b2 = qaq(cc,qmn2(u0b));
136
+ // -----------------------------------------------------
137
+
138
+ // -----------------------------------------------------
139
+ // Return reduced A and B such that:
140
+ // A_full(s) = (s - t)^2*A(s)
141
+ // B_full(s) = (s - t)^2*B(s)
142
+ // where A is degree 1 and B is degree 4.
143
+ const ar1 = a3;
144
+ // const ar0 = a2 + 2*t*ar1;
145
+ const ar0 = qaq(a2,qm2(qmd(t,ar1)));
146
+
147
+ const br4 = b6;
148
+ // const br3 = b5 + 2*t*br4;
149
+ // const br2 = b4 + t*(2*br3 - t*br4);
150
+ // const br1 = b3 + t*(2*br2 - t*br3);
151
+ // const br0 = b2 + t*(2*br1 - t*br2);
152
+ const br3 = qaq(b5,qm2(qmd(t,br4)));
153
+ const br2 = qaq(b4,qmd(t,qaq(qm2(br3),qno(qmd(t,br4)))));
154
+ const br1 = qaq(b3,qmd(t,qaq(qm2(br2),qno(qmd(t,br3)))));
155
+ const br0 = qaq(b2,qmd(t,qaq(qm2(br1),qno(qmd(t,br2)))));
156
+ // -----------------------------------------------------
157
+
158
+
159
+ // Eliminate t from:
160
+ // A(s)*t + B(s) = 0
161
+ // C(s)*t + D(s) = 0
162
+ // by taking A(s)*D(s) - B(s)*C(s) = 0 (degree <= 8 in s)
163
+
164
+ // H8 = a3*d5 - b6*c2 = (-2*va)*(-3*aa) - aa*(3*va) = 3*va*aa.
165
+ // const H8 = 3*va*aa;
166
+ // const H7 = 4*(va*ab + vb*aa);
167
+ // const H6 = va*b4 + 6*vb*ab + 5*vc*aa;
168
+ // const H5 = 2*vb*b4 + 8*vc*ab - 6*vu0*aa;
169
+ // const H4 = -va*b2 + vb*b3 + 3*vc*b4 - 10*vu0*ab;
170
+ const H8 = qmd(3,qmq(va,aa));
171
+ const H7 = qm2(qm2(qaq(qmq(va,ab),qmq(vb,aa))));
172
+ const H6 = qaq(qaq(qmq(va,b4),qmd(6,qmq(vb,ab))),qmd(5,qmq(vc,aa)));
173
+ const H5 = qaq(qaq(qm2(qmq(vb,b4)),qmd(8,qmq(vc,ab))),qno(qmd(6,qmq(vu0,aa))));
174
+ const H4 = qaq(qaq(qno(qmq(va,b2)),qmq(vb,b3)),qaq(qmd(3,qmq(vc,b4)),qno(qmd(10,qmq(vu0,ab)))));
175
+
176
+ // Reduce H_full(s) by its guaranteed (s - t)^4 factor:
177
+ // H_full(s) = (s - t)^4*(q4*s^4 + q3*s^3 + q2*s^2 + q1*s + q0)
178
+ // Match the high-order coefficients of H_full(s) explicitly.
179
+ const q4 = H8;
180
+ // const q3 = H7 + 4*t*q4;
181
+ // const q2 = H6 + t*(4*q3 - 6*t*q4);
182
+ // const q1 = H5 + t*(4*q2 + t*(-6*q3 + 4*t*q4));
183
+ // const q0 = H4 + t*(4*q1 + t*(-6*q2 + t*(4*q3 - t*q4)));
184
+ const q3 = qaq(H7,qm2(qm2(qmd(t,q4))));
185
+ const q2 = qaq(H6,qmd(t,qaq(qm2(qm2(q3)),qno(qmd(6,qmd(t,q4))))));
186
+ const q1 = qaq(H5,qmd(t,qaq(qm2(qm2(q2)),qmd(t,qaq(qmd(-6,q3),qm2(qm2(qmd(t,q4))))))));
187
+ const q0 = qaq(H4,qmd(t,qaq(qm2(qm2(q1)),qmd(t,qaq(qmd(-6,q2),qmd(t,qaq(qm2(qm2(q3)),qno(qmd(t,q4)))))))));
188
+
189
+ return {
190
+ A: [ar1, ar0],
191
+ B: [br4, br3, br2, br1, br0],
192
+ C: [c2, cr0],
193
+ D: [dr4, dr3, dr2, dr1, dr0],
194
+ H: [q4, q3, q2, q1, q0]
195
+ };
196
+ }
197
+
198
+
199
+ export { ddGetMedialPointCoeffsBez3_SameCurve }