@tldraw/editor 3.16.0-internal.a478398270c6 → 3.16.0-internal.f8b97f0c414f

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 (325) hide show
  1. package/dist-cjs/index.d.ts +350 -142
  2. package/dist-cjs/index.js +13 -6
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/TldrawEditor.js +10 -8
  5. package/dist-cjs/lib/TldrawEditor.js.map +2 -2
  6. package/dist-cjs/lib/components/MenuClickCapture.js +0 -5
  7. package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
  8. package/dist-cjs/lib/components/SVGContainer.js +1 -1
  9. package/dist-cjs/lib/components/SVGContainer.js.map +2 -2
  10. package/dist-cjs/lib/components/Shape.js +11 -36
  11. package/dist-cjs/lib/components/Shape.js.map +2 -2
  12. package/dist-cjs/lib/components/default-components/DefaultBrush.js +1 -1
  13. package/dist-cjs/lib/components/default-components/DefaultBrush.js.map +2 -2
  14. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +15 -24
  15. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  16. package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js +2 -2
  17. package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js.map +2 -2
  18. package/dist-cjs/lib/components/default-components/DefaultCursor.js +1 -1
  19. package/dist-cjs/lib/components/default-components/DefaultCursor.js.map +2 -2
  20. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +1 -1
  21. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
  22. package/dist-cjs/lib/components/default-components/DefaultGrid.js +1 -1
  23. package/dist-cjs/lib/components/default-components/DefaultGrid.js.map +2 -2
  24. package/dist-cjs/lib/components/default-components/DefaultHandles.js +1 -1
  25. package/dist-cjs/lib/components/default-components/DefaultHandles.js.map +2 -2
  26. package/dist-cjs/lib/components/default-components/DefaultScribble.js +1 -1
  27. package/dist-cjs/lib/components/default-components/DefaultScribble.js.map +2 -2
  28. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +9 -1
  29. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
  30. package/dist-cjs/lib/components/default-components/DefaultShapeWrapper.js +53 -0
  31. package/dist-cjs/lib/components/default-components/DefaultShapeWrapper.js.map +7 -0
  32. package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js +1 -1
  33. package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js.map +2 -2
  34. package/dist-cjs/lib/components/default-components/DefaultSpinner.js +27 -15
  35. package/dist-cjs/lib/components/default-components/DefaultSpinner.js.map +3 -3
  36. package/dist-cjs/lib/config/TLUserPreferences.js +15 -3
  37. package/dist-cjs/lib/config/TLUserPreferences.js.map +2 -2
  38. package/dist-cjs/lib/editor/Editor.js +174 -180
  39. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  40. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js +4 -0
  41. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js.map +2 -2
  42. package/dist-cjs/lib/editor/derivations/parentsToChildren.js.map +2 -2
  43. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +14 -4
  44. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
  45. package/dist-cjs/lib/editor/shapes/BaseBoxShapeUtil.js.map +1 -1
  46. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +23 -0
  47. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  48. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.js.map +2 -2
  49. package/dist-cjs/lib/editor/tools/StateNode.js +20 -1
  50. package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
  51. package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
  52. package/dist-cjs/lib/exports/getSvgJsx.js +35 -16
  53. package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
  54. package/dist-cjs/lib/hooks/useCanvasEvents.js +44 -35
  55. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  56. package/dist-cjs/lib/hooks/useDocumentEvents.js +5 -5
  57. package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
  58. package/dist-cjs/lib/hooks/useEditor.js +1 -4
  59. package/dist-cjs/lib/hooks/useEditor.js.map +2 -2
  60. package/dist-cjs/lib/hooks/useEditorComponents.js +2 -0
  61. package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
  62. package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js +1 -2
  63. package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js.map +2 -2
  64. package/dist-cjs/lib/hooks/useGestureEvents.js +1 -1
  65. package/dist-cjs/lib/hooks/useGestureEvents.js.map +2 -2
  66. package/dist-cjs/lib/hooks/useHandleEvents.js +3 -3
  67. package/dist-cjs/lib/hooks/useHandleEvents.js.map +2 -2
  68. package/dist-cjs/lib/hooks/usePassThroughMouseOverEvents.js +4 -1
  69. package/dist-cjs/lib/hooks/usePassThroughMouseOverEvents.js.map +2 -2
  70. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js +4 -1
  71. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +2 -2
  72. package/dist-cjs/lib/hooks/useSelectionEvents.js +4 -4
  73. package/dist-cjs/lib/hooks/useSelectionEvents.js.map +2 -2
  74. package/dist-cjs/lib/{utils/nearestMultiple.js → hooks/useStateAttribute.js} +15 -14
  75. package/dist-cjs/lib/hooks/useStateAttribute.js.map +7 -0
  76. package/dist-cjs/lib/license/LicenseManager.js +140 -53
  77. package/dist-cjs/lib/license/LicenseManager.js.map +2 -2
  78. package/dist-cjs/lib/license/LicenseProvider.js +39 -1
  79. package/dist-cjs/lib/license/LicenseProvider.js.map +2 -2
  80. package/dist-cjs/lib/license/Watermark.js +75 -13
  81. package/dist-cjs/lib/license/Watermark.js.map +3 -3
  82. package/dist-cjs/lib/license/useLicenseManagerState.js.map +2 -2
  83. package/dist-cjs/lib/options.js +7 -0
  84. package/dist-cjs/lib/options.js.map +2 -2
  85. package/dist-cjs/lib/primitives/Box.js +3 -0
  86. package/dist-cjs/lib/primitives/Box.js.map +2 -2
  87. package/dist-cjs/lib/primitives/Vec.js +0 -4
  88. package/dist-cjs/lib/primitives/Vec.js.map +2 -2
  89. package/dist-cjs/lib/primitives/geometry/Arc2d.js +1 -1
  90. package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
  91. package/dist-cjs/lib/primitives/geometry/Circle2d.js +1 -1
  92. package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
  93. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +3 -1
  94. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
  95. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js +1 -1
  96. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
  97. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +50 -20
  98. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
  99. package/dist-cjs/lib/primitives/geometry/Group2d.js +8 -1
  100. package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
  101. package/dist-cjs/lib/primitives/geometry/geometry-constants.js +2 -2
  102. package/dist-cjs/lib/primitives/geometry/geometry-constants.js.map +2 -2
  103. package/dist-cjs/lib/primitives/intersect.js +4 -4
  104. package/dist-cjs/lib/primitives/intersect.js.map +2 -2
  105. package/dist-cjs/lib/primitives/utils.js +4 -0
  106. package/dist-cjs/lib/primitives/utils.js.map +2 -2
  107. package/dist-cjs/lib/utils/EditorAtom.js +45 -0
  108. package/dist-cjs/lib/utils/EditorAtom.js.map +7 -0
  109. package/dist-cjs/lib/utils/dom.js +12 -1
  110. package/dist-cjs/lib/utils/dom.js.map +2 -2
  111. package/dist-cjs/lib/utils/getPointerInfo.js +2 -2
  112. package/dist-cjs/lib/utils/getPointerInfo.js.map +2 -2
  113. package/dist-cjs/lib/utils/reparenting.js +2 -35
  114. package/dist-cjs/lib/utils/reparenting.js.map +3 -3
  115. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +0 -1
  116. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
  117. package/dist-cjs/version.js +3 -3
  118. package/dist-cjs/version.js.map +1 -1
  119. package/dist-esm/index.d.mts +350 -142
  120. package/dist-esm/index.mjs +24 -8
  121. package/dist-esm/index.mjs.map +2 -2
  122. package/dist-esm/lib/TldrawEditor.mjs +11 -9
  123. package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
  124. package/dist-esm/lib/components/MenuClickCapture.mjs +0 -5
  125. package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
  126. package/dist-esm/lib/components/SVGContainer.mjs +1 -1
  127. package/dist-esm/lib/components/SVGContainer.mjs.map +2 -2
  128. package/dist-esm/lib/components/Shape.mjs +11 -36
  129. package/dist-esm/lib/components/Shape.mjs.map +2 -2
  130. package/dist-esm/lib/components/default-components/DefaultBrush.mjs +1 -1
  131. package/dist-esm/lib/components/default-components/DefaultBrush.mjs.map +2 -2
  132. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +16 -25
  133. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  134. package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs +2 -2
  135. package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map +2 -2
  136. package/dist-esm/lib/components/default-components/DefaultCursor.mjs +1 -1
  137. package/dist-esm/lib/components/default-components/DefaultCursor.mjs.map +2 -2
  138. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +1 -1
  139. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
  140. package/dist-esm/lib/components/default-components/DefaultGrid.mjs +1 -1
  141. package/dist-esm/lib/components/default-components/DefaultGrid.mjs.map +2 -2
  142. package/dist-esm/lib/components/default-components/DefaultHandles.mjs +1 -1
  143. package/dist-esm/lib/components/default-components/DefaultHandles.mjs.map +2 -2
  144. package/dist-esm/lib/components/default-components/DefaultScribble.mjs +1 -1
  145. package/dist-esm/lib/components/default-components/DefaultScribble.mjs.map +2 -2
  146. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +9 -1
  147. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
  148. package/dist-esm/lib/components/default-components/DefaultShapeWrapper.mjs +23 -0
  149. package/dist-esm/lib/components/default-components/DefaultShapeWrapper.mjs.map +7 -0
  150. package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs +1 -1
  151. package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs.map +2 -2
  152. package/dist-esm/lib/components/default-components/DefaultSpinner.mjs +17 -15
  153. package/dist-esm/lib/components/default-components/DefaultSpinner.mjs.map +2 -2
  154. package/dist-esm/lib/config/TLUserPreferences.mjs +15 -3
  155. package/dist-esm/lib/config/TLUserPreferences.mjs.map +2 -2
  156. package/dist-esm/lib/editor/Editor.mjs +174 -180
  157. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  158. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs +4 -0
  159. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs.map +2 -2
  160. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs.map +2 -2
  161. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +14 -4
  162. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
  163. package/dist-esm/lib/editor/shapes/BaseBoxShapeUtil.mjs.map +1 -1
  164. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +23 -0
  165. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  166. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.mjs.map +2 -2
  167. package/dist-esm/lib/editor/tools/StateNode.mjs +20 -1
  168. package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
  169. package/dist-esm/lib/exports/getSvgJsx.mjs +36 -16
  170. package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
  171. package/dist-esm/lib/hooks/useCanvasEvents.mjs +47 -37
  172. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  173. package/dist-esm/lib/hooks/useDocumentEvents.mjs +11 -6
  174. package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
  175. package/dist-esm/lib/hooks/useEditor.mjs +1 -4
  176. package/dist-esm/lib/hooks/useEditor.mjs.map +2 -2
  177. package/dist-esm/lib/hooks/useEditorComponents.mjs +4 -0
  178. package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
  179. package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs +2 -3
  180. package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs.map +2 -2
  181. package/dist-esm/lib/hooks/useGestureEvents.mjs +2 -2
  182. package/dist-esm/lib/hooks/useGestureEvents.mjs.map +2 -2
  183. package/dist-esm/lib/hooks/useHandleEvents.mjs +9 -4
  184. package/dist-esm/lib/hooks/useHandleEvents.mjs.map +2 -2
  185. package/dist-esm/lib/hooks/usePassThroughMouseOverEvents.mjs +4 -1
  186. package/dist-esm/lib/hooks/usePassThroughMouseOverEvents.mjs.map +2 -2
  187. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs +4 -1
  188. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +2 -2
  189. package/dist-esm/lib/hooks/useSelectionEvents.mjs +6 -5
  190. package/dist-esm/lib/hooks/useSelectionEvents.mjs.map +2 -2
  191. package/dist-esm/lib/hooks/useStateAttribute.mjs +15 -0
  192. package/dist-esm/lib/hooks/useStateAttribute.mjs.map +7 -0
  193. package/dist-esm/lib/license/LicenseManager.mjs +141 -54
  194. package/dist-esm/lib/license/LicenseManager.mjs.map +2 -2
  195. package/dist-esm/lib/license/LicenseProvider.mjs +39 -2
  196. package/dist-esm/lib/license/LicenseProvider.mjs.map +2 -2
  197. package/dist-esm/lib/license/Watermark.mjs +76 -14
  198. package/dist-esm/lib/license/Watermark.mjs.map +3 -3
  199. package/dist-esm/lib/license/useLicenseManagerState.mjs.map +2 -2
  200. package/dist-esm/lib/options.mjs +7 -0
  201. package/dist-esm/lib/options.mjs.map +2 -2
  202. package/dist-esm/lib/primitives/Box.mjs +4 -1
  203. package/dist-esm/lib/primitives/Box.mjs.map +2 -2
  204. package/dist-esm/lib/primitives/Vec.mjs +0 -4
  205. package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
  206. package/dist-esm/lib/primitives/geometry/Arc2d.mjs +2 -2
  207. package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
  208. package/dist-esm/lib/primitives/geometry/Circle2d.mjs +2 -2
  209. package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
  210. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +3 -1
  211. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
  212. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs +2 -2
  213. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
  214. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +53 -21
  215. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
  216. package/dist-esm/lib/primitives/geometry/Group2d.mjs +8 -1
  217. package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
  218. package/dist-esm/lib/primitives/geometry/geometry-constants.mjs +2 -2
  219. package/dist-esm/lib/primitives/geometry/geometry-constants.mjs.map +2 -2
  220. package/dist-esm/lib/primitives/intersect.mjs +5 -5
  221. package/dist-esm/lib/primitives/intersect.mjs.map +2 -2
  222. package/dist-esm/lib/primitives/utils.mjs +4 -0
  223. package/dist-esm/lib/primitives/utils.mjs.map +2 -2
  224. package/dist-esm/lib/utils/EditorAtom.mjs +25 -0
  225. package/dist-esm/lib/utils/EditorAtom.mjs.map +7 -0
  226. package/dist-esm/lib/utils/dom.mjs +12 -1
  227. package/dist-esm/lib/utils/dom.mjs.map +2 -2
  228. package/dist-esm/lib/utils/getPointerInfo.mjs +2 -2
  229. package/dist-esm/lib/utils/getPointerInfo.mjs.map +2 -2
  230. package/dist-esm/lib/utils/reparenting.mjs +3 -40
  231. package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
  232. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +0 -1
  233. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
  234. package/dist-esm/version.mjs +3 -3
  235. package/dist-esm/version.mjs.map +1 -1
  236. package/editor.css +327 -315
  237. package/package.json +16 -38
  238. package/src/index.ts +19 -10
  239. package/src/lib/TldrawEditor.tsx +16 -21
  240. package/src/lib/components/MenuClickCapture.tsx +0 -8
  241. package/src/lib/components/SVGContainer.tsx +1 -1
  242. package/src/lib/components/Shape.tsx +12 -33
  243. package/src/lib/components/default-components/DefaultBrush.tsx +1 -1
  244. package/src/lib/components/default-components/DefaultCanvas.tsx +13 -24
  245. package/src/lib/components/default-components/DefaultCollaboratorHint.tsx +2 -2
  246. package/src/lib/components/default-components/DefaultCursor.tsx +1 -1
  247. package/src/lib/components/default-components/DefaultErrorFallback.tsx +1 -1
  248. package/src/lib/components/default-components/DefaultGrid.tsx +1 -1
  249. package/src/lib/components/default-components/DefaultHandles.tsx +5 -1
  250. package/src/lib/components/default-components/DefaultScribble.tsx +1 -1
  251. package/src/lib/components/default-components/DefaultShapeIndicator.tsx +6 -2
  252. package/src/lib/components/default-components/DefaultShapeWrapper.tsx +35 -0
  253. package/src/lib/components/default-components/DefaultSnapIndictor.tsx +1 -1
  254. package/src/lib/components/default-components/DefaultSpinner.tsx +12 -12
  255. package/src/lib/config/TLUserPreferences.ts +15 -1
  256. package/src/lib/editor/Editor.test.ts +512 -8
  257. package/src/lib/editor/Editor.ts +252 -267
  258. package/src/lib/editor/derivations/notVisibleShapes.ts +6 -0
  259. package/src/lib/editor/derivations/parentsToChildren.ts +1 -1
  260. package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +15 -14
  261. package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +16 -15
  262. package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +49 -48
  263. package/src/lib/editor/managers/FontManager/FontManager.test.ts +38 -27
  264. package/src/lib/editor/managers/HistoryManager/HistoryManager.test.ts +7 -6
  265. package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +12 -11
  266. package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +57 -50
  267. package/src/lib/editor/managers/TextManager/TextManager.test.ts +51 -26
  268. package/src/lib/editor/managers/TickManager/TickManager.test.ts +14 -13
  269. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +55 -26
  270. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +14 -1
  271. package/src/lib/editor/shapes/BaseBoxShapeUtil.tsx +2 -2
  272. package/src/lib/editor/shapes/ShapeUtil.ts +108 -8
  273. package/src/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.ts +2 -1
  274. package/src/lib/editor/tools/StateNode.test.ts +285 -0
  275. package/src/lib/editor/tools/StateNode.ts +27 -1
  276. package/src/lib/editor/types/misc-types.ts +73 -7
  277. package/src/lib/exports/getSvgJsx.test.ts +874 -0
  278. package/src/lib/exports/getSvgJsx.tsx +78 -21
  279. package/src/lib/hooks/useCanvasEvents.ts +60 -47
  280. package/src/lib/hooks/useDocumentEvents.ts +11 -6
  281. package/src/lib/hooks/useEditor.tsx +6 -5
  282. package/src/lib/hooks/useEditorComponents.tsx +8 -2
  283. package/src/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.ts +2 -2
  284. package/src/lib/hooks/useGestureEvents.ts +2 -2
  285. package/src/lib/hooks/useHandleEvents.ts +9 -4
  286. package/src/lib/hooks/usePassThroughMouseOverEvents.ts +4 -1
  287. package/src/lib/hooks/usePassThroughWheelEvents.ts +6 -1
  288. package/src/lib/hooks/useSelectionEvents.ts +6 -5
  289. package/src/lib/hooks/useStateAttribute.ts +15 -0
  290. package/src/lib/license/LicenseManager.test.ts +724 -383
  291. package/src/lib/license/LicenseManager.ts +201 -58
  292. package/src/lib/license/LicenseProvider.tsx +74 -2
  293. package/src/lib/license/Watermark.test.tsx +2 -1
  294. package/src/lib/license/Watermark.tsx +81 -14
  295. package/src/lib/license/useLicenseManagerState.ts +2 -2
  296. package/src/lib/options.ts +8 -0
  297. package/src/lib/primitives/Box.test.ts +126 -0
  298. package/src/lib/primitives/Box.ts +10 -1
  299. package/src/lib/primitives/Vec.ts +0 -5
  300. package/src/lib/primitives/geometry/Arc2d.ts +2 -2
  301. package/src/lib/primitives/geometry/Circle2d.ts +2 -2
  302. package/src/lib/primitives/geometry/CubicBezier2d.ts +4 -1
  303. package/src/lib/primitives/geometry/Ellipse2d.ts +2 -2
  304. package/src/lib/primitives/geometry/Geometry2d.test.ts +420 -0
  305. package/src/lib/primitives/geometry/Geometry2d.ts +78 -21
  306. package/src/lib/primitives/geometry/Group2d.ts +10 -1
  307. package/src/lib/primitives/geometry/geometry-constants.ts +2 -1
  308. package/src/lib/primitives/intersect.test.ts +946 -0
  309. package/src/lib/primitives/intersect.ts +12 -5
  310. package/src/lib/primitives/utils.ts +11 -0
  311. package/src/lib/test/InFrontOfTheCanvas.test.tsx +187 -0
  312. package/src/lib/utils/EditorAtom.ts +37 -0
  313. package/src/lib/utils/dom.test.ts +94 -0
  314. package/src/lib/utils/dom.ts +38 -1
  315. package/src/lib/utils/getPointerInfo.ts +2 -1
  316. package/src/lib/utils/reparenting.ts +3 -69
  317. package/src/lib/utils/sync/LocalIndexedDb.test.ts +2 -1
  318. package/src/lib/utils/sync/TLLocalSyncClient.test.ts +15 -15
  319. package/src/lib/utils/sync/TLLocalSyncClient.ts +0 -1
  320. package/src/version.ts +3 -3
  321. package/dist-cjs/lib/utils/nearestMultiple.js.map +0 -7
  322. package/dist-esm/lib/utils/nearestMultiple.mjs +0 -14
  323. package/dist-esm/lib/utils/nearestMultiple.mjs.map +0 -7
  324. package/src/lib/test/currentToolIdMask.test.ts +0 -49
  325. package/src/lib/utils/nearestMultiple.ts +0 -13
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Arc2d.ts"],
4
- "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { intersectLineSegmentCircle } from '../intersect'\nimport { getArcMeasure, getPointInArcT, getPointOnCircle } from '../utils'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForLength } from './geometry-constants'\n\n/** @public */\nexport class Arc2d extends Geometry2d {\n\tprivate _center: Vec\n\tprivate _radius: number\n\tprivate _start: Vec\n\tprivate _end: Vec\n\tprivate _largeArcFlag: number\n\tprivate _sweepFlag: number\n\tprivate _measure: number\n\tprivate _angleStart: number\n\tprivate _angleEnd: number\n\n\tconstructor(\n\t\tconfig: Omit<Geometry2dOptions, 'isFilled' | 'isClosed'> & {\n\t\t\tcenter: Vec\n\t\t\tstart: Vec\n\t\t\tend: Vec\n\t\t\tsweepFlag: number\n\t\t\tlargeArcFlag: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isFilled: false, isClosed: false })\n\t\tconst { center, sweepFlag, largeArcFlag, start, end } = config\n\t\tif (start.equals(end)) throw Error(`Arc must have different start and end points.`)\n\n\t\t// ensure that the start and end are clockwise\n\t\tthis._angleStart = Vec.Angle(center, start)\n\t\tthis._angleEnd = Vec.Angle(center, end)\n\t\tthis._radius = Vec.Dist(center, start)\n\t\tthis._measure = getArcMeasure(this._angleStart, this._angleEnd, sweepFlag, largeArcFlag)\n\n\t\tthis._start = start\n\t\tthis._end = end\n\n\t\tthis._sweepFlag = sweepFlag\n\t\tthis._largeArcFlag = largeArcFlag\n\t\tthis._center = center\n\t}\n\n\tnearestPoint(point: VecLike): Vec {\n\t\tconst {\n\t\t\t_center,\n\t\t\t_measure: measure,\n\t\t\t_radius: radius,\n\t\t\t_angleEnd: angleEnd,\n\t\t\t_angleStart: angleStart,\n\t\t\t_start: A,\n\t\t\t_end: B,\n\t\t} = this\n\t\tconst t = getPointInArcT(measure, angleStart, angleEnd, _center.angle(point))\n\t\tif (t <= 0) return A\n\t\tif (t >= 1) return B\n\n\t\t// Get the point (P) on the arc, then pick the nearest of A, B, and P\n\t\tconst P = Vec.Sub(point, _center).uni().mul(radius).add(_center)\n\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tfor (const p of [A, B, P]) {\n\t\t\td = Vec.Dist2(point, p)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\tconst {\n\t\t\t_center,\n\t\t\t_radius: radius,\n\t\t\t_measure: measure,\n\t\t\t_angleStart: angleStart,\n\t\t\t_angleEnd: angleEnd,\n\t\t} = this\n\t\tconst intersection = intersectLineSegmentCircle(A, B, _center, radius)\n\t\tif (intersection === null) return false\n\n\t\treturn intersection.some((p) => {\n\t\t\tconst result = getPointInArcT(measure, angleStart, angleEnd, _center.angle(p))\n\t\t\treturn result >= 0 && result <= 1\n\t\t})\n\t}\n\n\tgetVertices(): Vec[] {\n\t\tconst { _center, _measure: measure, length, _radius: radius, _angleStart: angleStart } = this\n\t\tconst vertices: Vec[] = []\n\t\tfor (let i = 0, n = getVerticesCountForLength(Math.abs(length)); i < n + 1; i++) {\n\t\t\tconst t = (i / n) * measure\n\t\t\tconst angle = angleStart + t\n\t\t\tvertices.push(getPointOnCircle(_center, radius, angle))\n\t\t}\n\t\treturn vertices\n\t}\n\n\tgetSvgPathData(first = true) {\n\t\tconst {\n\t\t\t_start: start,\n\t\t\t_end: end,\n\t\t\t_radius: radius,\n\t\t\t_largeArcFlag: largeArcFlag,\n\t\t\t_sweepFlag: sweepFlag,\n\t\t} = this\n\t\treturn `${first ? `M${start.toFixed()}` : ``} A${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${end.toFixed()}`\n\t}\n\n\toverride getLength() {\n\t\treturn Math.abs(this._measure * this._radius)\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { intersectLineSegmentCircle } from '../intersect'\nimport { getArcMeasure, getPointInArcT, getPointOnCircle } from '../utils'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForArcLength } from './geometry-constants'\n\n/** @public */\nexport class Arc2d extends Geometry2d {\n\tprivate _center: Vec\n\tprivate _radius: number\n\tprivate _start: Vec\n\tprivate _end: Vec\n\tprivate _largeArcFlag: number\n\tprivate _sweepFlag: number\n\tprivate _measure: number\n\tprivate _angleStart: number\n\tprivate _angleEnd: number\n\n\tconstructor(\n\t\tconfig: Omit<Geometry2dOptions, 'isFilled' | 'isClosed'> & {\n\t\t\tcenter: Vec\n\t\t\tstart: Vec\n\t\t\tend: Vec\n\t\t\tsweepFlag: number\n\t\t\tlargeArcFlag: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isFilled: false, isClosed: false })\n\t\tconst { center, sweepFlag, largeArcFlag, start, end } = config\n\t\tif (start.equals(end)) throw Error(`Arc must have different start and end points.`)\n\n\t\t// ensure that the start and end are clockwise\n\t\tthis._angleStart = Vec.Angle(center, start)\n\t\tthis._angleEnd = Vec.Angle(center, end)\n\t\tthis._radius = Vec.Dist(center, start)\n\t\tthis._measure = getArcMeasure(this._angleStart, this._angleEnd, sweepFlag, largeArcFlag)\n\n\t\tthis._start = start\n\t\tthis._end = end\n\n\t\tthis._sweepFlag = sweepFlag\n\t\tthis._largeArcFlag = largeArcFlag\n\t\tthis._center = center\n\t}\n\n\tnearestPoint(point: VecLike): Vec {\n\t\tconst {\n\t\t\t_center,\n\t\t\t_measure: measure,\n\t\t\t_radius: radius,\n\t\t\t_angleEnd: angleEnd,\n\t\t\t_angleStart: angleStart,\n\t\t\t_start: A,\n\t\t\t_end: B,\n\t\t} = this\n\t\tconst t = getPointInArcT(measure, angleStart, angleEnd, _center.angle(point))\n\t\tif (t <= 0) return A\n\t\tif (t >= 1) return B\n\n\t\t// Get the point (P) on the arc, then pick the nearest of A, B, and P\n\t\tconst P = Vec.Sub(point, _center).uni().mul(radius).add(_center)\n\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tfor (const p of [A, B, P]) {\n\t\t\td = Vec.Dist2(point, p)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\tconst {\n\t\t\t_center,\n\t\t\t_radius: radius,\n\t\t\t_measure: measure,\n\t\t\t_angleStart: angleStart,\n\t\t\t_angleEnd: angleEnd,\n\t\t} = this\n\t\tconst intersection = intersectLineSegmentCircle(A, B, _center, radius)\n\t\tif (intersection === null) return false\n\n\t\treturn intersection.some((p) => {\n\t\t\tconst result = getPointInArcT(measure, angleStart, angleEnd, _center.angle(p))\n\t\t\treturn result >= 0 && result <= 1\n\t\t})\n\t}\n\n\tgetVertices(): Vec[] {\n\t\tconst { _center, _measure: measure, length, _radius: radius, _angleStart: angleStart } = this\n\t\tconst vertices: Vec[] = []\n\t\tfor (let i = 0, n = getVerticesCountForArcLength(Math.abs(length)); i < n + 1; i++) {\n\t\t\tconst t = (i / n) * measure\n\t\t\tconst angle = angleStart + t\n\t\t\tvertices.push(getPointOnCircle(_center, radius, angle))\n\t\t}\n\t\treturn vertices\n\t}\n\n\tgetSvgPathData(first = true) {\n\t\tconst {\n\t\t\t_start: start,\n\t\t\t_end: end,\n\t\t\t_radius: radius,\n\t\t\t_largeArcFlag: largeArcFlag,\n\t\t\t_sweepFlag: sweepFlag,\n\t\t} = this\n\t\treturn `${first ? `M${start.toFixed()}` : ``} A${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${end.toFixed()}`\n\t}\n\n\toverride getLength() {\n\t\treturn Math.abs(this._measure * this._radius)\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -48,7 +48,7 @@ class Circle2d extends import_Geometry2d.Geometry2d {
48
48
  const { _center, _radius: radius } = this;
49
49
  const perimeter = import_utils.PI2 * radius;
50
50
  const vertices = [];
51
- for (let i = 0, n = (0, import_geometry_constants.getVerticesCountForLength)(perimeter); i < n; i++) {
51
+ for (let i = 0, n = (0, import_geometry_constants.getVerticesCountForArcLength)(perimeter); i < n; i++) {
52
52
  const angle = i / n * import_utils.PI2;
53
53
  vertices.push((0, import_utils.getPointOnCircle)(_center, radius, angle));
54
54
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Circle2d.ts"],
4
- "sourcesContent": ["import { Box } from '../Box'\nimport { Vec, VecLike } from '../Vec'\nimport { intersectLineSegmentCircle } from '../intersect'\nimport { PI2, getPointOnCircle } from '../utils'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForLength } from './geometry-constants'\n\n/** @public */\nexport class Circle2d extends Geometry2d {\n\tprivate _center: Vec\n\tprivate _radius: number\n\tprivate _x: number\n\tprivate _y: number\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\tx?: number\n\t\t\ty?: number\n\t\t\tradius: number\n\t\t\tisFilled: boolean\n\t\t}\n\t) {\n\t\tsuper({ isClosed: true, ...config })\n\t\tconst { x = 0, y = 0, radius } = config\n\t\tthis._x = x\n\t\tthis._y = y\n\t\tthis._center = new Vec(radius + x, radius + y)\n\t\tthis._radius = radius\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(this._x, this._y, this._radius * 2, this._radius * 2)\n\t}\n\n\tgetVertices(): Vec[] {\n\t\tconst { _center, _radius: radius } = this\n\t\tconst perimeter = PI2 * radius\n\t\tconst vertices: Vec[] = []\n\t\tfor (let i = 0, n = getVerticesCountForLength(perimeter); i < n; i++) {\n\t\t\tconst angle = (i / n) * PI2\n\t\t\tvertices.push(getPointOnCircle(_center, radius, angle))\n\t\t}\n\t\treturn vertices\n\t}\n\n\tnearestPoint(point: VecLike): Vec {\n\t\tconst { _center, _radius: radius } = this\n\t\tif (_center.equals(point)) return Vec.AddXY(_center, radius, 0)\n\t\treturn Vec.Sub(point, _center).uni().mul(radius).add(_center)\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike, distance = 0): boolean {\n\t\tconst { _center, _radius: radius } = this\n\t\treturn intersectLineSegmentCircle(A, B, _center, radius + distance) !== null\n\t}\n\n\tgetSvgPathData(): string {\n\t\tconst { _center, _radius: radius } = this\n\t\treturn `M${_center.x + radius},${_center.y} a${radius},${radius} 0 1,0 ${radius * 2},0a${radius},${radius} 0 1,0 -${radius * 2},0`\n\t}\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAoB;AACpB,iBAA6B;AAC7B,uBAA2C;AAC3C,mBAAsC;AACtC,wBAA8C;AAC9C,gCAA0C;AAGnC,MAAM,iBAAiB,6BAAW;AAAA,EAMxC,YACQ,QAMN;AACD,UAAM,EAAE,UAAU,MAAM,GAAG,OAAO,CAAC;AAP5B;AAQP,UAAM,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,IAAI;AACjC,SAAK,KAAK;AACV,SAAK,KAAK;AACV,SAAK,UAAU,IAAI,eAAI,SAAS,GAAG,SAAS,CAAC;AAC7C,SAAK,UAAU;AAAA,EAChB;AAAA,EAnBQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAkBR,YAAY;AACX,WAAO,IAAI,eAAI,KAAK,IAAI,KAAK,IAAI,KAAK,UAAU,GAAG,KAAK,UAAU,CAAC;AAAA,EACpE;AAAA,EAEA,cAAqB;AACpB,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,UAAM,YAAY,mBAAM;AACxB,UAAM,WAAkB,CAAC;AACzB,aAAS,IAAI,GAAG,QAAI,qDAA0B,SAAS,GAAG,IAAI,GAAG,KAAK;AACrE,YAAM,QAAS,IAAI,IAAK;AACxB,eAAS,SAAK,+BAAiB,SAAS,QAAQ,KAAK,CAAC;AAAA,IACvD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,aAAa,OAAqB;AACjC,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,QAAI,QAAQ,OAAO,KAAK,EAAG,QAAO,eAAI,MAAM,SAAS,QAAQ,CAAC;AAC9D,WAAO,eAAI,IAAI,OAAO,OAAO,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,IAAI,OAAO;AAAA,EAC7D;AAAA,EAEA,mBAAmB,GAAY,GAAY,WAAW,GAAY;AACjE,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,eAAO,6CAA2B,GAAG,GAAG,SAAS,SAAS,QAAQ,MAAM;AAAA,EACzE;AAAA,EAEA,iBAAyB;AACxB,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,WAAO,IAAI,QAAQ,IAAI,MAAM,IAAI,QAAQ,CAAC,KAAK,MAAM,IAAI,MAAM,UAAU,SAAS,CAAC,MAAM,MAAM,IAAI,MAAM,WAAW,SAAS,CAAC;AAAA,EAC/H;AACD;",
4
+ "sourcesContent": ["import { Box } from '../Box'\nimport { Vec, VecLike } from '../Vec'\nimport { intersectLineSegmentCircle } from '../intersect'\nimport { PI2, getPointOnCircle } from '../utils'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForArcLength } from './geometry-constants'\n\n/** @public */\nexport class Circle2d extends Geometry2d {\n\tprivate _center: Vec\n\tprivate _radius: number\n\tprivate _x: number\n\tprivate _y: number\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\tx?: number\n\t\t\ty?: number\n\t\t\tradius: number\n\t\t\tisFilled: boolean\n\t\t}\n\t) {\n\t\tsuper({ isClosed: true, ...config })\n\t\tconst { x = 0, y = 0, radius } = config\n\t\tthis._x = x\n\t\tthis._y = y\n\t\tthis._center = new Vec(radius + x, radius + y)\n\t\tthis._radius = radius\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(this._x, this._y, this._radius * 2, this._radius * 2)\n\t}\n\n\tgetVertices(): Vec[] {\n\t\tconst { _center, _radius: radius } = this\n\t\tconst perimeter = PI2 * radius\n\t\tconst vertices: Vec[] = []\n\t\tfor (let i = 0, n = getVerticesCountForArcLength(perimeter); i < n; i++) {\n\t\t\tconst angle = (i / n) * PI2\n\t\t\tvertices.push(getPointOnCircle(_center, radius, angle))\n\t\t}\n\t\treturn vertices\n\t}\n\n\tnearestPoint(point: VecLike): Vec {\n\t\tconst { _center, _radius: radius } = this\n\t\tif (_center.equals(point)) return Vec.AddXY(_center, radius, 0)\n\t\treturn Vec.Sub(point, _center).uni().mul(radius).add(_center)\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike, distance = 0): boolean {\n\t\tconst { _center, _radius: radius } = this\n\t\treturn intersectLineSegmentCircle(A, B, _center, radius + distance) !== null\n\t}\n\n\tgetSvgPathData(): string {\n\t\tconst { _center, _radius: radius } = this\n\t\treturn `M${_center.x + radius},${_center.y} a${radius},${radius} 0 1,0 ${radius * 2},0a${radius},${radius} 0 1,0 -${radius * 2},0`\n\t}\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAoB;AACpB,iBAA6B;AAC7B,uBAA2C;AAC3C,mBAAsC;AACtC,wBAA8C;AAC9C,gCAA6C;AAGtC,MAAM,iBAAiB,6BAAW;AAAA,EAMxC,YACQ,QAMN;AACD,UAAM,EAAE,UAAU,MAAM,GAAG,OAAO,CAAC;AAP5B;AAQP,UAAM,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,IAAI;AACjC,SAAK,KAAK;AACV,SAAK,KAAK;AACV,SAAK,UAAU,IAAI,eAAI,SAAS,GAAG,SAAS,CAAC;AAC7C,SAAK,UAAU;AAAA,EAChB;AAAA,EAnBQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAkBR,YAAY;AACX,WAAO,IAAI,eAAI,KAAK,IAAI,KAAK,IAAI,KAAK,UAAU,GAAG,KAAK,UAAU,CAAC;AAAA,EACpE;AAAA,EAEA,cAAqB;AACpB,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,UAAM,YAAY,mBAAM;AACxB,UAAM,WAAkB,CAAC;AACzB,aAAS,IAAI,GAAG,QAAI,wDAA6B,SAAS,GAAG,IAAI,GAAG,KAAK;AACxE,YAAM,QAAS,IAAI,IAAK;AACxB,eAAS,SAAK,+BAAiB,SAAS,QAAQ,KAAK,CAAC;AAAA,IACvD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,aAAa,OAAqB;AACjC,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,QAAI,QAAQ,OAAO,KAAK,EAAG,QAAO,eAAI,MAAM,SAAS,QAAQ,CAAC;AAC9D,WAAO,eAAI,IAAI,OAAO,OAAO,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,IAAI,OAAO;AAAA,EAC7D;AAAA,EAEA,mBAAmB,GAAY,GAAY,WAAW,GAAY;AACjE,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,eAAO,6CAA2B,GAAG,GAAG,SAAS,SAAS,QAAQ,MAAM;AAAA,EACzE;AAAA,EAEA,iBAAyB;AACxB,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,WAAO,IAAI,QAAQ,IAAI,MAAM,IAAI,QAAQ,CAAC,KAAK,MAAM,IAAI,MAAM,UAAU,SAAS,CAAC,MAAM,MAAM,IAAI,MAAM,WAAW,SAAS,CAAC;AAAA,EAC/H;AACD;",
6
6
  "names": []
7
7
  }
@@ -28,6 +28,7 @@ class CubicBezier2d extends import_Polyline2d.Polyline2d {
28
28
  _b;
29
29
  _c;
30
30
  _d;
31
+ _resolution;
31
32
  constructor(config) {
32
33
  const { start: a, cp1: b, cp2: c, end: d } = config;
33
34
  super({ ...config, points: [a, d] });
@@ -35,11 +36,12 @@ class CubicBezier2d extends import_Polyline2d.Polyline2d {
35
36
  this._b = b;
36
37
  this._c = c;
37
38
  this._d = d;
39
+ this._resolution = config.resolution ?? 10;
38
40
  }
39
41
  getVertices() {
40
42
  const vertices = [];
41
43
  const { _a: a, _b: b, _c: c, _d: d } = this;
42
- for (let i = 0, n = 10; i <= n; i++) {
44
+ for (let i = 0, n = this._resolution; i <= n; i++) {
43
45
  const t = i / n;
44
46
  vertices.push(
45
47
  new import_Vec.Vec(
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/CubicBezier2d.ts"],
4
- "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { Geometry2dFilters, Geometry2dOptions } from './Geometry2d'\nimport { Polyline2d } from './Polyline2d'\n\n/** @public */\nexport class CubicBezier2d extends Polyline2d {\n\tprivate _a: Vec\n\tprivate _b: Vec\n\tprivate _c: Vec\n\tprivate _d: Vec\n\n\tconstructor(\n\t\tconfig: Omit<Geometry2dOptions, 'isFilled' | 'isClosed'> & {\n\t\t\tstart: Vec\n\t\t\tcp1: Vec\n\t\t\tcp2: Vec\n\t\t\tend: Vec\n\t\t}\n\t) {\n\t\tconst { start: a, cp1: b, cp2: c, end: d } = config\n\t\tsuper({ ...config, points: [a, d] })\n\n\t\tthis._a = a\n\t\tthis._b = b\n\t\tthis._c = c\n\t\tthis._d = d\n\t}\n\n\toverride getVertices() {\n\t\tconst vertices = [] as Vec[]\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\t// we'll always use ten vertices for each bezier curve\n\t\tfor (let i = 0, n = 10; i <= n; i++) {\n\t\t\tconst t = i / n\n\t\t\tvertices.push(\n\t\t\t\tnew Vec(\n\t\t\t\t\t(1 - t) * (1 - t) * (1 - t) * a.x +\n\t\t\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.x +\n\t\t\t\t\t\t3 * (1 - t) * (t * t) * c.x +\n\t\t\t\t\t\tt * t * t * d.x,\n\t\t\t\t\t(1 - t) * (1 - t) * (1 - t) * a.y +\n\t\t\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.y +\n\t\t\t\t\t\t3 * (1 - t) * (t * t) * c.y +\n\t\t\t\t\t\tt * t * t * d.y\n\t\t\t\t)\n\t\t\t)\n\t\t}\n\t\treturn vertices\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tlet p: Vec\n\t\tfor (const edge of this.segments) {\n\t\t\tp = edge.nearestPoint(A)\n\t\t\td = Vec.Dist2(p, A)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\tgetSvgPathData(first = true) {\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\treturn `${first ? `M ${a.toFixed()} ` : ``} C${b.toFixed()} ${c.toFixed()} ${d.toFixed()}`\n\t}\n\n\tstatic GetAtT(segment: CubicBezier2d, t: number) {\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = segment\n\t\treturn new Vec(\n\t\t\t(1 - t) * (1 - t) * (1 - t) * a.x +\n\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.x +\n\t\t\t\t3 * (1 - t) * (t * t) * c.x +\n\t\t\t\tt * t * t * d.x,\n\t\t\t(1 - t) * (1 - t) * (1 - t) * a.y +\n\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.y +\n\t\t\t\t3 * (1 - t) * (t * t) * c.y +\n\t\t\t\tt * t * t * d.y\n\t\t)\n\t}\n\n\toverride getLength(_filters?: Geometry2dFilters, precision = 32) {\n\t\tlet n1: Vec,\n\t\t\tp1 = this._a,\n\t\t\tlength = 0\n\t\tfor (let i = 1; i <= precision; i++) {\n\t\t\tn1 = CubicBezier2d.GetAtT(this, i / precision)\n\t\t\tlength += Vec.Dist(p1, n1)\n\t\t\tp1 = n1\n\t\t}\n\t\treturn length\n\t}\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAA6B;AAE7B,wBAA2B;AAGpB,MAAM,sBAAsB,6BAAW;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YACC,QAMC;AACD,UAAM,EAAE,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI;AAC7C,UAAM,EAAE,GAAG,QAAQ,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;AAEnC,SAAK,KAAK;AACV,SAAK,KAAK;AACV,SAAK,KAAK;AACV,SAAK,KAAK;AAAA,EACX;AAAA,EAES,cAAc;AACtB,UAAM,WAAW,CAAC;AAClB,UAAM,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,IAAI;AAEvC,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK,GAAG,KAAK;AACpC,YAAM,IAAI,IAAI;AACd,eAAS;AAAA,QACR,IAAI;AAAA,WACF,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE,IAC/B,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,EAAE,IAChC,KAAK,IAAI,MAAM,IAAI,KAAK,EAAE,IAC1B,IAAI,IAAI,IAAI,EAAE;AAAA,WACd,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE,IAC/B,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,EAAE,IAChC,KAAK,IAAI,MAAM,IAAI,KAAK,EAAE,IAC1B,IAAI,IAAI,IAAI,EAAE;AAAA,QAChB;AAAA,MACD;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,aAAa,GAAiB;AAC7B,QAAI;AACJ,QAAI,OAAO;AACX,QAAI;AACJ,QAAI;AACJ,eAAW,QAAQ,KAAK,UAAU;AACjC,UAAI,KAAK,aAAa,CAAC;AACvB,UAAI,eAAI,MAAM,GAAG,CAAC;AAClB,UAAI,IAAI,MAAM;AACb,kBAAU;AACV,eAAO;AAAA,MACR;AAAA,IACD;AAEA,QAAI,CAAC,QAAS,OAAM,MAAM,yBAAyB;AACnD,WAAO;AAAA,EACR;AAAA,EAEA,eAAe,QAAQ,MAAM;AAC5B,UAAM,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,IAAI;AACvC,WAAO,GAAG,QAAQ,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;AAAA,EACzF;AAAA,EAEA,OAAO,OAAO,SAAwB,GAAW;AAChD,UAAM,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,IAAI;AACvC,WAAO,IAAI;AAAA,OACT,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE,IAC/B,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,EAAE,IAChC,KAAK,IAAI,MAAM,IAAI,KAAK,EAAE,IAC1B,IAAI,IAAI,IAAI,EAAE;AAAA,OACd,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE,IAC/B,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,EAAE,IAChC,KAAK,IAAI,MAAM,IAAI,KAAK,EAAE,IAC1B,IAAI,IAAI,IAAI,EAAE;AAAA,IAChB;AAAA,EACD;AAAA,EAES,UAAU,UAA8B,YAAY,IAAI;AAChE,QAAI,IACH,KAAK,KAAK,IACV,SAAS;AACV,aAAS,IAAI,GAAG,KAAK,WAAW,KAAK;AACpC,WAAK,cAAc,OAAO,MAAM,IAAI,SAAS;AAC7C,gBAAU,eAAI,KAAK,IAAI,EAAE;AACzB,WAAK;AAAA,IACN;AACA,WAAO;AAAA,EACR;AACD;",
4
+ "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { Geometry2dFilters, Geometry2dOptions } from './Geometry2d'\nimport { Polyline2d } from './Polyline2d'\n\n/** @public */\nexport class CubicBezier2d extends Polyline2d {\n\tprivate _a: Vec\n\tprivate _b: Vec\n\tprivate _c: Vec\n\tprivate _d: Vec\n\tprivate _resolution: number\n\n\tconstructor(\n\t\tconfig: Omit<Geometry2dOptions, 'isFilled' | 'isClosed'> & {\n\t\t\tstart: Vec\n\t\t\tcp1: Vec\n\t\t\tcp2: Vec\n\t\t\tend: Vec\n\t\t\tresolution?: number\n\t\t}\n\t) {\n\t\tconst { start: a, cp1: b, cp2: c, end: d } = config\n\t\tsuper({ ...config, points: [a, d] })\n\n\t\tthis._a = a\n\t\tthis._b = b\n\t\tthis._c = c\n\t\tthis._d = d\n\t\tthis._resolution = config.resolution ?? 10\n\t}\n\n\toverride getVertices() {\n\t\tconst vertices = [] as Vec[]\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\t// we'll always use ten vertices for each bezier curve\n\t\tfor (let i = 0, n = this._resolution; i <= n; i++) {\n\t\t\tconst t = i / n\n\t\t\tvertices.push(\n\t\t\t\tnew Vec(\n\t\t\t\t\t(1 - t) * (1 - t) * (1 - t) * a.x +\n\t\t\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.x +\n\t\t\t\t\t\t3 * (1 - t) * (t * t) * c.x +\n\t\t\t\t\t\tt * t * t * d.x,\n\t\t\t\t\t(1 - t) * (1 - t) * (1 - t) * a.y +\n\t\t\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.y +\n\t\t\t\t\t\t3 * (1 - t) * (t * t) * c.y +\n\t\t\t\t\t\tt * t * t * d.y\n\t\t\t\t)\n\t\t\t)\n\t\t}\n\t\treturn vertices\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tlet p: Vec\n\t\tfor (const edge of this.segments) {\n\t\t\tp = edge.nearestPoint(A)\n\t\t\td = Vec.Dist2(p, A)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\tgetSvgPathData(first = true) {\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\treturn `${first ? `M ${a.toFixed()} ` : ``} C${b.toFixed()} ${c.toFixed()} ${d.toFixed()}`\n\t}\n\n\tstatic GetAtT(segment: CubicBezier2d, t: number) {\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = segment\n\t\treturn new Vec(\n\t\t\t(1 - t) * (1 - t) * (1 - t) * a.x +\n\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.x +\n\t\t\t\t3 * (1 - t) * (t * t) * c.x +\n\t\t\t\tt * t * t * d.x,\n\t\t\t(1 - t) * (1 - t) * (1 - t) * a.y +\n\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.y +\n\t\t\t\t3 * (1 - t) * (t * t) * c.y +\n\t\t\t\tt * t * t * d.y\n\t\t)\n\t}\n\n\toverride getLength(_filters?: Geometry2dFilters, precision = 32) {\n\t\tlet n1: Vec,\n\t\t\tp1 = this._a,\n\t\t\tlength = 0\n\t\tfor (let i = 1; i <= precision; i++) {\n\t\t\tn1 = CubicBezier2d.GetAtT(this, i / precision)\n\t\t\tlength += Vec.Dist(p1, n1)\n\t\t\tp1 = n1\n\t\t}\n\t\treturn length\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -58,7 +58,7 @@ class Ellipse2d extends import_Geometry2d.Geometry2d {
58
58
  const cy = h / 2;
59
59
  const q = Math.pow(cx - cy, 2) / Math.pow(cx + cy, 2);
60
60
  const p = import_utils.PI * (cx + cy) * (1 + 3 * q / (10 + Math.sqrt(4 - 3 * q)));
61
- const len = (0, import_geometry_constants.getVerticesCountForLength)(p);
61
+ const len = (0, import_geometry_constants.getVerticesCountForArcLength)(p);
62
62
  const step = import_utils.PI2 / len;
63
63
  const a = Math.cos(step);
64
64
  const b = Math.sin(step);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Ellipse2d.ts"],
4
- "sourcesContent": ["import { Box } from '../Box'\nimport { Vec, VecLike } from '../Vec'\nimport { PI, PI2, clamp, perimeterOfEllipse } from '../utils'\nimport { Edge2d } from './Edge2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForLength } from './geometry-constants'\n\n/** @public */\nexport class Ellipse2d extends Geometry2d {\n\tprivate _w: number\n\tprivate _h: number\n\tprivate _edges?: Edge2d[]\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\twidth: number\n\t\t\theight: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isClosed: true })\n\t\tconst { width, height } = config\n\t\tthis._w = width\n\t\tthis._h = height\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget edges() {\n\t\tif (!this._edges) {\n\t\t\tconst { vertices } = this\n\t\t\tthis._edges = []\n\t\t\tfor (let i = 0, n = vertices.length; i < n; i++) {\n\t\t\t\tconst start = vertices[i]\n\t\t\t\tconst end = vertices[(i + 1) % n]\n\t\t\t\tthis._edges.push(new Edge2d({ start, end }))\n\t\t\t}\n\t\t}\n\n\t\treturn this._edges\n\t}\n\n\tgetVertices() {\n\t\t// Perimeter of the ellipse\n\t\tconst w = Math.max(1, this._w)\n\t\tconst h = Math.max(1, this._h)\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst q = Math.pow(cx - cy, 2) / Math.pow(cx + cy, 2)\n\t\tconst p = PI * (cx + cy) * (1 + (3 * q) / (10 + Math.sqrt(4 - 3 * q)))\n\t\t// Number of points\n\t\tconst len = getVerticesCountForLength(p)\n\t\t// Size of step\n\t\tconst step = PI2 / len\n\n\t\tconst a = Math.cos(step)\n\t\tconst b = Math.sin(step)\n\n\t\tlet sin = 0\n\t\tlet cos = 1\n\t\tlet ts = 0\n\t\tlet tc = 1\n\n\t\tconst vertices = Array(len)\n\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tvertices[i] = new Vec(clamp(cx + cx * cos, 0, w), clamp(cy + cy * sin, 0, h))\n\t\t\tts = b * cos + a * sin\n\t\t\ttc = a * cos - b * sin\n\t\t\tsin = ts\n\t\t\tcos = tc\n\t\t}\n\n\t\treturn vertices\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tlet p: Vec\n\t\tfor (const edge of this.edges) {\n\t\t\tp = edge.nearestPoint(A)\n\t\t\td = Vec.Dist2(p, A)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\treturn this.edges.some((edge) => edge.hitTestLineSegment(A, B))\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(0, 0, this._w, this._h)\n\t}\n\n\tgetLength(): number {\n\t\tconst { _w: w, _h: h } = this\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst rx = Math.max(0, cx)\n\t\tconst ry = Math.max(0, cy)\n\t\treturn perimeterOfEllipse(rx, ry)\n\t}\n\n\tgetSvgPathData(first = false) {\n\t\tconst { _w: w, _h: h } = this\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst rx = Math.max(0, cx)\n\t\tconst ry = Math.max(0, cy)\n\t\treturn `${first ? `M${cx - rx},${cy}` : ``} a${rx},${ry},0,1,1,${rx * 2},0a${rx},${ry},0,1,1,-${rx * 2},0`\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box } from '../Box'\nimport { Vec, VecLike } from '../Vec'\nimport { PI, PI2, clamp, perimeterOfEllipse } from '../utils'\nimport { Edge2d } from './Edge2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForArcLength } from './geometry-constants'\n\n/** @public */\nexport class Ellipse2d extends Geometry2d {\n\tprivate _w: number\n\tprivate _h: number\n\tprivate _edges?: Edge2d[]\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\twidth: number\n\t\t\theight: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isClosed: true })\n\t\tconst { width, height } = config\n\t\tthis._w = width\n\t\tthis._h = height\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget edges() {\n\t\tif (!this._edges) {\n\t\t\tconst { vertices } = this\n\t\t\tthis._edges = []\n\t\t\tfor (let i = 0, n = vertices.length; i < n; i++) {\n\t\t\t\tconst start = vertices[i]\n\t\t\t\tconst end = vertices[(i + 1) % n]\n\t\t\t\tthis._edges.push(new Edge2d({ start, end }))\n\t\t\t}\n\t\t}\n\n\t\treturn this._edges\n\t}\n\n\tgetVertices() {\n\t\t// Perimeter of the ellipse\n\t\tconst w = Math.max(1, this._w)\n\t\tconst h = Math.max(1, this._h)\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst q = Math.pow(cx - cy, 2) / Math.pow(cx + cy, 2)\n\t\tconst p = PI * (cx + cy) * (1 + (3 * q) / (10 + Math.sqrt(4 - 3 * q)))\n\t\t// Number of points\n\t\tconst len = getVerticesCountForArcLength(p)\n\t\t// Size of step\n\t\tconst step = PI2 / len\n\n\t\tconst a = Math.cos(step)\n\t\tconst b = Math.sin(step)\n\n\t\tlet sin = 0\n\t\tlet cos = 1\n\t\tlet ts = 0\n\t\tlet tc = 1\n\n\t\tconst vertices = Array(len)\n\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tvertices[i] = new Vec(clamp(cx + cx * cos, 0, w), clamp(cy + cy * sin, 0, h))\n\t\t\tts = b * cos + a * sin\n\t\t\ttc = a * cos - b * sin\n\t\t\tsin = ts\n\t\t\tcos = tc\n\t\t}\n\n\t\treturn vertices\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tlet p: Vec\n\t\tfor (const edge of this.edges) {\n\t\t\tp = edge.nearestPoint(A)\n\t\t\td = Vec.Dist2(p, A)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\treturn this.edges.some((edge) => edge.hitTestLineSegment(A, B))\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(0, 0, this._w, this._h)\n\t}\n\n\tgetLength(): number {\n\t\tconst { _w: w, _h: h } = this\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst rx = Math.max(0, cx)\n\t\tconst ry = Math.max(0, cy)\n\t\treturn perimeterOfEllipse(rx, ry)\n\t}\n\n\tgetSvgPathData(first = false) {\n\t\tconst { _w: w, _h: h } = this\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst rx = Math.max(0, cx)\n\t\tconst ry = Math.max(0, cy)\n\t\treturn `${first ? `M${cx - rx},${cy}` : ``} a${rx},${ry},0,1,1,${rx * 2},0a${rx},${ry},0,1,1,-${rx * 2},0`\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -45,10 +45,16 @@ class Geometry2d {
45
45
  isLabel = false;
46
46
  isEmptyLabel = false;
47
47
  isInternal = false;
48
+ excludeFromShapeBounds = false;
48
49
  debugColor;
49
50
  ignore;
50
51
  constructor(opts) {
51
- const { isLabel = false, isEmptyLabel = false, isInternal = false } = opts;
52
+ const {
53
+ isLabel = false,
54
+ isEmptyLabel = false,
55
+ isInternal = false,
56
+ excludeFromShapeBounds = false
57
+ } = opts;
52
58
  this.isFilled = opts.isFilled;
53
59
  this.isClosed = opts.isClosed;
54
60
  this.debugColor = opts.debugColor;
@@ -56,6 +62,7 @@ class Geometry2d {
56
62
  this.isLabel = isLabel;
57
63
  this.isEmptyLabel = isEmptyLabel;
58
64
  this.isInternal = isInternal;
65
+ this.excludeFromShapeBounds = excludeFromShapeBounds;
59
66
  }
60
67
  isExcludedByFilter(filters) {
61
68
  if (!filters) return false;
@@ -166,28 +173,36 @@ class Geometry2d {
166
173
  const distanceAlongRoute = closestSegment.distanceToStart + import_Vec.Vec.Dist(closestSegment.start, closestSegment.nearestPoint);
167
174
  return distanceAlongRoute / length;
168
175
  }
169
- /** @deprecated Iterate the vertices instead. */
170
- nearestPointOnLineSegment(A, B) {
171
- const { vertices } = this;
172
- let nearest;
173
- let dist = Infinity;
174
- let d, p, q;
175
- for (let i = 0; i < vertices.length; i++) {
176
- p = vertices[i];
177
- q = import_Vec.Vec.NearestPointOnLineSegment(A, B, p, true);
178
- d = import_Vec.Vec.Dist2(p, q);
179
- if (d < dist) {
180
- dist = d;
181
- nearest = q;
182
- }
183
- }
184
- if (!nearest) throw Error("nearest point not found");
185
- return nearest;
186
- }
187
176
  isPointInBounds(point, margin = 0) {
188
177
  const { bounds } = this;
189
178
  return !(point.x < bounds.minX - margin || point.y < bounds.minY - margin || point.x > bounds.maxX + margin || point.y > bounds.maxY + margin);
190
179
  }
180
+ overlapsPolygon(_polygon) {
181
+ const polygon = _polygon.map((v) => import_Vec.Vec.From(v));
182
+ const { vertices, center, isFilled, isEmptyLabel, isClosed } = this;
183
+ if (isEmptyLabel) return false;
184
+ if (vertices.some((v) => (0, import_utils2.pointInPolygon)(v, polygon))) {
185
+ return true;
186
+ }
187
+ if (isClosed) {
188
+ if (isFilled) {
189
+ if ((0, import_utils2.pointInPolygon)(center, polygon)) {
190
+ return true;
191
+ }
192
+ if (polygon.every((v) => (0, import_utils2.pointInPolygon)(v, vertices))) {
193
+ return true;
194
+ }
195
+ }
196
+ if ((0, import_intersect.polygonsIntersect)(polygon, vertices)) {
197
+ return true;
198
+ }
199
+ } else {
200
+ if ((0, import_intersect.polygonIntersectsPolyline)(polygon, vertices)) {
201
+ return true;
202
+ }
203
+ }
204
+ return false;
205
+ }
191
206
  transform(transform, opts) {
192
207
  return new TransformedGeometry2d(this, transform, opts);
193
208
  }
@@ -199,8 +214,20 @@ class Geometry2d {
199
214
  }
200
215
  return this._vertices;
201
216
  }
217
+ getBoundsVertices() {
218
+ if (this.excludeFromShapeBounds) return [];
219
+ return this.vertices;
220
+ }
221
+ _boundsVertices;
222
+ // eslint-disable-next-line no-restricted-syntax
223
+ get boundsVertices() {
224
+ if (!this._boundsVertices) {
225
+ this._boundsVertices = this.getBoundsVertices();
226
+ }
227
+ return this._boundsVertices;
228
+ }
202
229
  getBounds() {
203
- return import_Box.Box.FromPoints(this.vertices);
230
+ return import_Box.Box.FromPoints(this.boundsVertices);
204
231
  }
205
232
  _bounds;
206
233
  // eslint-disable-next-line no-restricted-syntax
@@ -295,6 +322,9 @@ class TransformedGeometry2d extends Geometry2d {
295
322
  getVertices(filters) {
296
323
  return this.geometry.getVertices(filters).map((v) => import_Mat.Mat.applyToPoint(this.matrix, v));
297
324
  }
325
+ getBoundsVertices() {
326
+ return this.geometry.getBoundsVertices().map((v) => import_Mat.Mat.applyToPoint(this.matrix, v));
327
+ }
298
328
  nearestPoint(point, filters) {
299
329
  return import_Mat.Mat.applyToPoint(
300
330
  this.matrix,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Geometry2d.ts"],
4
- "sourcesContent": ["import { assert, invLerp } from '@tldraw/utils'\nimport { Box } from '../Box'\nimport { Mat, MatModel } from '../Mat'\nimport { Vec, VecLike } from '../Vec'\nimport {\n\tintersectCirclePolygon,\n\tintersectCirclePolyline,\n\tintersectLineSegmentPolygon,\n\tintersectLineSegmentPolyline,\n\tintersectPolys,\n\tlinesIntersect,\n} from '../intersect'\nimport { approximately, pointInPolygon } from '../utils'\n\n/**\n * Filter geometry within a group.\n *\n * Filters are ignored when called directly on primitive geometries, but can be used to narrow down\n * the results of an operation on `Group2d` geometries.\n *\n * @public\n */\nexport interface Geometry2dFilters {\n\treadonly includeLabels?: boolean\n\treadonly includeInternal?: boolean\n}\n\n/** @public */\nexport const Geometry2dFilters: {\n\tEXCLUDE_NON_STANDARD: Geometry2dFilters\n\tINCLUDE_ALL: Geometry2dFilters\n\tEXCLUDE_LABELS: Geometry2dFilters\n\tEXCLUDE_INTERNAL: Geometry2dFilters\n} = {\n\tEXCLUDE_NON_STANDARD: {\n\t\tincludeLabels: false,\n\t\tincludeInternal: false,\n\t},\n\tINCLUDE_ALL: { includeLabels: true, includeInternal: true },\n\tEXCLUDE_LABELS: { includeLabels: false, includeInternal: true },\n\tEXCLUDE_INTERNAL: { includeLabels: true, includeInternal: false },\n}\n\n/** @public */\nexport interface TransformedGeometry2dOptions {\n\tisLabel?: boolean\n\tisEmptyLabel?: boolean\n\tisInternal?: boolean\n\tdebugColor?: string\n\tignore?: boolean\n}\n\n/** @public */\nexport interface Geometry2dOptions extends TransformedGeometry2dOptions {\n\tisFilled: boolean\n\tisClosed: boolean\n}\n\n/** @public */\nexport abstract class Geometry2d {\n\t// todo: consider making accessors for these too, so that they can be overridden in subclasses by geometries with more complex logic\n\tisFilled = false\n\tisClosed = true\n\tisLabel = false\n\tisEmptyLabel = false\n\tisInternal = false\n\tdebugColor?: string\n\tignore?: boolean\n\n\tconstructor(opts: Geometry2dOptions) {\n\t\tconst { isLabel = false, isEmptyLabel = false, isInternal = false } = opts\n\t\tthis.isFilled = opts.isFilled\n\t\tthis.isClosed = opts.isClosed\n\t\tthis.debugColor = opts.debugColor\n\t\tthis.ignore = opts.ignore\n\t\tthis.isLabel = isLabel\n\t\tthis.isEmptyLabel = isEmptyLabel\n\t\tthis.isInternal = isInternal\n\t}\n\n\tisExcludedByFilter(filters?: Geometry2dFilters) {\n\t\tif (!filters) return false\n\t\tif (this.isLabel && !filters.includeLabels) return true\n\t\tif (this.isInternal && !filters.includeInternal) return true\n\t\treturn false\n\t}\n\n\tabstract getVertices(filters: Geometry2dFilters): Vec[]\n\n\tabstract nearestPoint(point: VecLike, _filters?: Geometry2dFilters): Vec\n\n\thitTestPoint(point: VecLike, margin = 0, hitInside = false, _filters?: Geometry2dFilters) {\n\t\t// First check whether the point is inside\n\t\tif (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)) {\n\t\t\treturn true\n\t\t}\n\t\t// Then check whether the distance is within the margin\n\t\treturn Vec.Dist2(point, this.nearestPoint(point)) <= margin * margin\n\t}\n\n\tdistanceToPoint(point: VecLike, hitInside = false, filters?: Geometry2dFilters) {\n\t\treturn (\n\t\t\tVec.Dist(point, this.nearestPoint(point, filters)) *\n\t\t\t(this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)\n\t\t\t\t? -1\n\t\t\t\t: 1)\n\t\t)\n\t}\n\n\tdistanceToLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {\n\t\tif (Vec.Equals(A, B)) return this.distanceToPoint(A, false, filters)\n\t\tconst { vertices } = this\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number, p: Vec, q: Vec\n\t\tconst nextLimit = this.isClosed ? vertices.length : vertices.length - 1\n\t\tfor (let i = 0; i < vertices.length; i++) {\n\t\t\tp = vertices[i]\n\t\t\tif (i < nextLimit) {\n\t\t\t\tconst next = vertices[(i + 1) % vertices.length]\n\t\t\t\tif (linesIntersect(A, B, p, next)) return 0\n\t\t\t}\n\t\t\tq = Vec.NearestPointOnLineSegment(A, B, p, true)\n\t\t\td = Vec.Dist2(p, q)\n\t\t\tif (d < dist) {\n\t\t\t\tdist = d\n\t\t\t\tnearest = q\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn this.isClosed && this.isFilled && pointInPolygon(nearest, this.vertices) ? -dist : dist\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike, distance = 0, filters?: Geometry2dFilters): boolean {\n\t\treturn this.distanceToLineSegment(A, B, filters) <= distance\n\t}\n\n\tintersectLineSegment(A: VecLike, B: VecLike, _filters?: Geometry2dFilters): VecLike[] {\n\t\tconst intersections = this.isClosed\n\t\t\t? intersectLineSegmentPolygon(A, B, this.vertices)\n\t\t\t: intersectLineSegmentPolyline(A, B, this.vertices)\n\n\t\treturn intersections ?? []\n\t}\n\n\tintersectCircle(center: VecLike, radius: number, _filters?: Geometry2dFilters): VecLike[] {\n\t\tconst intersections = this.isClosed\n\t\t\t? intersectCirclePolygon(center, radius, this.vertices)\n\t\t\t: intersectCirclePolyline(center, radius, this.vertices)\n\n\t\treturn intersections ?? []\n\t}\n\n\tintersectPolygon(polygon: VecLike[], _filters?: Geometry2dFilters): VecLike[] {\n\t\treturn intersectPolys(polygon, this.vertices, true, this.isClosed)\n\t}\n\n\tintersectPolyline(polyline: VecLike[], _filters?: Geometry2dFilters): VecLike[] {\n\t\treturn intersectPolys(polyline, this.vertices, false, this.isClosed)\n\t}\n\n\t/**\n\t * Find a point along the edge of the geometry that is a fraction `t` along the entire way round.\n\t */\n\tinterpolateAlongEdge(t: number, _filters?: Geometry2dFilters): Vec {\n\t\tconst { vertices } = this\n\n\t\tif (t <= 0) return vertices[0]\n\n\t\tconst distanceToTravel = t * this.length\n\t\tlet distanceTraveled = 0\n\n\t\tfor (let i = 0; i < (this.isClosed ? vertices.length : vertices.length - 1); i++) {\n\t\t\tconst curr = vertices[i]\n\t\t\tconst next = vertices[(i + 1) % vertices.length]\n\t\t\tconst dist = Vec.Dist(curr, next)\n\t\t\tconst newDistanceTraveled = distanceTraveled + dist\n\t\t\tif (newDistanceTraveled >= distanceToTravel) {\n\t\t\t\tconst p = Vec.Lrp(\n\t\t\t\t\tcurr,\n\t\t\t\t\tnext,\n\t\t\t\t\tinvLerp(distanceTraveled, newDistanceTraveled, distanceToTravel)\n\t\t\t\t)\n\t\t\t\treturn p\n\t\t\t}\n\t\t\tdistanceTraveled = newDistanceTraveled\n\t\t}\n\n\t\treturn this.isClosed ? vertices[0] : vertices[vertices.length - 1]\n\t}\n\n\t/**\n\t * Take `point`, find the closest point to it on the edge of the geometry, and return how far\n\t * along the edge it is as a fraction of the total length.\n\t */\n\tuninterpolateAlongEdge(point: VecLike, _filters?: Geometry2dFilters): number {\n\t\tconst { vertices, length } = this\n\t\tlet closestSegment = null\n\t\tlet closestDistance = Infinity\n\t\tlet distanceTraveled = 0\n\n\t\tfor (let i = 0; i < (this.isClosed ? vertices.length : vertices.length - 1); i++) {\n\t\t\tconst curr = vertices[i]\n\t\t\tconst next = vertices[(i + 1) % vertices.length]\n\n\t\t\tconst nearestPoint = Vec.NearestPointOnLineSegment(curr, next, point, true)\n\t\t\tconst distance = Vec.Dist(nearestPoint, point)\n\n\t\t\tif (distance < closestDistance) {\n\t\t\t\tclosestDistance = distance\n\t\t\t\tclosestSegment = {\n\t\t\t\t\tstart: curr,\n\t\t\t\t\tend: next,\n\t\t\t\t\tnearestPoint,\n\t\t\t\t\tdistanceToStart: distanceTraveled,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdistanceTraveled += Vec.Dist(curr, next)\n\t\t}\n\n\t\tassert(closestSegment)\n\n\t\tconst distanceAlongRoute =\n\t\t\tclosestSegment.distanceToStart + Vec.Dist(closestSegment.start, closestSegment.nearestPoint)\n\n\t\treturn distanceAlongRoute / length\n\t}\n\n\t/** @deprecated Iterate the vertices instead. */\n\tnearestPointOnLineSegment(A: VecLike, B: VecLike): Vec {\n\t\tconst { vertices } = this\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number, p: Vec, q: Vec\n\t\tfor (let i = 0; i < vertices.length; i++) {\n\t\t\tp = vertices[i]\n\t\t\tq = Vec.NearestPointOnLineSegment(A, B, p, true)\n\t\t\td = Vec.Dist2(p, q)\n\t\t\tif (d < dist) {\n\t\t\t\tdist = d\n\t\t\t\tnearest = q\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\tisPointInBounds(point: VecLike, margin = 0) {\n\t\tconst { bounds } = this\n\t\treturn !(\n\t\t\tpoint.x < bounds.minX - margin ||\n\t\t\tpoint.y < bounds.minY - margin ||\n\t\t\tpoint.x > bounds.maxX + margin ||\n\t\t\tpoint.y > bounds.maxY + margin\n\t\t)\n\t}\n\n\ttransform(transform: MatModel, opts?: TransformedGeometry2dOptions): Geometry2d {\n\t\treturn new TransformedGeometry2d(this, transform, opts)\n\t}\n\n\tprivate _vertices: Vec[] | undefined\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget vertices(): Vec[] {\n\t\tif (!this._vertices) {\n\t\t\tthis._vertices = this.getVertices(Geometry2dFilters.EXCLUDE_LABELS)\n\t\t}\n\n\t\treturn this._vertices\n\t}\n\n\tgetBounds() {\n\t\treturn Box.FromPoints(this.vertices)\n\t}\n\n\tprivate _bounds: Box | undefined\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget bounds(): Box {\n\t\tif (!this._bounds) {\n\t\t\tthis._bounds = this.getBounds()\n\t\t}\n\t\treturn this._bounds\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget center() {\n\t\treturn this.bounds.center\n\t}\n\n\tprivate _area: number | undefined\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget area() {\n\t\tif (!this._area) {\n\t\t\tthis._area = this.getArea()\n\t\t}\n\t\treturn this._area\n\t}\n\n\tgetArea() {\n\t\tif (!this.isClosed) {\n\t\t\treturn 0\n\t\t}\n\t\tconst { vertices } = this\n\t\tlet area = 0\n\t\tfor (let i = 0, n = vertices.length; i < n; i++) {\n\t\t\tconst curr = vertices[i]\n\t\t\tconst next = vertices[(i + 1) % n]\n\t\t\tarea += curr.x * next.y - next.x * curr.y\n\t\t}\n\t\treturn area / 2\n\t}\n\n\ttoSimpleSvgPath() {\n\t\tlet path = ''\n\n\t\tconst { vertices } = this\n\t\tconst n = vertices.length\n\n\t\tif (n === 0) return path\n\n\t\tpath += `M${vertices[0].x},${vertices[0].y}`\n\n\t\tfor (let i = 1; i < n; i++) {\n\t\t\tpath += `L${vertices[i].x},${vertices[i].y}`\n\t\t}\n\n\t\tif (this.isClosed) {\n\t\t\tpath += 'Z'\n\t\t}\n\n\t\treturn path\n\t}\n\n\tprivate _length?: number\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget length() {\n\t\tif (this._length) return this._length\n\t\tthis._length = this.getLength(Geometry2dFilters.EXCLUDE_LABELS)\n\t\treturn this._length\n\t}\n\n\tgetLength(_filters?: Geometry2dFilters) {\n\t\tconst vertices = this.getVertices(_filters ?? Geometry2dFilters.EXCLUDE_LABELS)\n\t\tif (vertices.length === 0) return 0\n\t\tlet prev = vertices[0]\n\t\tlet length = 0\n\t\tfor (let i = 1; i < vertices.length; i++) {\n\t\t\tconst next = vertices[i]\n\t\t\tlength += Vec.Dist(prev, next)\n\t\t\tprev = next\n\t\t}\n\t\tif (this.isClosed) {\n\t\t\tlength += Vec.Dist(vertices[vertices.length - 1], vertices[0])\n\t\t}\n\t\treturn length\n\t}\n\n\tabstract getSvgPathData(first: boolean): string\n}\n\n// =================================================================================================\n// Because Geometry2d.transform depends on TransformedGeometry2d, we need to define it here instead\n// of in its own files. This prevents a circular import error.\n// =================================================================================================\n\n/** @public */\nexport class TransformedGeometry2d extends Geometry2d {\n\tprivate readonly inverse: MatModel\n\tprivate readonly decomposed\n\n\tconstructor(\n\t\tprivate readonly geometry: Geometry2d,\n\t\tprivate readonly matrix: MatModel,\n\t\topts?: TransformedGeometry2dOptions\n\t) {\n\t\tsuper(geometry)\n\t\tthis.inverse = Mat.Inverse(matrix)\n\t\tthis.decomposed = Mat.Decompose(matrix)\n\n\t\tif (opts) {\n\t\t\tif (opts.isLabel != null) this.isLabel = opts.isLabel\n\t\t\tif (opts.isInternal != null) this.isInternal = opts.isInternal\n\t\t\tif (opts.debugColor != null) this.debugColor = opts.debugColor\n\t\t\tif (opts.ignore != null) this.ignore = opts.ignore\n\t\t}\n\n\t\tassert(\n\t\t\tapproximately(this.decomposed.scaleX, this.decomposed.scaleY),\n\t\t\t'non-uniform scaling is not yet supported'\n\t\t)\n\t}\n\n\tgetVertices(filters: Geometry2dFilters): Vec[] {\n\t\treturn this.geometry.getVertices(filters).map((v) => Mat.applyToPoint(this.matrix, v))\n\t}\n\n\tnearestPoint(point: VecLike, filters?: Geometry2dFilters): Vec {\n\t\treturn Mat.applyToPoint(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.nearestPoint(Mat.applyToPoint(this.inverse, point), filters)\n\t\t)\n\t}\n\n\toverride hitTestPoint(\n\t\tpoint: VecLike,\n\t\tmargin = 0,\n\t\thitInside?: boolean,\n\t\tfilters?: Geometry2dFilters\n\t): boolean {\n\t\treturn this.geometry.hitTestPoint(\n\t\t\tMat.applyToPoint(this.inverse, point),\n\t\t\tmargin / this.decomposed.scaleX,\n\t\t\thitInside,\n\t\t\tfilters\n\t\t)\n\t}\n\n\toverride distanceToPoint(point: VecLike, hitInside = false, filters?: Geometry2dFilters) {\n\t\treturn (\n\t\t\tthis.geometry.distanceToPoint(Mat.applyToPoint(this.inverse, point), hitInside, filters) *\n\t\t\tthis.decomposed.scaleX\n\t\t)\n\t}\n\n\toverride distanceToLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {\n\t\treturn (\n\t\t\tthis.geometry.distanceToLineSegment(\n\t\t\t\tMat.applyToPoint(this.inverse, A),\n\t\t\t\tMat.applyToPoint(this.inverse, B),\n\t\t\t\tfilters\n\t\t\t) * this.decomposed.scaleX\n\t\t)\n\t}\n\n\toverride hitTestLineSegment(\n\t\tA: VecLike,\n\t\tB: VecLike,\n\t\tdistance = 0,\n\t\tfilters?: Geometry2dFilters\n\t): boolean {\n\t\treturn this.geometry.hitTestLineSegment(\n\t\t\tMat.applyToPoint(this.inverse, A),\n\t\t\tMat.applyToPoint(this.inverse, B),\n\t\t\tdistance / this.decomposed.scaleX,\n\t\t\tfilters\n\t\t)\n\t}\n\n\toverride intersectLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {\n\t\treturn Mat.applyToPoints(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.intersectLineSegment(\n\t\t\t\tMat.applyToPoint(this.inverse, A),\n\t\t\t\tMat.applyToPoint(this.inverse, B),\n\t\t\t\tfilters\n\t\t\t)\n\t\t)\n\t}\n\n\toverride intersectCircle(center: VecLike, radius: number, filters?: Geometry2dFilters) {\n\t\treturn Mat.applyToPoints(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.intersectCircle(\n\t\t\t\tMat.applyToPoint(this.inverse, center),\n\t\t\t\tradius / this.decomposed.scaleX,\n\t\t\t\tfilters\n\t\t\t)\n\t\t)\n\t}\n\n\toverride intersectPolygon(polygon: VecLike[], filters?: Geometry2dFilters): VecLike[] {\n\t\treturn Mat.applyToPoints(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.intersectPolygon(Mat.applyToPoints(this.inverse, polygon), filters)\n\t\t)\n\t}\n\n\toverride intersectPolyline(polyline: VecLike[], filters?: Geometry2dFilters): VecLike[] {\n\t\treturn Mat.applyToPoints(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.intersectPolyline(Mat.applyToPoints(this.inverse, polyline), filters)\n\t\t)\n\t}\n\n\toverride transform(transform: MatModel, opts?: TransformedGeometry2dOptions): Geometry2d {\n\t\treturn new TransformedGeometry2d(this.geometry, Mat.Multiply(transform, this.matrix), {\n\t\t\tisLabel: opts?.isLabel ?? this.isLabel,\n\t\t\tisInternal: opts?.isInternal ?? this.isInternal,\n\t\t\tdebugColor: opts?.debugColor ?? this.debugColor,\n\t\t\tignore: opts?.ignore ?? this.ignore,\n\t\t})\n\t}\n\n\tgetSvgPathData(): string {\n\t\tthrow new Error('Cannot get SVG path data for transformed geometry.')\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { assert, invLerp } from '@tldraw/utils'\nimport { Box } from '../Box'\nimport { Mat, MatModel } from '../Mat'\nimport { Vec, VecLike } from '../Vec'\nimport {\n\tintersectCirclePolygon,\n\tintersectCirclePolyline,\n\tintersectLineSegmentPolygon,\n\tintersectLineSegmentPolyline,\n\tintersectPolys,\n\tlinesIntersect,\n\tpolygonIntersectsPolyline,\n\tpolygonsIntersect,\n} from '../intersect'\nimport { approximately, pointInPolygon } from '../utils'\n\n/**\n * Filter geometry within a group.\n *\n * Filters are ignored when called directly on primitive geometries, but can be used to narrow down\n * the results of an operation on `Group2d` geometries.\n *\n * @public\n */\nexport interface Geometry2dFilters {\n\treadonly includeLabels?: boolean\n\treadonly includeInternal?: boolean\n}\n\n/** @public */\nexport const Geometry2dFilters: {\n\tEXCLUDE_NON_STANDARD: Geometry2dFilters\n\tINCLUDE_ALL: Geometry2dFilters\n\tEXCLUDE_LABELS: Geometry2dFilters\n\tEXCLUDE_INTERNAL: Geometry2dFilters\n} = {\n\tEXCLUDE_NON_STANDARD: {\n\t\tincludeLabels: false,\n\t\tincludeInternal: false,\n\t},\n\tINCLUDE_ALL: { includeLabels: true, includeInternal: true },\n\tEXCLUDE_LABELS: { includeLabels: false, includeInternal: true },\n\tEXCLUDE_INTERNAL: { includeLabels: true, includeInternal: false },\n}\n\n/** @public */\nexport interface TransformedGeometry2dOptions {\n\tisLabel?: boolean\n\tisEmptyLabel?: boolean\n\tisInternal?: boolean\n\tdebugColor?: string\n\tignore?: boolean\n\texcludeFromShapeBounds?: boolean\n}\n\n/** @public */\nexport interface Geometry2dOptions extends TransformedGeometry2dOptions {\n\tisFilled: boolean\n\tisClosed: boolean\n}\n\n/** @public */\nexport abstract class Geometry2d {\n\t// todo: consider making accessors for these too, so that they can be overridden in subclasses by geometries with more complex logic\n\tisFilled = false\n\tisClosed = true\n\tisLabel = false\n\tisEmptyLabel = false\n\tisInternal = false\n\texcludeFromShapeBounds = false\n\tdebugColor?: string\n\tignore?: boolean\n\n\tconstructor(opts: Geometry2dOptions) {\n\t\tconst {\n\t\t\tisLabel = false,\n\t\t\tisEmptyLabel = false,\n\t\t\tisInternal = false,\n\t\t\texcludeFromShapeBounds = false,\n\t\t} = opts\n\t\tthis.isFilled = opts.isFilled\n\t\tthis.isClosed = opts.isClosed\n\t\tthis.debugColor = opts.debugColor\n\t\tthis.ignore = opts.ignore\n\t\tthis.isLabel = isLabel\n\t\tthis.isEmptyLabel = isEmptyLabel\n\t\tthis.isInternal = isInternal\n\t\tthis.excludeFromShapeBounds = excludeFromShapeBounds\n\t}\n\n\tisExcludedByFilter(filters?: Geometry2dFilters) {\n\t\tif (!filters) return false\n\t\tif (this.isLabel && !filters.includeLabels) return true\n\t\tif (this.isInternal && !filters.includeInternal) return true\n\t\treturn false\n\t}\n\n\tabstract getVertices(filters: Geometry2dFilters): Vec[]\n\n\tabstract nearestPoint(point: VecLike, _filters?: Geometry2dFilters): Vec\n\n\thitTestPoint(point: VecLike, margin = 0, hitInside = false, _filters?: Geometry2dFilters) {\n\t\t// First check whether the point is inside\n\t\tif (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)) {\n\t\t\treturn true\n\t\t}\n\t\t// Then check whether the distance is within the margin\n\t\treturn Vec.Dist2(point, this.nearestPoint(point)) <= margin * margin\n\t}\n\n\tdistanceToPoint(point: VecLike, hitInside = false, filters?: Geometry2dFilters) {\n\t\treturn (\n\t\t\tVec.Dist(point, this.nearestPoint(point, filters)) *\n\t\t\t(this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)\n\t\t\t\t? -1\n\t\t\t\t: 1)\n\t\t)\n\t}\n\n\tdistanceToLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {\n\t\tif (Vec.Equals(A, B)) return this.distanceToPoint(A, false, filters)\n\t\tconst { vertices } = this\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number, p: Vec, q: Vec\n\t\tconst nextLimit = this.isClosed ? vertices.length : vertices.length - 1\n\t\tfor (let i = 0; i < vertices.length; i++) {\n\t\t\tp = vertices[i]\n\t\t\tif (i < nextLimit) {\n\t\t\t\tconst next = vertices[(i + 1) % vertices.length]\n\t\t\t\tif (linesIntersect(A, B, p, next)) return 0\n\t\t\t}\n\t\t\tq = Vec.NearestPointOnLineSegment(A, B, p, true)\n\t\t\td = Vec.Dist2(p, q)\n\t\t\tif (d < dist) {\n\t\t\t\tdist = d\n\t\t\t\tnearest = q\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn this.isClosed && this.isFilled && pointInPolygon(nearest, this.vertices) ? -dist : dist\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike, distance = 0, filters?: Geometry2dFilters): boolean {\n\t\treturn this.distanceToLineSegment(A, B, filters) <= distance\n\t}\n\n\tintersectLineSegment(A: VecLike, B: VecLike, _filters?: Geometry2dFilters): VecLike[] {\n\t\tconst intersections = this.isClosed\n\t\t\t? intersectLineSegmentPolygon(A, B, this.vertices)\n\t\t\t: intersectLineSegmentPolyline(A, B, this.vertices)\n\n\t\treturn intersections ?? []\n\t}\n\n\tintersectCircle(center: VecLike, radius: number, _filters?: Geometry2dFilters): VecLike[] {\n\t\tconst intersections = this.isClosed\n\t\t\t? intersectCirclePolygon(center, radius, this.vertices)\n\t\t\t: intersectCirclePolyline(center, radius, this.vertices)\n\n\t\treturn intersections ?? []\n\t}\n\n\tintersectPolygon(polygon: VecLike[], _filters?: Geometry2dFilters): VecLike[] {\n\t\treturn intersectPolys(polygon, this.vertices, true, this.isClosed)\n\t}\n\n\tintersectPolyline(polyline: VecLike[], _filters?: Geometry2dFilters): VecLike[] {\n\t\treturn intersectPolys(polyline, this.vertices, false, this.isClosed)\n\t}\n\n\t/**\n\t * Find a point along the edge of the geometry that is a fraction `t` along the entire way round.\n\t */\n\tinterpolateAlongEdge(t: number, _filters?: Geometry2dFilters): Vec {\n\t\tconst { vertices } = this\n\n\t\tif (t <= 0) return vertices[0]\n\n\t\tconst distanceToTravel = t * this.length\n\t\tlet distanceTraveled = 0\n\n\t\tfor (let i = 0; i < (this.isClosed ? vertices.length : vertices.length - 1); i++) {\n\t\t\tconst curr = vertices[i]\n\t\t\tconst next = vertices[(i + 1) % vertices.length]\n\t\t\tconst dist = Vec.Dist(curr, next)\n\t\t\tconst newDistanceTraveled = distanceTraveled + dist\n\t\t\tif (newDistanceTraveled >= distanceToTravel) {\n\t\t\t\tconst p = Vec.Lrp(\n\t\t\t\t\tcurr,\n\t\t\t\t\tnext,\n\t\t\t\t\tinvLerp(distanceTraveled, newDistanceTraveled, distanceToTravel)\n\t\t\t\t)\n\t\t\t\treturn p\n\t\t\t}\n\t\t\tdistanceTraveled = newDistanceTraveled\n\t\t}\n\n\t\treturn this.isClosed ? vertices[0] : vertices[vertices.length - 1]\n\t}\n\n\t/**\n\t * Take `point`, find the closest point to it on the edge of the geometry, and return how far\n\t * along the edge it is as a fraction of the total length.\n\t */\n\tuninterpolateAlongEdge(point: VecLike, _filters?: Geometry2dFilters): number {\n\t\tconst { vertices, length } = this\n\t\tlet closestSegment = null\n\t\tlet closestDistance = Infinity\n\t\tlet distanceTraveled = 0\n\n\t\tfor (let i = 0; i < (this.isClosed ? vertices.length : vertices.length - 1); i++) {\n\t\t\tconst curr = vertices[i]\n\t\t\tconst next = vertices[(i + 1) % vertices.length]\n\n\t\t\tconst nearestPoint = Vec.NearestPointOnLineSegment(curr, next, point, true)\n\t\t\tconst distance = Vec.Dist(nearestPoint, point)\n\n\t\t\tif (distance < closestDistance) {\n\t\t\t\tclosestDistance = distance\n\t\t\t\tclosestSegment = {\n\t\t\t\t\tstart: curr,\n\t\t\t\t\tend: next,\n\t\t\t\t\tnearestPoint,\n\t\t\t\t\tdistanceToStart: distanceTraveled,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdistanceTraveled += Vec.Dist(curr, next)\n\t\t}\n\n\t\tassert(closestSegment)\n\n\t\tconst distanceAlongRoute =\n\t\t\tclosestSegment.distanceToStart + Vec.Dist(closestSegment.start, closestSegment.nearestPoint)\n\n\t\treturn distanceAlongRoute / length\n\t}\n\n\tisPointInBounds(point: VecLike, margin = 0) {\n\t\tconst { bounds } = this\n\t\treturn !(\n\t\t\tpoint.x < bounds.minX - margin ||\n\t\t\tpoint.y < bounds.minY - margin ||\n\t\t\tpoint.x > bounds.maxX + margin ||\n\t\t\tpoint.y > bounds.maxY + margin\n\t\t)\n\t}\n\n\toverlapsPolygon(_polygon: VecLike[]): boolean {\n\t\tconst polygon = _polygon.map((v) => Vec.From(v))\n\n\t\t// Otherwise, check if the geometry itself overlaps the polygon\n\t\tconst { vertices, center, isFilled, isEmptyLabel, isClosed } = this\n\n\t\t// We'll do things in order of cheapest to most expensive checks\n\n\t\t// Skip empty labels\n\t\tif (isEmptyLabel) return false\n\n\t\t// If any of the geometry's vertices are inside the polygon, it's inside\n\t\tif (vertices.some((v) => pointInPolygon(v, polygon))) {\n\t\t\treturn true\n\t\t}\n\n\t\t// If the geometry is filled and closed and its center is inside the polygon, it's inside\n\t\tif (isClosed) {\n\t\t\tif (isFilled) {\n\t\t\t\t// If closed and filled, check if the center is inside the polygon\n\t\t\t\tif (pointInPolygon(center, polygon)) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\n\t\t\t\t// ..then, slightly more expensive check, see the geometry covers the entire polygon but not its center\n\t\t\t\tif (polygon.every((v) => pointInPolygon(v, vertices))) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If any the geometry's vertices intersect the edge of the polygon, it's inside.\n\t\t\t// for example when a rotated rectangle is moved over the corner of a parent rectangle\n\t\t\t// If the geometry is closed, intersect as a polygon\n\t\t\tif (polygonsIntersect(polygon, vertices)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t} else {\n\t\t\t// If the geometry is not closed, intersect as a polyline\n\t\t\tif (polygonIntersectsPolyline(polygon, vertices)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\n\t\t// If none of the above checks passed, the geometry is outside the polygon\n\t\treturn false\n\t}\n\n\ttransform(transform: MatModel, opts?: TransformedGeometry2dOptions): Geometry2d {\n\t\treturn new TransformedGeometry2d(this, transform, opts)\n\t}\n\n\tprivate _vertices: Vec[] | undefined\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget vertices(): Vec[] {\n\t\tif (!this._vertices) {\n\t\t\tthis._vertices = this.getVertices(Geometry2dFilters.EXCLUDE_LABELS)\n\t\t}\n\n\t\treturn this._vertices\n\t}\n\n\tgetBoundsVertices(): Vec[] {\n\t\tif (this.excludeFromShapeBounds) return []\n\t\treturn this.vertices\n\t}\n\n\tprivate _boundsVertices: Vec[] | undefined\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget boundsVertices(): Vec[] {\n\t\tif (!this._boundsVertices) {\n\t\t\tthis._boundsVertices = this.getBoundsVertices()\n\t\t}\n\t\treturn this._boundsVertices\n\t}\n\n\tgetBounds() {\n\t\treturn Box.FromPoints(this.boundsVertices)\n\t}\n\n\tprivate _bounds: Box | undefined\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget bounds(): Box {\n\t\tif (!this._bounds) {\n\t\t\tthis._bounds = this.getBounds()\n\t\t}\n\t\treturn this._bounds\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget center() {\n\t\treturn this.bounds.center\n\t}\n\n\tprivate _area: number | undefined\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget area() {\n\t\tif (!this._area) {\n\t\t\tthis._area = this.getArea()\n\t\t}\n\t\treturn this._area\n\t}\n\n\tgetArea() {\n\t\tif (!this.isClosed) {\n\t\t\treturn 0\n\t\t}\n\t\tconst { vertices } = this\n\t\tlet area = 0\n\t\tfor (let i = 0, n = vertices.length; i < n; i++) {\n\t\t\tconst curr = vertices[i]\n\t\t\tconst next = vertices[(i + 1) % n]\n\t\t\tarea += curr.x * next.y - next.x * curr.y\n\t\t}\n\t\treturn area / 2\n\t}\n\n\ttoSimpleSvgPath() {\n\t\tlet path = ''\n\n\t\tconst { vertices } = this\n\t\tconst n = vertices.length\n\n\t\tif (n === 0) return path\n\n\t\tpath += `M${vertices[0].x},${vertices[0].y}`\n\n\t\tfor (let i = 1; i < n; i++) {\n\t\t\tpath += `L${vertices[i].x},${vertices[i].y}`\n\t\t}\n\n\t\tif (this.isClosed) {\n\t\t\tpath += 'Z'\n\t\t}\n\n\t\treturn path\n\t}\n\n\tprivate _length?: number\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget length() {\n\t\tif (this._length) return this._length\n\t\tthis._length = this.getLength(Geometry2dFilters.EXCLUDE_LABELS)\n\t\treturn this._length\n\t}\n\n\tgetLength(_filters?: Geometry2dFilters) {\n\t\tconst vertices = this.getVertices(_filters ?? Geometry2dFilters.EXCLUDE_LABELS)\n\t\tif (vertices.length === 0) return 0\n\t\tlet prev = vertices[0]\n\t\tlet length = 0\n\t\tfor (let i = 1; i < vertices.length; i++) {\n\t\t\tconst next = vertices[i]\n\t\t\tlength += Vec.Dist(prev, next)\n\t\t\tprev = next\n\t\t}\n\t\tif (this.isClosed) {\n\t\t\tlength += Vec.Dist(vertices[vertices.length - 1], vertices[0])\n\t\t}\n\t\treturn length\n\t}\n\n\tabstract getSvgPathData(first: boolean): string\n}\n\n// =================================================================================================\n// Because Geometry2d.transform depends on TransformedGeometry2d, we need to define it here instead\n// of in its own files. This prevents a circular import error.\n// =================================================================================================\n\n/** @public */\nexport class TransformedGeometry2d extends Geometry2d {\n\tprivate readonly inverse: MatModel\n\tprivate readonly decomposed\n\n\tconstructor(\n\t\tprivate readonly geometry: Geometry2d,\n\t\tprivate readonly matrix: MatModel,\n\t\topts?: TransformedGeometry2dOptions\n\t) {\n\t\tsuper(geometry)\n\t\tthis.inverse = Mat.Inverse(matrix)\n\t\tthis.decomposed = Mat.Decompose(matrix)\n\n\t\tif (opts) {\n\t\t\tif (opts.isLabel != null) this.isLabel = opts.isLabel\n\t\t\tif (opts.isInternal != null) this.isInternal = opts.isInternal\n\t\t\tif (opts.debugColor != null) this.debugColor = opts.debugColor\n\t\t\tif (opts.ignore != null) this.ignore = opts.ignore\n\t\t}\n\n\t\tassert(\n\t\t\tapproximately(this.decomposed.scaleX, this.decomposed.scaleY),\n\t\t\t'non-uniform scaling is not yet supported'\n\t\t)\n\t}\n\n\tgetVertices(filters: Geometry2dFilters): Vec[] {\n\t\treturn this.geometry.getVertices(filters).map((v) => Mat.applyToPoint(this.matrix, v))\n\t}\n\n\tgetBoundsVertices(): Vec[] {\n\t\treturn this.geometry.getBoundsVertices().map((v) => Mat.applyToPoint(this.matrix, v))\n\t}\n\n\tnearestPoint(point: VecLike, filters?: Geometry2dFilters): Vec {\n\t\treturn Mat.applyToPoint(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.nearestPoint(Mat.applyToPoint(this.inverse, point), filters)\n\t\t)\n\t}\n\n\toverride hitTestPoint(\n\t\tpoint: VecLike,\n\t\tmargin = 0,\n\t\thitInside?: boolean,\n\t\tfilters?: Geometry2dFilters\n\t): boolean {\n\t\treturn this.geometry.hitTestPoint(\n\t\t\tMat.applyToPoint(this.inverse, point),\n\t\t\tmargin / this.decomposed.scaleX,\n\t\t\thitInside,\n\t\t\tfilters\n\t\t)\n\t}\n\n\toverride distanceToPoint(point: VecLike, hitInside = false, filters?: Geometry2dFilters) {\n\t\treturn (\n\t\t\tthis.geometry.distanceToPoint(Mat.applyToPoint(this.inverse, point), hitInside, filters) *\n\t\t\tthis.decomposed.scaleX\n\t\t)\n\t}\n\n\toverride distanceToLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {\n\t\treturn (\n\t\t\tthis.geometry.distanceToLineSegment(\n\t\t\t\tMat.applyToPoint(this.inverse, A),\n\t\t\t\tMat.applyToPoint(this.inverse, B),\n\t\t\t\tfilters\n\t\t\t) * this.decomposed.scaleX\n\t\t)\n\t}\n\n\toverride hitTestLineSegment(\n\t\tA: VecLike,\n\t\tB: VecLike,\n\t\tdistance = 0,\n\t\tfilters?: Geometry2dFilters\n\t): boolean {\n\t\treturn this.geometry.hitTestLineSegment(\n\t\t\tMat.applyToPoint(this.inverse, A),\n\t\t\tMat.applyToPoint(this.inverse, B),\n\t\t\tdistance / this.decomposed.scaleX,\n\t\t\tfilters\n\t\t)\n\t}\n\n\toverride intersectLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {\n\t\treturn Mat.applyToPoints(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.intersectLineSegment(\n\t\t\t\tMat.applyToPoint(this.inverse, A),\n\t\t\t\tMat.applyToPoint(this.inverse, B),\n\t\t\t\tfilters\n\t\t\t)\n\t\t)\n\t}\n\n\toverride intersectCircle(center: VecLike, radius: number, filters?: Geometry2dFilters) {\n\t\treturn Mat.applyToPoints(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.intersectCircle(\n\t\t\t\tMat.applyToPoint(this.inverse, center),\n\t\t\t\tradius / this.decomposed.scaleX,\n\t\t\t\tfilters\n\t\t\t)\n\t\t)\n\t}\n\n\toverride intersectPolygon(polygon: VecLike[], filters?: Geometry2dFilters): VecLike[] {\n\t\treturn Mat.applyToPoints(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.intersectPolygon(Mat.applyToPoints(this.inverse, polygon), filters)\n\t\t)\n\t}\n\n\toverride intersectPolyline(polyline: VecLike[], filters?: Geometry2dFilters): VecLike[] {\n\t\treturn Mat.applyToPoints(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.intersectPolyline(Mat.applyToPoints(this.inverse, polyline), filters)\n\t\t)\n\t}\n\n\toverride transform(transform: MatModel, opts?: TransformedGeometry2dOptions): Geometry2d {\n\t\treturn new TransformedGeometry2d(this.geometry, Mat.Multiply(transform, this.matrix), {\n\t\t\tisLabel: opts?.isLabel ?? this.isLabel,\n\t\t\tisInternal: opts?.isInternal ?? this.isInternal,\n\t\t\tdebugColor: opts?.debugColor ?? this.debugColor,\n\t\t\tignore: opts?.ignore ?? this.ignore,\n\t\t})\n\t}\n\n\tgetSvgPathData(): string {\n\t\tthrow new Error('Cannot get SVG path data for transformed geometry.')\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_utils"]
7
7
  }
@@ -99,6 +99,10 @@ class Group2d extends import_Geometry2d.Geometry2d {
99
99
  return child.intersectCircle(center, radius, filters);
100
100
  });
101
101
  }
102
+ getBoundsVertices() {
103
+ if (this.excludeFromShapeBounds) return [];
104
+ return this.children.flatMap((child) => child.getBoundsVertices());
105
+ }
102
106
  intersectPolygon(polygon, filters) {
103
107
  return this.children.flatMap((child) => {
104
108
  if (child.isExcludedByFilter(filters)) return import_state.EMPTY_ARRAY;
@@ -174,7 +178,7 @@ class Group2d extends import_Geometry2d.Geometry2d {
174
178
  for (const child of this.children) {
175
179
  path += child.toSimpleSvgPath();
176
180
  }
177
- const corners = import_Box.Box.FromPoints(this.vertices).corners;
181
+ const corners = import_Box.Box.FromPoints(this.boundsVertices).corners;
178
182
  for (let i = 0, n = corners.length; i < n; i++) {
179
183
  const corner = corners[i];
180
184
  const prevCorner = corners[(i - 1 + n) % n];
@@ -199,5 +203,8 @@ class Group2d extends import_Geometry2d.Geometry2d {
199
203
  getSvgPathData() {
200
204
  return this.children.map((c, i) => c.isLabel ? "" : c.getSvgPathData(i === 0)).join(" ");
201
205
  }
206
+ overlapsPolygon(polygon) {
207
+ return this.children.some((child) => child.overlapsPolygon(polygon));
208
+ }
202
209
  }
203
210
  //# sourceMappingURL=Group2d.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Group2d.ts"],
4
- "sourcesContent": ["import { EMPTY_ARRAY } from '@tldraw/state'\nimport { assert, invLerp, lerp } from '@tldraw/utils'\nimport { Box } from '../Box'\nimport { Mat } from '../Mat'\nimport { Vec, VecLike } from '../Vec'\nimport { Geometry2d, Geometry2dFilters, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Group2d extends Geometry2d {\n\tchildren: Geometry2d[] = []\n\tignoredChildren: Geometry2d[] = []\n\n\tconstructor(\n\t\tconfig: Omit<Geometry2dOptions, 'isClosed' | 'isFilled'> & {\n\t\t\tchildren: Geometry2d[]\n\t\t}\n\t) {\n\t\tsuper({ ...config, isClosed: true, isFilled: false })\n\n\t\tconst addChildren = (children: Geometry2d[]) => {\n\t\t\tfor (const child of children) {\n\t\t\t\tif (child instanceof Group2d) {\n\t\t\t\t\taddChildren(child.children)\n\t\t\t\t} else if (child.ignore) {\n\t\t\t\t\tthis.ignoredChildren.push(child)\n\t\t\t\t} else {\n\t\t\t\t\tthis.children.push(child)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\taddChildren(config.children)\n\n\t\tif (this.children.length === 0) throw Error('Group2d must have at least one child')\n\t}\n\n\toverride getVertices(filters: Geometry2dFilters): Vec[] {\n\t\tif (this.isExcludedByFilter(filters)) return []\n\t\treturn this.children\n\t\t\t.filter((c) => !c.isExcludedByFilter(filters))\n\t\t\t.flatMap((c) => c.getVertices(filters))\n\t}\n\n\toverride nearestPoint(point: VecLike, filters?: Geometry2dFilters): Vec {\n\t\tlet dist = Infinity\n\t\tlet nearest: Vec | undefined\n\n\t\tconst { children } = this\n\n\t\tif (children.length === 0) {\n\t\t\tthrow Error('no children')\n\t\t}\n\n\t\tlet p: Vec\n\t\tlet d: number\n\t\tfor (const child of children) {\n\t\t\tif (child.isExcludedByFilter(filters)) continue\n\t\t\tp = child.nearestPoint(point, filters)\n\t\t\td = Vec.Dist2(p, point)\n\t\t\tif (d < dist) {\n\t\t\t\tdist = d\n\t\t\t\tnearest = p\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\toverride distanceToPoint(point: VecLike, hitInside = false, filters?: Geometry2dFilters) {\n\t\tlet smallestDistance = Infinity\n\t\tfor (const child of this.children) {\n\t\t\tif (child.isExcludedByFilter(filters)) continue\n\t\t\tconst distance = child.distanceToPoint(point, hitInside, filters)\n\t\t\tif (distance < smallestDistance) {\n\t\t\t\tsmallestDistance = distance\n\t\t\t}\n\t\t}\n\t\treturn smallestDistance\n\t}\n\n\toverride hitTestPoint(\n\t\tpoint: VecLike,\n\t\tmargin: number,\n\t\thitInside: boolean,\n\t\tfilters = Geometry2dFilters.EXCLUDE_LABELS\n\t): boolean {\n\t\treturn !!this.children\n\t\t\t.filter((c) => !c.isExcludedByFilter(filters))\n\t\t\t.find((c) => c.hitTestPoint(point, margin, hitInside))\n\t}\n\n\toverride hitTestLineSegment(\n\t\tA: VecLike,\n\t\tB: VecLike,\n\t\tzoom: number,\n\t\tfilters = Geometry2dFilters.EXCLUDE_LABELS\n\t): boolean {\n\t\treturn !!this.children\n\t\t\t.filter((c) => !c.isExcludedByFilter(filters))\n\t\t\t.find((c) => c.hitTestLineSegment(A, B, zoom))\n\t}\n\n\toverride intersectLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {\n\t\treturn this.children.flatMap((child) => {\n\t\t\tif (child.isExcludedByFilter(filters)) return EMPTY_ARRAY\n\t\t\treturn child.intersectLineSegment(A, B, filters)\n\t\t})\n\t}\n\n\toverride intersectCircle(center: VecLike, radius: number, filters?: Geometry2dFilters) {\n\t\treturn this.children.flatMap((child) => {\n\t\t\tif (child.isExcludedByFilter(filters)) return EMPTY_ARRAY\n\t\t\treturn child.intersectCircle(center, radius, filters)\n\t\t})\n\t}\n\n\toverride intersectPolygon(polygon: VecLike[], filters?: Geometry2dFilters) {\n\t\treturn this.children.flatMap((child) => {\n\t\t\tif (child.isExcludedByFilter(filters)) return EMPTY_ARRAY\n\t\t\treturn child.intersectPolygon(polygon, filters)\n\t\t})\n\t}\n\n\toverride intersectPolyline(polyline: VecLike[], filters?: Geometry2dFilters) {\n\t\treturn this.children.flatMap((child) => {\n\t\t\tif (child.isExcludedByFilter(filters)) return EMPTY_ARRAY\n\t\t\treturn child.intersectPolyline(polyline, filters)\n\t\t})\n\t}\n\n\toverride interpolateAlongEdge(t: number, filters?: Geometry2dFilters): Vec {\n\t\tconst totalLength = this.getLength(filters)\n\n\t\tconst distanceToTravel = t * totalLength\n\t\tlet distanceTraveled = 0\n\t\tfor (const child of this.children) {\n\t\t\tif (child.isExcludedByFilter(filters)) continue\n\t\t\tconst childLength = child.length\n\t\t\tconst newDistanceTraveled = distanceTraveled + childLength\n\t\t\tif (newDistanceTraveled >= distanceToTravel) {\n\t\t\t\treturn child.interpolateAlongEdge(\n\t\t\t\t\tinvLerp(distanceTraveled, newDistanceTraveled, distanceToTravel),\n\t\t\t\t\tfilters\n\t\t\t\t)\n\t\t\t}\n\t\t\tdistanceTraveled = newDistanceTraveled\n\t\t}\n\n\t\treturn this.children[this.children.length - 1].interpolateAlongEdge(1, filters)\n\t}\n\n\toverride uninterpolateAlongEdge(point: VecLike, filters?: Geometry2dFilters): number {\n\t\tconst totalLength = this.getLength(filters)\n\n\t\tlet closestChild = null\n\t\tlet closestDistance = Infinity\n\t\tlet distanceTraveled = 0\n\n\t\tfor (const child of this.children) {\n\t\t\tif (child.isExcludedByFilter(filters)) continue\n\t\t\tconst childLength = child.getLength(filters)\n\t\t\tconst newDistanceTraveled = distanceTraveled + childLength\n\n\t\t\tconst distance = child.distanceToPoint(point, false, filters)\n\t\t\tif (distance < closestDistance) {\n\t\t\t\tclosestDistance = distance\n\t\t\t\tclosestChild = {\n\t\t\t\t\tstartLength: distanceTraveled,\n\t\t\t\t\tendLength: newDistanceTraveled,\n\t\t\t\t\tchild,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdistanceTraveled = newDistanceTraveled\n\t\t}\n\n\t\tassert(closestChild)\n\n\t\tconst normalizedDistanceInChild = closestChild.child.uninterpolateAlongEdge(point, filters)\n\t\tconst childTLength = lerp(\n\t\t\tclosestChild.startLength,\n\t\t\tclosestChild.endLength,\n\t\t\tnormalizedDistanceInChild\n\t\t)\n\t\treturn childTLength / totalLength\n\t}\n\n\toverride transform(transform: Mat): Geometry2d {\n\t\treturn new Group2d({\n\t\t\tchildren: this.children.map((c) => c.transform(transform)),\n\t\t\tisLabel: this.isLabel,\n\t\t\tdebugColor: this.debugColor,\n\t\t\tignore: this.ignore,\n\t\t})\n\t}\n\n\tgetArea() {\n\t\t// todo: this is a temporary solution, assuming that the first child defines the group size; we would want to flatten the group and then find the area of the hull polygon\n\t\treturn this.children[0].area\n\t}\n\n\ttoSimpleSvgPath() {\n\t\tlet path = ''\n\t\tfor (const child of this.children) {\n\t\t\tpath += child.toSimpleSvgPath()\n\t\t}\n\n\t\tconst corners = Box.FromPoints(this.vertices).corners\n\t\t// draw just a few pixels around each corner, e.g. an L shape for the bottom left\n\n\t\tfor (let i = 0, n = corners.length; i < n; i++) {\n\t\t\tconst corner = corners[i]\n\t\t\tconst prevCorner = corners[(i - 1 + n) % n]\n\t\t\tconst prevDist = corner.dist(prevCorner)\n\t\t\tconst nextCorner = corners[(i + 1) % n]\n\t\t\tconst nextDist = corner.dist(nextCorner)\n\n\t\t\tconst A = corner.clone().lrp(prevCorner, 4 / prevDist)\n\t\t\tconst B = corner\n\t\t\tconst C = corner.clone().lrp(nextCorner, 4 / nextDist)\n\n\t\t\tpath += `M${A.x},${A.y} L${B.x},${B.y} L${C.x},${C.y} `\n\t\t}\n\t\treturn path\n\t}\n\n\tgetLength(filters?: Geometry2dFilters): number {\n\t\tlet length = 0\n\t\tfor (const child of this.children) {\n\t\t\tif (child.isExcludedByFilter(filters)) continue\n\t\t\tlength += child.length\n\t\t}\n\t\treturn length\n\t}\n\n\tgetSvgPathData(): string {\n\t\treturn this.children.map((c, i) => (c.isLabel ? '' : c.getSvgPathData(i === 0))).join(' ')\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { EMPTY_ARRAY } from '@tldraw/state'\nimport { assert, invLerp, lerp } from '@tldraw/utils'\nimport { Box } from '../Box'\nimport { Mat } from '../Mat'\nimport { Vec, VecLike } from '../Vec'\nimport { Geometry2d, Geometry2dFilters, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Group2d extends Geometry2d {\n\tchildren: Geometry2d[] = []\n\tignoredChildren: Geometry2d[] = []\n\n\tconstructor(\n\t\tconfig: Omit<Geometry2dOptions, 'isClosed' | 'isFilled'> & {\n\t\t\tchildren: Geometry2d[]\n\t\t}\n\t) {\n\t\tsuper({ ...config, isClosed: true, isFilled: false })\n\n\t\tconst addChildren = (children: Geometry2d[]) => {\n\t\t\tfor (const child of children) {\n\t\t\t\tif (child instanceof Group2d) {\n\t\t\t\t\taddChildren(child.children)\n\t\t\t\t} else if (child.ignore) {\n\t\t\t\t\tthis.ignoredChildren.push(child)\n\t\t\t\t} else {\n\t\t\t\t\tthis.children.push(child)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\taddChildren(config.children)\n\n\t\tif (this.children.length === 0) throw Error('Group2d must have at least one child')\n\t}\n\n\toverride getVertices(filters: Geometry2dFilters): Vec[] {\n\t\tif (this.isExcludedByFilter(filters)) return []\n\t\treturn this.children\n\t\t\t.filter((c) => !c.isExcludedByFilter(filters))\n\t\t\t.flatMap((c) => c.getVertices(filters))\n\t}\n\n\toverride nearestPoint(point: VecLike, filters?: Geometry2dFilters): Vec {\n\t\tlet dist = Infinity\n\t\tlet nearest: Vec | undefined\n\n\t\tconst { children } = this\n\n\t\tif (children.length === 0) {\n\t\t\tthrow Error('no children')\n\t\t}\n\n\t\tlet p: Vec\n\t\tlet d: number\n\t\tfor (const child of children) {\n\t\t\tif (child.isExcludedByFilter(filters)) continue\n\t\t\tp = child.nearestPoint(point, filters)\n\t\t\td = Vec.Dist2(p, point)\n\t\t\tif (d < dist) {\n\t\t\t\tdist = d\n\t\t\t\tnearest = p\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\toverride distanceToPoint(point: VecLike, hitInside = false, filters?: Geometry2dFilters) {\n\t\tlet smallestDistance = Infinity\n\t\tfor (const child of this.children) {\n\t\t\tif (child.isExcludedByFilter(filters)) continue\n\t\t\tconst distance = child.distanceToPoint(point, hitInside, filters)\n\t\t\tif (distance < smallestDistance) {\n\t\t\t\tsmallestDistance = distance\n\t\t\t}\n\t\t}\n\t\treturn smallestDistance\n\t}\n\n\toverride hitTestPoint(\n\t\tpoint: VecLike,\n\t\tmargin: number,\n\t\thitInside: boolean,\n\t\tfilters = Geometry2dFilters.EXCLUDE_LABELS\n\t): boolean {\n\t\treturn !!this.children\n\t\t\t.filter((c) => !c.isExcludedByFilter(filters))\n\t\t\t.find((c) => c.hitTestPoint(point, margin, hitInside))\n\t}\n\n\toverride hitTestLineSegment(\n\t\tA: VecLike,\n\t\tB: VecLike,\n\t\tzoom: number,\n\t\tfilters = Geometry2dFilters.EXCLUDE_LABELS\n\t): boolean {\n\t\treturn !!this.children\n\t\t\t.filter((c) => !c.isExcludedByFilter(filters))\n\t\t\t.find((c) => c.hitTestLineSegment(A, B, zoom))\n\t}\n\n\toverride intersectLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {\n\t\treturn this.children.flatMap((child) => {\n\t\t\tif (child.isExcludedByFilter(filters)) return EMPTY_ARRAY\n\t\t\treturn child.intersectLineSegment(A, B, filters)\n\t\t})\n\t}\n\n\toverride intersectCircle(center: VecLike, radius: number, filters?: Geometry2dFilters) {\n\t\treturn this.children.flatMap((child) => {\n\t\t\tif (child.isExcludedByFilter(filters)) return EMPTY_ARRAY\n\t\t\treturn child.intersectCircle(center, radius, filters)\n\t\t})\n\t}\n\n\toverride getBoundsVertices(): Vec[] {\n\t\tif (this.excludeFromShapeBounds) return []\n\t\treturn this.children.flatMap((child) => child.getBoundsVertices())\n\t}\n\n\toverride intersectPolygon(polygon: VecLike[], filters?: Geometry2dFilters) {\n\t\treturn this.children.flatMap((child) => {\n\t\t\tif (child.isExcludedByFilter(filters)) return EMPTY_ARRAY\n\t\t\treturn child.intersectPolygon(polygon, filters)\n\t\t})\n\t}\n\n\toverride intersectPolyline(polyline: VecLike[], filters?: Geometry2dFilters) {\n\t\treturn this.children.flatMap((child) => {\n\t\t\tif (child.isExcludedByFilter(filters)) return EMPTY_ARRAY\n\t\t\treturn child.intersectPolyline(polyline, filters)\n\t\t})\n\t}\n\n\toverride interpolateAlongEdge(t: number, filters?: Geometry2dFilters): Vec {\n\t\tconst totalLength = this.getLength(filters)\n\n\t\tconst distanceToTravel = t * totalLength\n\t\tlet distanceTraveled = 0\n\t\tfor (const child of this.children) {\n\t\t\tif (child.isExcludedByFilter(filters)) continue\n\t\t\tconst childLength = child.length\n\t\t\tconst newDistanceTraveled = distanceTraveled + childLength\n\t\t\tif (newDistanceTraveled >= distanceToTravel) {\n\t\t\t\treturn child.interpolateAlongEdge(\n\t\t\t\t\tinvLerp(distanceTraveled, newDistanceTraveled, distanceToTravel),\n\t\t\t\t\tfilters\n\t\t\t\t)\n\t\t\t}\n\t\t\tdistanceTraveled = newDistanceTraveled\n\t\t}\n\n\t\treturn this.children[this.children.length - 1].interpolateAlongEdge(1, filters)\n\t}\n\n\toverride uninterpolateAlongEdge(point: VecLike, filters?: Geometry2dFilters): number {\n\t\tconst totalLength = this.getLength(filters)\n\n\t\tlet closestChild = null\n\t\tlet closestDistance = Infinity\n\t\tlet distanceTraveled = 0\n\n\t\tfor (const child of this.children) {\n\t\t\tif (child.isExcludedByFilter(filters)) continue\n\t\t\tconst childLength = child.getLength(filters)\n\t\t\tconst newDistanceTraveled = distanceTraveled + childLength\n\n\t\t\tconst distance = child.distanceToPoint(point, false, filters)\n\t\t\tif (distance < closestDistance) {\n\t\t\t\tclosestDistance = distance\n\t\t\t\tclosestChild = {\n\t\t\t\t\tstartLength: distanceTraveled,\n\t\t\t\t\tendLength: newDistanceTraveled,\n\t\t\t\t\tchild,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdistanceTraveled = newDistanceTraveled\n\t\t}\n\n\t\tassert(closestChild)\n\n\t\tconst normalizedDistanceInChild = closestChild.child.uninterpolateAlongEdge(point, filters)\n\t\tconst childTLength = lerp(\n\t\t\tclosestChild.startLength,\n\t\t\tclosestChild.endLength,\n\t\t\tnormalizedDistanceInChild\n\t\t)\n\t\treturn childTLength / totalLength\n\t}\n\n\toverride transform(transform: Mat): Geometry2d {\n\t\treturn new Group2d({\n\t\t\tchildren: this.children.map((c) => c.transform(transform)),\n\t\t\tisLabel: this.isLabel,\n\t\t\tdebugColor: this.debugColor,\n\t\t\tignore: this.ignore,\n\t\t})\n\t}\n\n\tgetArea() {\n\t\t// todo: this is a temporary solution, assuming that the first child defines the group size; we would want to flatten the group and then find the area of the hull polygon\n\t\treturn this.children[0].area\n\t}\n\n\ttoSimpleSvgPath() {\n\t\tlet path = ''\n\t\tfor (const child of this.children) {\n\t\t\tpath += child.toSimpleSvgPath()\n\t\t}\n\n\t\tconst corners = Box.FromPoints(this.boundsVertices).corners\n\t\t// draw just a few pixels around each corner, e.g. an L shape for the bottom left\n\n\t\tfor (let i = 0, n = corners.length; i < n; i++) {\n\t\t\tconst corner = corners[i]\n\t\t\tconst prevCorner = corners[(i - 1 + n) % n]\n\t\t\tconst prevDist = corner.dist(prevCorner)\n\t\t\tconst nextCorner = corners[(i + 1) % n]\n\t\t\tconst nextDist = corner.dist(nextCorner)\n\n\t\t\tconst A = corner.clone().lrp(prevCorner, 4 / prevDist)\n\t\t\tconst B = corner\n\t\t\tconst C = corner.clone().lrp(nextCorner, 4 / nextDist)\n\n\t\t\tpath += `M${A.x},${A.y} L${B.x},${B.y} L${C.x},${C.y} `\n\t\t}\n\t\treturn path\n\t}\n\n\tgetLength(filters?: Geometry2dFilters): number {\n\t\tlet length = 0\n\t\tfor (const child of this.children) {\n\t\t\tif (child.isExcludedByFilter(filters)) continue\n\t\t\tlength += child.length\n\t\t}\n\t\treturn length\n\t}\n\n\tgetSvgPathData(): string {\n\t\treturn this.children.map((c, i) => (c.isLabel ? '' : c.getSvgPathData(i === 0))).join(' ')\n\t}\n\n\toverlapsPolygon(polygon: VecLike[]): boolean {\n\t\treturn this.children.some((child) => child.overlapsPolygon(polygon))\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -18,12 +18,12 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var geometry_constants_exports = {};
20
20
  __export(geometry_constants_exports, {
21
- getVerticesCountForLength: () => getVerticesCountForLength
21
+ getVerticesCountForArcLength: () => getVerticesCountForArcLength
22
22
  });
23
23
  module.exports = __toCommonJS(geometry_constants_exports);
24
24
  const SPACING = 20;
25
25
  const MIN_COUNT = 8;
26
- function getVerticesCountForLength(length, spacing = SPACING) {
26
+ function getVerticesCountForArcLength(length, spacing = SPACING) {
27
27
  return Math.max(MIN_COUNT, Math.ceil(length / spacing));
28
28
  }
29
29
  //# sourceMappingURL=geometry-constants.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/geometry-constants.ts"],
4
- "sourcesContent": ["const SPACING = 20\nconst MIN_COUNT = 8\n\nexport function getVerticesCountForLength(length: number, spacing = SPACING) {\n\treturn Math.max(MIN_COUNT, Math.ceil(length / spacing))\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAAM,UAAU;AAChB,MAAM,YAAY;AAEX,SAAS,0BAA0B,QAAgB,UAAU,SAAS;AAC5E,SAAO,KAAK,IAAI,WAAW,KAAK,KAAK,SAAS,OAAO,CAAC;AACvD;",
4
+ "sourcesContent": ["const SPACING = 20\nconst MIN_COUNT = 8\n\n/** @internal */\nexport function getVerticesCountForArcLength(length: number, spacing = SPACING) {\n\treturn Math.max(MIN_COUNT, Math.ceil(length / spacing))\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAAM,UAAU;AAChB,MAAM,YAAY;AAGX,SAAS,6BAA6B,QAAgB,UAAU,SAAS;AAC/E,SAAO,KAAK,IAAI,WAAW,KAAK,KAAK,SAAS,OAAO,CAAC;AACvD;",
6
6
  "names": []
7
7
  }
@@ -35,7 +35,7 @@ __export(intersect_exports, {
35
35
  module.exports = __toCommonJS(intersect_exports);
36
36
  var import_utils = require("./utils");
37
37
  var import_Vec = require("./Vec");
38
- function intersectLineSegmentLineSegment(a1, a2, b1, b2) {
38
+ function intersectLineSegmentLineSegment(a1, a2, b1, b2, precision = 1e-10) {
39
39
  const ABx = a1.x - b1.x;
40
40
  const ABy = a1.y - b1.y;
41
41
  const BVx = b2.x - b1.x;
@@ -45,12 +45,12 @@ function intersectLineSegmentLineSegment(a1, a2, b1, b2) {
45
45
  const ua_t = BVx * ABy - BVy * ABx;
46
46
  const ub_t = AVx * ABy - AVy * ABx;
47
47
  const u_b = BVy * AVx - BVx * AVy;
48
- if (ua_t === 0 || ub_t === 0) return null;
49
- if (u_b === 0) return null;
48
+ if ((0, import_utils.approximately)(ua_t, 0, precision) || (0, import_utils.approximately)(ub_t, 0, precision)) return null;
49
+ if ((0, import_utils.approximately)(u_b, 0, precision)) return null;
50
50
  if (u_b !== 0) {
51
51
  const ua = ua_t / u_b;
52
52
  const ub = ub_t / u_b;
53
- if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {
53
+ if ((0, import_utils.approximatelyLte)(0, ua, precision) && (0, import_utils.approximatelyLte)(ua, 1, precision) && (0, import_utils.approximatelyLte)(0, ub, precision) && (0, import_utils.approximatelyLte)(ub, 1, precision)) {
54
54
  return import_Vec.Vec.AddXY(a1, ua * AVx, ua * AVy);
55
55
  }
56
56
  }