@tldraw/editor 3.13.1 → 3.14.0-canary.0086db67f471

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 (220) hide show
  1. package/dist-cjs/index.d.ts +76 -70
  2. package/dist-cjs/index.js +8 -8
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/config/TLSessionStateSnapshot.js +1 -12
  5. package/dist-cjs/lib/config/TLSessionStateSnapshot.js.map +3 -3
  6. package/dist-cjs/lib/editor/Editor.js +51 -77
  7. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  8. package/dist-cjs/lib/editor/bindings/BindingUtil.js.map +2 -2
  9. package/dist-cjs/lib/editor/derivations/bindingsIndex.js +22 -22
  10. package/dist-cjs/lib/editor/derivations/bindingsIndex.js.map +2 -2
  11. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js +16 -20
  12. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js.map +3 -3
  13. package/dist-cjs/lib/editor/derivations/parentsToChildren.js +16 -16
  14. package/dist-cjs/lib/editor/derivations/parentsToChildren.js.map +2 -2
  15. package/dist-cjs/lib/editor/managers/{ClickManager.js → ClickManager/ClickManager.js} +1 -1
  16. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +7 -0
  17. package/dist-cjs/lib/editor/managers/{EdgeScrollManager.js → EdgeScrollManager/EdgeScrollManager.js} +2 -2
  18. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +7 -0
  19. package/dist-cjs/lib/editor/managers/{FocusManager.js → FocusManager/FocusManager.js} +2 -0
  20. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +7 -0
  21. package/dist-cjs/lib/editor/managers/{FontManager.js → FontManager/FontManager.js} +4 -1
  22. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +7 -0
  23. package/dist-cjs/lib/editor/managers/{HistoryManager.js → HistoryManager/HistoryManager.js} +64 -6
  24. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +7 -0
  25. package/dist-cjs/lib/editor/managers/{ScribbleManager.js → ScribbleManager/ScribbleManager.js} +1 -1
  26. package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js.map +7 -0
  27. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +7 -0
  28. package/dist-cjs/lib/editor/managers/{TickManager.js → TickManager/TickManager.js} +1 -1
  29. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +7 -0
  30. package/dist-cjs/lib/editor/managers/{UserPreferencesManager.js → UserPreferencesManager/UserPreferencesManager.js} +1 -1
  31. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +7 -0
  32. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +8 -0
  33. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  34. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +6 -0
  35. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
  36. package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js.map +2 -2
  37. package/dist-cjs/lib/exports/getSvgJsx.js.map +1 -1
  38. package/dist-cjs/lib/primitives/Box.js +33 -33
  39. package/dist-cjs/lib/primitives/Box.js.map +2 -2
  40. package/dist-cjs/lib/primitives/Vec.js +18 -13
  41. package/dist-cjs/lib/primitives/Vec.js.map +3 -3
  42. package/dist-cjs/lib/primitives/geometry/Arc2d.js +41 -21
  43. package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
  44. package/dist-cjs/lib/primitives/geometry/Circle2d.js +11 -11
  45. package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
  46. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +13 -16
  47. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
  48. package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js +4 -4
  49. package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js.map +2 -2
  50. package/dist-cjs/lib/primitives/geometry/Edge2d.js +14 -21
  51. package/dist-cjs/lib/primitives/geometry/Edge2d.js.map +2 -2
  52. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js +10 -10
  53. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
  54. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +5 -0
  55. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
  56. package/dist-cjs/lib/primitives/geometry/Point2d.js +6 -6
  57. package/dist-cjs/lib/primitives/geometry/Point2d.js.map +2 -2
  58. package/dist-cjs/lib/primitives/geometry/Polygon2d.js +3 -0
  59. package/dist-cjs/lib/primitives/geometry/Polygon2d.js.map +2 -2
  60. package/dist-cjs/lib/primitives/geometry/Polyline2d.js +8 -5
  61. package/dist-cjs/lib/primitives/geometry/Polyline2d.js.map +2 -2
  62. package/dist-cjs/lib/primitives/geometry/Rectangle2d.js +22 -11
  63. package/dist-cjs/lib/primitives/geometry/Rectangle2d.js.map +2 -2
  64. package/dist-cjs/lib/primitives/geometry/Stadium2d.js +22 -22
  65. package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +2 -2
  66. package/dist-cjs/lib/utils/reorderShapes.js +11 -10
  67. package/dist-cjs/lib/utils/reorderShapes.js.map +2 -2
  68. package/dist-cjs/lib/utils/richText.js +7 -2
  69. package/dist-cjs/lib/utils/richText.js.map +2 -2
  70. package/dist-cjs/version.js +3 -3
  71. package/dist-cjs/version.js.map +1 -1
  72. package/dist-esm/index.d.mts +76 -70
  73. package/dist-esm/index.mjs +15 -9
  74. package/dist-esm/index.mjs.map +2 -2
  75. package/dist-esm/lib/config/TLSessionStateSnapshot.mjs +1 -1
  76. package/dist-esm/lib/config/TLSessionStateSnapshot.mjs.map +2 -2
  77. package/dist-esm/lib/editor/Editor.mjs +51 -77
  78. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  79. package/dist-esm/lib/editor/bindings/BindingUtil.mjs.map +2 -2
  80. package/dist-esm/lib/editor/derivations/bindingsIndex.mjs +22 -22
  81. package/dist-esm/lib/editor/derivations/bindingsIndex.mjs.map +2 -2
  82. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs +16 -20
  83. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs.map +3 -3
  84. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs +16 -16
  85. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs.map +2 -2
  86. package/dist-esm/lib/editor/managers/{ClickManager.mjs → ClickManager/ClickManager.mjs} +1 -1
  87. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +7 -0
  88. package/dist-esm/lib/editor/managers/{EdgeScrollManager.mjs → EdgeScrollManager/EdgeScrollManager.mjs} +2 -2
  89. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +7 -0
  90. package/dist-esm/lib/editor/managers/{FocusManager.mjs → FocusManager/FocusManager.mjs} +2 -0
  91. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +7 -0
  92. package/dist-esm/lib/editor/managers/{FontManager.mjs → FontManager/FontManager.mjs} +4 -1
  93. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +7 -0
  94. package/dist-esm/lib/editor/managers/{HistoryManager.mjs → HistoryManager/HistoryManager.mjs} +60 -2
  95. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +7 -0
  96. package/dist-esm/lib/editor/managers/{ScribbleManager.mjs → ScribbleManager/ScribbleManager.mjs} +1 -1
  97. package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs.map +7 -0
  98. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +7 -0
  99. package/dist-esm/lib/editor/managers/{TickManager.mjs → TickManager/TickManager.mjs} +1 -1
  100. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +7 -0
  101. package/dist-esm/lib/editor/managers/{UserPreferencesManager.mjs → UserPreferencesManager/UserPreferencesManager.mjs} +1 -1
  102. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +7 -0
  103. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +8 -0
  104. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  105. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +6 -0
  106. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
  107. package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs.map +2 -2
  108. package/dist-esm/lib/exports/getSvgJsx.mjs.map +1 -1
  109. package/dist-esm/lib/primitives/Box.mjs +33 -33
  110. package/dist-esm/lib/primitives/Box.mjs.map +2 -2
  111. package/dist-esm/lib/primitives/Vec.mjs +19 -14
  112. package/dist-esm/lib/primitives/Vec.mjs.map +3 -3
  113. package/dist-esm/lib/primitives/geometry/Arc2d.mjs +41 -21
  114. package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
  115. package/dist-esm/lib/primitives/geometry/Circle2d.mjs +11 -11
  116. package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
  117. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +13 -16
  118. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
  119. package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs +4 -4
  120. package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs.map +2 -2
  121. package/dist-esm/lib/primitives/geometry/Edge2d.mjs +14 -21
  122. package/dist-esm/lib/primitives/geometry/Edge2d.mjs.map +2 -2
  123. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs +11 -11
  124. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
  125. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +7 -1
  126. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
  127. package/dist-esm/lib/primitives/geometry/Point2d.mjs +6 -6
  128. package/dist-esm/lib/primitives/geometry/Point2d.mjs.map +2 -2
  129. package/dist-esm/lib/primitives/geometry/Polygon2d.mjs +3 -0
  130. package/dist-esm/lib/primitives/geometry/Polygon2d.mjs.map +2 -2
  131. package/dist-esm/lib/primitives/geometry/Polyline2d.mjs +8 -5
  132. package/dist-esm/lib/primitives/geometry/Polyline2d.mjs.map +2 -2
  133. package/dist-esm/lib/primitives/geometry/Rectangle2d.mjs +22 -11
  134. package/dist-esm/lib/primitives/geometry/Rectangle2d.mjs.map +2 -2
  135. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs +22 -22
  136. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +2 -2
  137. package/dist-esm/lib/utils/reorderShapes.mjs +11 -10
  138. package/dist-esm/lib/utils/reorderShapes.mjs.map +2 -2
  139. package/dist-esm/lib/utils/richText.mjs +8 -3
  140. package/dist-esm/lib/utils/richText.mjs.map +2 -2
  141. package/dist-esm/version.mjs +3 -3
  142. package/dist-esm/version.mjs.map +1 -1
  143. package/package.json +8 -9
  144. package/src/index.ts +17 -8
  145. package/src/lib/config/TLSessionStateSnapshot.ts +1 -1
  146. package/src/lib/editor/Editor.test.ts +252 -3
  147. package/src/lib/editor/Editor.ts +49 -75
  148. package/src/lib/editor/bindings/BindingUtil.ts +6 -0
  149. package/src/lib/editor/derivations/bindingsIndex.ts +27 -26
  150. package/src/lib/editor/derivations/notVisibleShapes.ts +24 -25
  151. package/src/lib/editor/derivations/parentsToChildren.ts +28 -25
  152. package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +442 -0
  153. package/src/lib/editor/managers/{ClickManager.ts → ClickManager/ClickManager.ts} +3 -3
  154. package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +374 -0
  155. package/src/lib/editor/managers/{EdgeScrollManager.ts → EdgeScrollManager/EdgeScrollManager.ts} +3 -3
  156. package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +455 -0
  157. package/src/lib/editor/managers/{FocusManager.ts → FocusManager/FocusManager.ts} +3 -1
  158. package/src/lib/editor/managers/FontManager/FontManager.test.ts +263 -0
  159. package/src/lib/editor/managers/{FontManager.ts → FontManager/FontManager.ts} +5 -2
  160. package/src/lib/editor/managers/{HistoryManager.test.ts → HistoryManager/HistoryManager.test.ts} +388 -1
  161. package/src/lib/editor/managers/{HistoryManager.ts → HistoryManager/HistoryManager.ts} +73 -2
  162. package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +624 -0
  163. package/src/lib/editor/managers/{ScribbleManager.ts → ScribbleManager/ScribbleManager.ts} +2 -2
  164. package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +485 -0
  165. package/src/lib/editor/managers/TextManager/TextManager.test.ts +411 -0
  166. package/src/lib/editor/managers/{TextManager.ts → TextManager/TextManager.ts} +1 -1
  167. package/src/lib/editor/managers/TickManager/TickManager.test.ts +314 -0
  168. package/src/lib/editor/managers/{TickManager.ts → TickManager/TickManager.ts} +2 -2
  169. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +591 -0
  170. package/src/lib/editor/managers/{UserPreferencesManager.ts → UserPreferencesManager/UserPreferencesManager.ts} +2 -2
  171. package/src/lib/editor/shapes/ShapeUtil.ts +10 -1
  172. package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +8 -0
  173. package/src/lib/editor/shapes/shared/getPerfectDashProps.ts +5 -2
  174. package/src/lib/exports/getSvgJsx.tsx +1 -1
  175. package/src/lib/primitives/Box.test.ts +588 -7
  176. package/src/lib/primitives/Box.ts +33 -33
  177. package/src/lib/primitives/Vec.test.ts +2 -2
  178. package/src/lib/primitives/Vec.ts +15 -10
  179. package/src/lib/primitives/geometry/Arc2d.ts +42 -23
  180. package/src/lib/primitives/geometry/Circle2d.ts +12 -12
  181. package/src/lib/primitives/geometry/CubicBezier2d.test.ts +5 -0
  182. package/src/lib/primitives/geometry/CubicBezier2d.ts +13 -17
  183. package/src/lib/primitives/geometry/CubicSpline2d.ts +5 -5
  184. package/src/lib/primitives/geometry/Edge2d.ts +14 -25
  185. package/src/lib/primitives/geometry/Ellipse2d.ts +12 -13
  186. package/src/lib/primitives/geometry/Geometry2d.ts +6 -0
  187. package/src/lib/primitives/geometry/Point2d.ts +6 -6
  188. package/src/lib/primitives/geometry/Polygon2d.ts +4 -0
  189. package/src/lib/primitives/geometry/Polyline2d.ts +10 -7
  190. package/src/lib/primitives/geometry/Rectangle2d.ts +24 -11
  191. package/src/lib/primitives/geometry/Stadium2d.ts +22 -23
  192. package/src/lib/utils/reorderShapes.ts +10 -13
  193. package/src/lib/utils/richText.ts +10 -4
  194. package/src/version.ts +3 -3
  195. package/dist-cjs/lib/editor/managers/ClickManager.js.map +0 -7
  196. package/dist-cjs/lib/editor/managers/EdgeScrollManager.js.map +0 -7
  197. package/dist-cjs/lib/editor/managers/FocusManager.js.map +0 -7
  198. package/dist-cjs/lib/editor/managers/FontManager.js.map +0 -7
  199. package/dist-cjs/lib/editor/managers/HistoryManager.js.map +0 -7
  200. package/dist-cjs/lib/editor/managers/ScribbleManager.js.map +0 -7
  201. package/dist-cjs/lib/editor/managers/Stack.js +0 -82
  202. package/dist-cjs/lib/editor/managers/Stack.js.map +0 -7
  203. package/dist-cjs/lib/editor/managers/TextManager.js.map +0 -7
  204. package/dist-cjs/lib/editor/managers/TickManager.js.map +0 -7
  205. package/dist-cjs/lib/editor/managers/UserPreferencesManager.js.map +0 -7
  206. package/dist-esm/lib/editor/managers/ClickManager.mjs.map +0 -7
  207. package/dist-esm/lib/editor/managers/EdgeScrollManager.mjs.map +0 -7
  208. package/dist-esm/lib/editor/managers/FocusManager.mjs.map +0 -7
  209. package/dist-esm/lib/editor/managers/FontManager.mjs.map +0 -7
  210. package/dist-esm/lib/editor/managers/HistoryManager.mjs.map +0 -7
  211. package/dist-esm/lib/editor/managers/ScribbleManager.mjs.map +0 -7
  212. package/dist-esm/lib/editor/managers/Stack.mjs +0 -62
  213. package/dist-esm/lib/editor/managers/Stack.mjs.map +0 -7
  214. package/dist-esm/lib/editor/managers/TextManager.mjs.map +0 -7
  215. package/dist-esm/lib/editor/managers/TickManager.mjs.map +0 -7
  216. package/dist-esm/lib/editor/managers/UserPreferencesManager.mjs.map +0 -7
  217. package/src/lib/editor/managers/ScribbleManager.test.ts +0 -32
  218. package/src/lib/editor/managers/Stack.ts +0 -71
  219. /package/dist-cjs/lib/editor/managers/{TextManager.js → TextManager/TextManager.js} +0 -0
  220. /package/dist-esm/lib/editor/managers/{TextManager.mjs → TextManager/TextManager.mjs} +0 -0
@@ -32,20 +32,20 @@ class Circle2d extends import_Geometry2d.Geometry2d {
32
32
  super({ isClosed: true, ...config });
33
33
  this.config = config;
34
34
  const { x = 0, y = 0, radius } = config;
35
- this.x = x;
36
- this.y = y;
35
+ this._x = x;
36
+ this._y = y;
37
37
  this._center = new import_Vec.Vec(radius + x, radius + y);
38
- this.radius = radius;
38
+ this._radius = radius;
39
39
  }
40
40
  _center;
41
- radius;
42
- x;
43
- y;
41
+ _radius;
42
+ _x;
43
+ _y;
44
44
  getBounds() {
45
- return new import_Box.Box(this.x, this.y, this.radius * 2, this.radius * 2);
45
+ return new import_Box.Box(this._x, this._y, this._radius * 2, this._radius * 2);
46
46
  }
47
47
  getVertices() {
48
- const { _center, radius } = this;
48
+ const { _center, _radius: radius } = this;
49
49
  const perimeter = import_utils.PI2 * radius;
50
50
  const vertices = [];
51
51
  for (let i = 0, n = (0, import_geometry_constants.getVerticesCountForLength)(perimeter); i < n; i++) {
@@ -55,16 +55,16 @@ class Circle2d extends import_Geometry2d.Geometry2d {
55
55
  return vertices;
56
56
  }
57
57
  nearestPoint(point) {
58
- const { _center, radius } = this;
58
+ const { _center, _radius: radius } = this;
59
59
  if (_center.equals(point)) return import_Vec.Vec.AddXY(_center, radius, 0);
60
60
  return import_Vec.Vec.Sub(point, _center).uni().mul(radius).add(_center);
61
61
  }
62
62
  hitTestLineSegment(A, B, distance = 0) {
63
- const { _center, radius } = this;
63
+ const { _center, _radius: radius } = this;
64
64
  return (0, import_intersect.intersectLineSegmentCircle)(A, B, _center, radius + distance) !== null;
65
65
  }
66
66
  getSvgPathData() {
67
- const { _center, radius } = this;
67
+ const { _center, _radius: radius } = this;
68
68
  return `M${_center.x + radius},${_center.y} a${radius},${radius} 0 1,0 ${radius * 2},0a${radius},${radius} 0 1,0 -${radius * 2},0`;
69
69
  }
70
70
  }
@@ -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\t_center: Vec\n\tradius: number\n\tx: number\n\ty: 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 } = 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 } = 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 } = this\n\t\treturn intersectLineSegmentCircle(A, B, _center, radius + distance) !== null\n\t}\n\n\tgetSvgPathData(): string {\n\t\tconst { _center, 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,IAAI;AACT,SAAK,IAAI;AACT,SAAK,UAAU,IAAI,eAAI,SAAS,GAAG,SAAS,CAAC;AAC7C,SAAK,SAAS;AAAA,EACf;AAAA,EAnBA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAkBA,YAAY;AACX,WAAO,IAAI,eAAI,KAAK,GAAG,KAAK,GAAG,KAAK,SAAS,GAAG,KAAK,SAAS,CAAC;AAAA,EAChE;AAAA,EAEA,cAAqB;AACpB,UAAM,EAAE,SAAS,OAAO,IAAI;AAC5B,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,OAAO,IAAI;AAC5B,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,OAAO,IAAI;AAC5B,eAAO,6CAA2B,GAAG,GAAG,SAAS,SAAS,QAAQ,MAAM;AAAA,EACzE;AAAA,EAEA,iBAAyB;AACxB,UAAM,EAAE,SAAS,OAAO,IAAI;AAC5B,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 { 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;",
6
6
  "names": []
7
7
  }
@@ -24,21 +24,21 @@ module.exports = __toCommonJS(CubicBezier2d_exports);
24
24
  var import_Vec = require("../Vec");
25
25
  var import_Polyline2d = require("./Polyline2d");
26
26
  class CubicBezier2d extends import_Polyline2d.Polyline2d {
27
- a;
28
- b;
29
- c;
30
- d;
27
+ _a;
28
+ _b;
29
+ _c;
30
+ _d;
31
31
  constructor(config) {
32
32
  const { start: a, cp1: b, cp2: c, end: d } = config;
33
33
  super({ ...config, points: [a, d] });
34
- this.a = a;
35
- this.b = b;
36
- this.c = c;
37
- this.d = d;
34
+ this._a = a;
35
+ this._b = b;
36
+ this._c = c;
37
+ this._d = d;
38
38
  }
39
39
  getVertices() {
40
40
  const vertices = [];
41
- const { a, b, c, d } = this;
41
+ const { _a: a, _b: b, _c: c, _d: d } = this;
42
42
  for (let i = 0, n = 10; i <= n; i++) {
43
43
  const t = i / n;
44
44
  vertices.push(
@@ -50,9 +50,6 @@ class CubicBezier2d extends import_Polyline2d.Polyline2d {
50
50
  }
51
51
  return vertices;
52
52
  }
53
- midPoint() {
54
- return CubicBezier2d.GetAtT(this, 0.5);
55
- }
56
53
  nearestPoint(A) {
57
54
  let nearest;
58
55
  let dist = Infinity;
@@ -70,18 +67,18 @@ class CubicBezier2d extends import_Polyline2d.Polyline2d {
70
67
  return nearest;
71
68
  }
72
69
  getSvgPathData(first = true) {
73
- const { a, b, c, d } = this;
70
+ const { _a: a, _b: b, _c: c, _d: d } = this;
74
71
  return `${first ? `M ${a.toFixed()} ` : ``} C${b.toFixed()} ${c.toFixed()} ${d.toFixed()}`;
75
72
  }
76
73
  static GetAtT(segment, t) {
77
- const { a, b, c, d } = segment;
74
+ const { _a: a, _b: b, _c: c, _d: d } = segment;
78
75
  return new import_Vec.Vec(
79
76
  (1 - t) * (1 - t) * (1 - t) * a.x + 3 * ((1 - t) * (1 - t)) * t * b.x + 3 * (1 - t) * (t * t) * c.x + t * t * t * d.x,
80
77
  (1 - t) * (1 - t) * (1 - t) * a.y + 3 * ((1 - t) * (1 - t)) * t * b.y + 3 * (1 - t) * (t * t) * c.y + t * t * t * d.y
81
78
  );
82
79
  }
83
- getLength(filters, precision = 32) {
84
- let n1, p1 = this.a, length = 0;
80
+ getLength(_filters, precision = 32) {
81
+ let n1, p1 = this._a, length = 0;
85
82
  for (let i = 1; i <= precision; i++) {
86
83
  n1 = CubicBezier2d.GetAtT(this, i / precision);
87
84
  length += import_Vec.Vec.Dist(p1, n1);
@@ -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\ta: Vec\n\tb: Vec\n\tc: Vec\n\td: 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, b, c, 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\tmidPoint() {\n\t\treturn CubicBezier2d.GetAtT(this, 0.5)\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, b, c, 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, b, c, 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,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,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,IAAI;AACT,SAAK,IAAI;AACT,SAAK,IAAI;AACT,SAAK,IAAI;AAAA,EACV;AAAA,EAES,cAAc;AACtB,UAAM,WAAW,CAAC;AAClB,UAAM,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI;AAEvB,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,WAAW;AACV,WAAO,cAAc,OAAO,MAAM,GAAG;AAAA,EACtC;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,GAAG,GAAG,GAAG,EAAE,IAAI;AACvB,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,GAAG,GAAG,GAAG,EAAE,IAAI;AACvB,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,SAA6B,YAAY,IAAI;AAC/D,QAAI,IACH,KAAK,KAAK,GACV,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\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;",
6
6
  "names": []
7
7
  }
@@ -25,18 +25,18 @@ var import_Vec = require("../Vec");
25
25
  var import_CubicBezier2d = require("./CubicBezier2d");
26
26
  var import_Geometry2d = require("./Geometry2d");
27
27
  class CubicSpline2d extends import_Geometry2d.Geometry2d {
28
- points;
28
+ _points;
29
29
  constructor(config) {
30
30
  super({ ...config, isClosed: false, isFilled: false });
31
31
  const { points } = config;
32
- this.points = points;
32
+ this._points = points;
33
33
  }
34
34
  _segments;
35
35
  // eslint-disable-next-line no-restricted-syntax
36
36
  get segments() {
37
37
  if (!this._segments) {
38
38
  this._segments = [];
39
- const { points } = this;
39
+ const { _points: points } = this;
40
40
  const len = points.length;
41
41
  const last = len - 2;
42
42
  const k = 1.25;
@@ -58,7 +58,7 @@ class CubicSpline2d extends import_Geometry2d.Geometry2d {
58
58
  const vertices = this.segments.reduce((acc, segment) => {
59
59
  return acc.concat(segment.vertices);
60
60
  }, []);
61
- vertices.push(this.points[this.points.length - 1]);
61
+ vertices.push(this._points[this._points.length - 1]);
62
62
  return vertices;
63
63
  }
64
64
  nearestPoint(A) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/CubicSpline2d.ts"],
4
- "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { CubicBezier2d } from './CubicBezier2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class CubicSpline2d extends Geometry2d {\n\tpoints: Vec[]\n\n\tconstructor(config: Omit<Geometry2dOptions, 'isClosed' | 'isFilled'> & { points: Vec[] }) {\n\t\tsuper({ ...config, isClosed: false, isFilled: false })\n\t\tconst { points } = config\n\n\t\tthis.points = points\n\t}\n\n\t_segments?: CubicBezier2d[]\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget segments() {\n\t\tif (!this._segments) {\n\t\t\tthis._segments = []\n\t\t\tconst { points } = this\n\n\t\t\tconst len = points.length\n\t\t\tconst last = len - 2\n\t\t\tconst k = 1.25\n\n\t\t\tfor (let i = 0; i < len - 1; i++) {\n\t\t\t\tconst p0 = i === 0 ? points[0] : points[i - 1]\n\t\t\t\tconst p1 = points[i]\n\t\t\t\tconst p2 = points[i + 1]\n\t\t\t\tconst p3 = i === last ? p2 : points[i + 2]\n\t\t\t\tconst start = p1,\n\t\t\t\t\tcp1 =\n\t\t\t\t\t\ti === 0 ? p0 : new Vec(p1.x + ((p2.x - p0.x) / 6) * k, p1.y + ((p2.y - p0.y) / 6) * k),\n\t\t\t\t\tcp2 =\n\t\t\t\t\t\ti === last\n\t\t\t\t\t\t\t? p2\n\t\t\t\t\t\t\t: new Vec(p2.x - ((p3.x - p1.x) / 6) * k, p2.y - ((p3.y - p1.y) / 6) * k),\n\t\t\t\t\tend = p2\n\n\t\t\t\tthis._segments.push(new CubicBezier2d({ start, cp1, cp2, end }))\n\t\t\t}\n\t\t}\n\n\t\treturn this._segments\n\t}\n\n\toverride getLength() {\n\t\treturn this.segments.reduce((acc, segment) => acc + segment.length, 0)\n\t}\n\n\tgetVertices() {\n\t\tconst vertices = this.segments.reduce((acc, segment) => {\n\t\t\treturn acc.concat(segment.vertices)\n\t\t}, [] as Vec[])\n\t\tvertices.push(this.points[this.points.length - 1])\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 segment of this.segments) {\n\t\t\tp = segment.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.segments.some((segment) => segment.hitTestLineSegment(A, B))\n\t}\n\n\tgetSvgPathData() {\n\t\tlet d = this.segments.reduce((d, segment, i) => {\n\t\t\treturn d + segment.getSvgPathData(i === 0)\n\t\t}, '')\n\n\t\tif (this.isClosed) {\n\t\t\td += 'Z'\n\t\t}\n\n\t\treturn d\n\t}\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAA6B;AAC7B,2BAA8B;AAC9B,wBAA8C;AAGvC,MAAM,sBAAsB,6BAAW;AAAA,EAC7C;AAAA,EAEA,YAAY,QAA8E;AACzF,UAAM,EAAE,GAAG,QAAQ,UAAU,OAAO,UAAU,MAAM,CAAC;AACrD,UAAM,EAAE,OAAO,IAAI;AAEnB,SAAK,SAAS;AAAA,EACf;AAAA,EAEA;AAAA;AAAA,EAGA,IAAI,WAAW;AACd,QAAI,CAAC,KAAK,WAAW;AACpB,WAAK,YAAY,CAAC;AAClB,YAAM,EAAE,OAAO,IAAI;AAEnB,YAAM,MAAM,OAAO;AACnB,YAAM,OAAO,MAAM;AACnB,YAAM,IAAI;AAEV,eAAS,IAAI,GAAG,IAAI,MAAM,GAAG,KAAK;AACjC,cAAM,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC;AAC7C,cAAM,KAAK,OAAO,CAAC;AACnB,cAAM,KAAK,OAAO,IAAI,CAAC;AACvB,cAAM,KAAK,MAAM,OAAO,KAAK,OAAO,IAAI,CAAC;AACzC,cAAM,QAAQ,IACb,MACC,MAAM,IAAI,KAAK,IAAI,eAAI,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK,GAAG,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK,CAAC,GACtF,MACC,MAAM,OACH,KACA,IAAI,eAAI,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK,GAAG,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK,CAAC,GAC1E,MAAM;AAEP,aAAK,UAAU,KAAK,IAAI,mCAAc,EAAE,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC;AAAA,MAChE;AAAA,IACD;AAEA,WAAO,KAAK;AAAA,EACb;AAAA,EAES,YAAY;AACpB,WAAO,KAAK,SAAS,OAAO,CAAC,KAAK,YAAY,MAAM,QAAQ,QAAQ,CAAC;AAAA,EACtE;AAAA,EAEA,cAAc;AACb,UAAM,WAAW,KAAK,SAAS,OAAO,CAAC,KAAK,YAAY;AACvD,aAAO,IAAI,OAAO,QAAQ,QAAQ;AAAA,IACnC,GAAG,CAAC,CAAU;AACd,aAAS,KAAK,KAAK,OAAO,KAAK,OAAO,SAAS,CAAC,CAAC;AACjD,WAAO;AAAA,EACR;AAAA,EAEA,aAAa,GAAiB;AAC7B,QAAI;AACJ,QAAI,OAAO;AACX,QAAI;AACJ,QAAI;AACJ,eAAW,WAAW,KAAK,UAAU;AACpC,UAAI,QAAQ,aAAa,CAAC;AAC1B,UAAI,eAAI,MAAM,GAAG,CAAC;AAClB,UAAI,IAAI,MAAM;AACb,kBAAU;AACV,eAAO;AAAA,MACR;AAAA,IACD;AACA,QAAI,CAAC,QAAS,OAAM,MAAM,yBAAyB;AACnD,WAAO;AAAA,EACR;AAAA,EAEA,mBAAmB,GAAY,GAAqB;AACnD,WAAO,KAAK,SAAS,KAAK,CAAC,YAAY,QAAQ,mBAAmB,GAAG,CAAC,CAAC;AAAA,EACxE;AAAA,EAEA,iBAAiB;AAChB,QAAI,IAAI,KAAK,SAAS,OAAO,CAACA,IAAG,SAAS,MAAM;AAC/C,aAAOA,KAAI,QAAQ,eAAe,MAAM,CAAC;AAAA,IAC1C,GAAG,EAAE;AAEL,QAAI,KAAK,UAAU;AAClB,WAAK;AAAA,IACN;AAEA,WAAO;AAAA,EACR;AACD;",
4
+ "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { CubicBezier2d } from './CubicBezier2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class CubicSpline2d extends Geometry2d {\n\tprivate _points: Vec[]\n\n\tconstructor(config: Omit<Geometry2dOptions, 'isClosed' | 'isFilled'> & { points: Vec[] }) {\n\t\tsuper({ ...config, isClosed: false, isFilled: false })\n\t\tconst { points } = config\n\n\t\tthis._points = points\n\t}\n\n\tprivate _segments?: CubicBezier2d[]\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget segments() {\n\t\tif (!this._segments) {\n\t\t\tthis._segments = []\n\t\t\tconst { _points: points } = this\n\n\t\t\tconst len = points.length\n\t\t\tconst last = len - 2\n\t\t\tconst k = 1.25\n\n\t\t\tfor (let i = 0; i < len - 1; i++) {\n\t\t\t\tconst p0 = i === 0 ? points[0] : points[i - 1]\n\t\t\t\tconst p1 = points[i]\n\t\t\t\tconst p2 = points[i + 1]\n\t\t\t\tconst p3 = i === last ? p2 : points[i + 2]\n\t\t\t\tconst start = p1,\n\t\t\t\t\tcp1 =\n\t\t\t\t\t\ti === 0 ? p0 : new Vec(p1.x + ((p2.x - p0.x) / 6) * k, p1.y + ((p2.y - p0.y) / 6) * k),\n\t\t\t\t\tcp2 =\n\t\t\t\t\t\ti === last\n\t\t\t\t\t\t\t? p2\n\t\t\t\t\t\t\t: new Vec(p2.x - ((p3.x - p1.x) / 6) * k, p2.y - ((p3.y - p1.y) / 6) * k),\n\t\t\t\t\tend = p2\n\n\t\t\t\tthis._segments.push(new CubicBezier2d({ start, cp1, cp2, end }))\n\t\t\t}\n\t\t}\n\n\t\treturn this._segments\n\t}\n\n\toverride getLength() {\n\t\treturn this.segments.reduce((acc, segment) => acc + segment.length, 0)\n\t}\n\n\tgetVertices() {\n\t\tconst vertices = this.segments.reduce((acc, segment) => {\n\t\t\treturn acc.concat(segment.vertices)\n\t\t}, [] as Vec[])\n\t\tvertices.push(this._points[this._points.length - 1])\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 segment of this.segments) {\n\t\t\tp = segment.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.segments.some((segment) => segment.hitTestLineSegment(A, B))\n\t}\n\n\tgetSvgPathData() {\n\t\tlet d = this.segments.reduce((d, segment, i) => {\n\t\t\treturn d + segment.getSvgPathData(i === 0)\n\t\t}, '')\n\n\t\tif (this.isClosed) {\n\t\t\td += 'Z'\n\t\t}\n\n\t\treturn d\n\t}\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAA6B;AAC7B,2BAA8B;AAC9B,wBAA8C;AAGvC,MAAM,sBAAsB,6BAAW;AAAA,EACrC;AAAA,EAER,YAAY,QAA8E;AACzF,UAAM,EAAE,GAAG,QAAQ,UAAU,OAAO,UAAU,MAAM,CAAC;AACrD,UAAM,EAAE,OAAO,IAAI;AAEnB,SAAK,UAAU;AAAA,EAChB;AAAA,EAEQ;AAAA;AAAA,EAGR,IAAI,WAAW;AACd,QAAI,CAAC,KAAK,WAAW;AACpB,WAAK,YAAY,CAAC;AAClB,YAAM,EAAE,SAAS,OAAO,IAAI;AAE5B,YAAM,MAAM,OAAO;AACnB,YAAM,OAAO,MAAM;AACnB,YAAM,IAAI;AAEV,eAAS,IAAI,GAAG,IAAI,MAAM,GAAG,KAAK;AACjC,cAAM,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC;AAC7C,cAAM,KAAK,OAAO,CAAC;AACnB,cAAM,KAAK,OAAO,IAAI,CAAC;AACvB,cAAM,KAAK,MAAM,OAAO,KAAK,OAAO,IAAI,CAAC;AACzC,cAAM,QAAQ,IACb,MACC,MAAM,IAAI,KAAK,IAAI,eAAI,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK,GAAG,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK,CAAC,GACtF,MACC,MAAM,OACH,KACA,IAAI,eAAI,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK,GAAG,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK,CAAC,GAC1E,MAAM;AAEP,aAAK,UAAU,KAAK,IAAI,mCAAc,EAAE,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC;AAAA,MAChE;AAAA,IACD;AAEA,WAAO,KAAK;AAAA,EACb;AAAA,EAES,YAAY;AACpB,WAAO,KAAK,SAAS,OAAO,CAAC,KAAK,YAAY,MAAM,QAAQ,QAAQ,CAAC;AAAA,EACtE;AAAA,EAEA,cAAc;AACb,UAAM,WAAW,KAAK,SAAS,OAAO,CAAC,KAAK,YAAY;AACvD,aAAO,IAAI,OAAO,QAAQ,QAAQ;AAAA,IACnC,GAAG,CAAC,CAAU;AACd,aAAS,KAAK,KAAK,QAAQ,KAAK,QAAQ,SAAS,CAAC,CAAC;AACnD,WAAO;AAAA,EACR;AAAA,EAEA,aAAa,GAAiB;AAC7B,QAAI;AACJ,QAAI,OAAO;AACX,QAAI;AACJ,QAAI;AACJ,eAAW,WAAW,KAAK,UAAU;AACpC,UAAI,QAAQ,aAAa,CAAC;AAC1B,UAAI,eAAI,MAAM,GAAG,CAAC;AAClB,UAAI,IAAI,MAAM;AACb,kBAAU;AACV,eAAO;AAAA,MACR;AAAA,IACD;AACA,QAAI,CAAC,QAAS,OAAM,MAAM,yBAAyB;AACnD,WAAO;AAAA,EACR;AAAA,EAEA,mBAAmB,GAAY,GAAqB;AACnD,WAAO,KAAK,SAAS,KAAK,CAAC,YAAY,QAAQ,mBAAmB,GAAG,CAAC,CAAC;AAAA,EACxE;AAAA,EAEA,iBAAiB;AAChB,QAAI,IAAI,KAAK,SAAS,OAAO,CAACA,IAAG,SAAS,MAAM;AAC/C,aAAOA,KAAI,QAAQ,eAAe,MAAM,CAAC;AAAA,IAC1C,GAAG,EAAE;AAEL,QAAI,KAAK,UAAU;AAClB,WAAK;AAAA,IACN;AAEA,WAAO;AAAA,EACR;AACD;",
6
6
  "names": ["d"]
7
7
  }
@@ -21,35 +21,31 @@ __export(Edge2d_exports, {
21
21
  Edge2d: () => Edge2d
22
22
  });
23
23
  module.exports = __toCommonJS(Edge2d_exports);
24
- var import_intersect = require("../intersect");
25
24
  var import_Vec = require("../Vec");
26
25
  var import_Geometry2d = require("./Geometry2d");
27
26
  class Edge2d extends import_Geometry2d.Geometry2d {
28
- start;
29
- end;
30
- d;
31
- u;
32
- ul;
27
+ _start;
28
+ _end;
29
+ _d;
30
+ _u;
31
+ _ul;
33
32
  constructor(config) {
34
33
  super({ ...config, isClosed: false, isFilled: false });
35
34
  const { start, end } = config;
36
- this.start = start;
37
- this.end = end;
38
- this.d = start.clone().sub(end);
39
- this.u = this.d.clone().uni();
40
- this.ul = this.u.len();
35
+ this._start = start;
36
+ this._end = end;
37
+ this._d = start.clone().sub(end);
38
+ this._u = this._d.clone().uni();
39
+ this._ul = this._u.len();
41
40
  }
42
41
  getLength() {
43
- return this.d.len();
44
- }
45
- midPoint() {
46
- return this.start.lrp(this.end, 0.5);
42
+ return this._d.len();
47
43
  }
48
44
  getVertices() {
49
- return [this.start, this.end];
45
+ return [this._start, this._end];
50
46
  }
51
47
  nearestPoint(point) {
52
- const { start, end, d, u, ul: l } = this;
48
+ const { _start: start, _end: end, _d: d, _u: u, _ul: l } = this;
53
49
  if (d.len() === 0) return start;
54
50
  if (l === 0) return start;
55
51
  const k = import_Vec.Vec.Sub(point, start).dpr(u) / l;
@@ -61,11 +57,8 @@ class Edge2d extends import_Geometry2d.Geometry2d {
61
57
  if (cy > Math.max(start.y, end.y)) return start.y > end.y ? start : end;
62
58
  return new import_Vec.Vec(cx, cy);
63
59
  }
64
- hitTestLineSegment(A, B, distance = 0) {
65
- return (0, import_intersect.linesIntersect)(A, B, this.start, this.end) || this.distanceToLineSegment(A, B) <= distance;
66
- }
67
60
  getSvgPathData(first = true) {
68
- const { start, end } = this;
61
+ const { _start: start, _end: end } = this;
69
62
  return `${first ? `M${start.toFixed()}` : ``} L${end.toFixed()}`;
70
63
  }
71
64
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Edge2d.ts"],
4
- "sourcesContent": ["import { linesIntersect } from '../intersect'\nimport { Vec, VecLike } from '../Vec'\nimport { Geometry2d } from './Geometry2d'\n\n/** @public */\nexport class Edge2d extends Geometry2d {\n\tstart: Vec\n\tend: Vec\n\td: Vec\n\tu: Vec\n\tul: number\n\n\tconstructor(config: { start: Vec; end: Vec }) {\n\t\tsuper({ ...config, isClosed: false, isFilled: false })\n\t\tconst { start, end } = config\n\n\t\tthis.start = start\n\t\tthis.end = end\n\n\t\tthis.d = start.clone().sub(end) // the delta from start to end\n\t\tthis.u = this.d.clone().uni() // the unit vector of the edge\n\t\tthis.ul = this.u.len() // the length of the unit vector\n\t}\n\n\toverride getLength() {\n\t\treturn this.d.len()\n\t}\n\n\tmidPoint(): Vec {\n\t\treturn this.start.lrp(this.end, 0.5)\n\t}\n\n\toverride getVertices(): Vec[] {\n\t\treturn [this.start, this.end]\n\t}\n\n\toverride nearestPoint(point: VecLike): Vec {\n\t\tconst { start, end, d, u, ul: l } = this\n\t\tif (d.len() === 0) return start // start and end are the same\n\t\tif (l === 0) return start // no length in the unit vector\n\t\tconst k = Vec.Sub(point, start).dpr(u) / l\n\t\tconst cx = start.x + u.x * k\n\t\tif (cx < Math.min(start.x, end.x)) return start.x < end.x ? start : end\n\t\tif (cx > Math.max(start.x, end.x)) return start.x > end.x ? start : end\n\t\tconst cy = start.y + u.y * k\n\t\tif (cy < Math.min(start.y, end.y)) return start.y < end.y ? start : end\n\t\tif (cy > Math.max(start.y, end.y)) return start.y > end.y ? start : end\n\t\treturn new Vec(cx, cy)\n\t}\n\n\toverride hitTestLineSegment(A: VecLike, B: VecLike, distance = 0): boolean {\n\t\treturn (\n\t\t\tlinesIntersect(A, B, this.start, this.end) || this.distanceToLineSegment(A, B) <= distance\n\t\t)\n\t}\n\n\tgetSvgPathData(first = true) {\n\t\tconst { start, end } = this\n\t\treturn `${first ? `M${start.toFixed()}` : ``} L${end.toFixed()}`\n\t}\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAA+B;AAC/B,iBAA6B;AAC7B,wBAA2B;AAGpB,MAAM,eAAe,6BAAW;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,QAAkC;AAC7C,UAAM,EAAE,GAAG,QAAQ,UAAU,OAAO,UAAU,MAAM,CAAC;AACrD,UAAM,EAAE,OAAO,IAAI,IAAI;AAEvB,SAAK,QAAQ;AACb,SAAK,MAAM;AAEX,SAAK,IAAI,MAAM,MAAM,EAAE,IAAI,GAAG;AAC9B,SAAK,IAAI,KAAK,EAAE,MAAM,EAAE,IAAI;AAC5B,SAAK,KAAK,KAAK,EAAE,IAAI;AAAA,EACtB;AAAA,EAES,YAAY;AACpB,WAAO,KAAK,EAAE,IAAI;AAAA,EACnB;AAAA,EAEA,WAAgB;AACf,WAAO,KAAK,MAAM,IAAI,KAAK,KAAK,GAAG;AAAA,EACpC;AAAA,EAES,cAAqB;AAC7B,WAAO,CAAC,KAAK,OAAO,KAAK,GAAG;AAAA,EAC7B;AAAA,EAES,aAAa,OAAqB;AAC1C,UAAM,EAAE,OAAO,KAAK,GAAG,GAAG,IAAI,EAAE,IAAI;AACpC,QAAI,EAAE,IAAI,MAAM,EAAG,QAAO;AAC1B,QAAI,MAAM,EAAG,QAAO;AACpB,UAAM,IAAI,eAAI,IAAI,OAAO,KAAK,EAAE,IAAI,CAAC,IAAI;AACzC,UAAM,KAAK,MAAM,IAAI,EAAE,IAAI;AAC3B,QAAI,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,EAAG,QAAO,MAAM,IAAI,IAAI,IAAI,QAAQ;AACpE,QAAI,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,EAAG,QAAO,MAAM,IAAI,IAAI,IAAI,QAAQ;AACpE,UAAM,KAAK,MAAM,IAAI,EAAE,IAAI;AAC3B,QAAI,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,EAAG,QAAO,MAAM,IAAI,IAAI,IAAI,QAAQ;AACpE,QAAI,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,EAAG,QAAO,MAAM,IAAI,IAAI,IAAI,QAAQ;AACpE,WAAO,IAAI,eAAI,IAAI,EAAE;AAAA,EACtB;AAAA,EAES,mBAAmB,GAAY,GAAY,WAAW,GAAY;AAC1E,eACC,iCAAe,GAAG,GAAG,KAAK,OAAO,KAAK,GAAG,KAAK,KAAK,sBAAsB,GAAG,CAAC,KAAK;AAAA,EAEpF;AAAA,EAEA,eAAe,QAAQ,MAAM;AAC5B,UAAM,EAAE,OAAO,IAAI,IAAI;AACvB,WAAO,GAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,KAAK,EAAE,KAAK,IAAI,QAAQ,CAAC;AAAA,EAC/D;AACD;",
4
+ "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { Geometry2d } from './Geometry2d'\n\n/** @public */\nexport class Edge2d extends Geometry2d {\n\tprivate _start: Vec\n\tprivate _end: Vec\n\tprivate _d: Vec\n\tprivate _u: Vec\n\tprivate _ul: number\n\n\tconstructor(config: { start: Vec; end: Vec }) {\n\t\tsuper({ ...config, isClosed: false, isFilled: false })\n\t\tconst { start, end } = config\n\n\t\tthis._start = start\n\t\tthis._end = end\n\n\t\tthis._d = start.clone().sub(end) // the delta from start to end\n\t\tthis._u = this._d.clone().uni() // the unit vector of the edge\n\t\tthis._ul = this._u.len() // the length of the unit vector\n\t}\n\n\toverride getLength() {\n\t\treturn this._d.len()\n\t}\n\n\toverride getVertices(): Vec[] {\n\t\treturn [this._start, this._end]\n\t}\n\n\toverride nearestPoint(point: VecLike): Vec {\n\t\tconst { _start: start, _end: end, _d: d, _u: u, _ul: l } = this\n\t\tif (d.len() === 0) return start // start and end are the same\n\t\tif (l === 0) return start // no length in the unit vector\n\t\tconst k = Vec.Sub(point, start).dpr(u) / l\n\t\tconst cx = start.x + u.x * k\n\t\tif (cx < Math.min(start.x, end.x)) return start.x < end.x ? start : end\n\t\tif (cx > Math.max(start.x, end.x)) return start.x > end.x ? start : end\n\t\tconst cy = start.y + u.y * k\n\t\tif (cy < Math.min(start.y, end.y)) return start.y < end.y ? start : end\n\t\tif (cy > Math.max(start.y, end.y)) return start.y > end.y ? start : end\n\t\treturn new Vec(cx, cy)\n\t}\n\n\tgetSvgPathData(first = true) {\n\t\tconst { _start: start, _end: end } = this\n\t\treturn `${first ? `M${start.toFixed()}` : ``} L${end.toFixed()}`\n\t}\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAA6B;AAC7B,wBAA2B;AAGpB,MAAM,eAAe,6BAAW;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,QAAkC;AAC7C,UAAM,EAAE,GAAG,QAAQ,UAAU,OAAO,UAAU,MAAM,CAAC;AACrD,UAAM,EAAE,OAAO,IAAI,IAAI;AAEvB,SAAK,SAAS;AACd,SAAK,OAAO;AAEZ,SAAK,KAAK,MAAM,MAAM,EAAE,IAAI,GAAG;AAC/B,SAAK,KAAK,KAAK,GAAG,MAAM,EAAE,IAAI;AAC9B,SAAK,MAAM,KAAK,GAAG,IAAI;AAAA,EACxB;AAAA,EAES,YAAY;AACpB,WAAO,KAAK,GAAG,IAAI;AAAA,EACpB;AAAA,EAES,cAAqB;AAC7B,WAAO,CAAC,KAAK,QAAQ,KAAK,IAAI;AAAA,EAC/B;AAAA,EAES,aAAa,OAAqB;AAC1C,UAAM,EAAE,QAAQ,OAAO,MAAM,KAAK,IAAI,GAAG,IAAI,GAAG,KAAK,EAAE,IAAI;AAC3D,QAAI,EAAE,IAAI,MAAM,EAAG,QAAO;AAC1B,QAAI,MAAM,EAAG,QAAO;AACpB,UAAM,IAAI,eAAI,IAAI,OAAO,KAAK,EAAE,IAAI,CAAC,IAAI;AACzC,UAAM,KAAK,MAAM,IAAI,EAAE,IAAI;AAC3B,QAAI,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,EAAG,QAAO,MAAM,IAAI,IAAI,IAAI,QAAQ;AACpE,QAAI,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,EAAG,QAAO,MAAM,IAAI,IAAI,IAAI,QAAQ;AACpE,UAAM,KAAK,MAAM,IAAI,EAAE,IAAI;AAC3B,QAAI,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,EAAG,QAAO,MAAM,IAAI,IAAI,IAAI,QAAQ;AACpE,QAAI,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,EAAG,QAAO,MAAM,IAAI,IAAI,IAAI,QAAQ;AACpE,WAAO,IAAI,eAAI,IAAI,EAAE;AAAA,EACtB;AAAA,EAEA,eAAe,QAAQ,MAAM;AAC5B,UAAM,EAAE,QAAQ,OAAO,MAAM,IAAI,IAAI;AACrC,WAAO,GAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,KAAK,EAAE,KAAK,IAAI,QAAQ,CAAC;AAAA,EAC/D;AACD;",
6
6
  "names": []
7
7
  }
@@ -32,11 +32,11 @@ class Ellipse2d extends import_Geometry2d.Geometry2d {
32
32
  super({ ...config, isClosed: true });
33
33
  this.config = config;
34
34
  const { width, height } = config;
35
- this.w = width;
36
- this.h = height;
35
+ this._w = width;
36
+ this._h = height;
37
37
  }
38
- w;
39
- h;
38
+ _w;
39
+ _h;
40
40
  _edges;
41
41
  // eslint-disable-next-line no-restricted-syntax
42
42
  get edges() {
@@ -52,8 +52,8 @@ class Ellipse2d extends import_Geometry2d.Geometry2d {
52
52
  return this._edges;
53
53
  }
54
54
  getVertices() {
55
- const w = Math.max(1, this.w);
56
- const h = Math.max(1, this.h);
55
+ const w = Math.max(1, this._w);
56
+ const h = Math.max(1, this._h);
57
57
  const cx = w / 2;
58
58
  const cy = h / 2;
59
59
  const q = Math.pow(cx - cy, 2) / Math.pow(cx + cy, 2);
@@ -68,7 +68,7 @@ class Ellipse2d extends import_Geometry2d.Geometry2d {
68
68
  let tc = 1;
69
69
  const vertices = Array(len);
70
70
  for (let i = 0; i < len; i++) {
71
- vertices[i] = new import_Vec.Vec(cx + cx * cos, cy + cy * sin);
71
+ vertices[i] = new import_Vec.Vec((0, import_utils.clamp)(cx + cx * cos, 0, w), (0, import_utils.clamp)(cy + cy * sin, 0, h));
72
72
  ts = b * cos + a * sin;
73
73
  tc = a * cos - b * sin;
74
74
  sin = ts;
@@ -96,10 +96,10 @@ class Ellipse2d extends import_Geometry2d.Geometry2d {
96
96
  return this.edges.some((edge) => edge.hitTestLineSegment(A, B));
97
97
  }
98
98
  getBounds() {
99
- return new import_Box.Box(0, 0, this.w, this.h);
99
+ return new import_Box.Box(0, 0, this._w, this._h);
100
100
  }
101
101
  getLength() {
102
- const { w, h } = this;
102
+ const { _w: w, _h: h } = this;
103
103
  const cx = w / 2;
104
104
  const cy = h / 2;
105
105
  const rx = Math.max(0, cx);
@@ -107,7 +107,7 @@ class Ellipse2d extends import_Geometry2d.Geometry2d {
107
107
  return (0, import_utils.perimeterOfEllipse)(rx, ry);
108
108
  }
109
109
  getSvgPathData(first = false) {
110
- const { w, h } = this;
110
+ const { _w: w, _h: h } = this;
111
111
  const cx = w / 2;
112
112
  const cy = h / 2;
113
113
  const rx = Math.max(0, cx);
@@ -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, 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\tw: number\n\th: number\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_edges?: Edge2d[]\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(cx + cx * cos, cy + cy * sin)\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, 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, 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 { 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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",
6
6
  "names": []
7
7
  }
@@ -74,8 +74,13 @@ class Geometry2d {
74
74
  let nearest;
75
75
  let dist = Infinity;
76
76
  let d, p, q;
77
+ const nextLimit = this.isClosed ? vertices.length : vertices.length - 1;
77
78
  for (let i = 0; i < vertices.length; i++) {
78
79
  p = vertices[i];
80
+ if (i < nextLimit) {
81
+ const next = vertices[(i + 1) % vertices.length];
82
+ if ((0, import_intersect.linesIntersect)(A, B, p, next)) return 0;
83
+ }
79
84
  q = import_Vec.Vec.NearestPointOnLineSegment(A, B, p, true);
80
85
  d = import_Vec.Vec.Dist2(p, q);
81
86
  if (d < dist) {
@@ -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} 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\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\tisFilled = false\n\tisClosed = true\n\tisLabel = false\n\tisInternal = false\n\tdebugColor?: string\n\tignore?: boolean\n\n\tconstructor(opts: Geometry2dOptions) {\n\t\tthis.isFilled = opts.isFilled\n\t\tthis.isClosed = opts.isClosed\n\t\tthis.isLabel = opts.isLabel ?? false\n\t\tthis.isInternal = opts.isInternal ?? false\n\t\tthis.debugColor = opts.debugColor\n\t\tthis.ignore = opts.ignore\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\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 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} 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\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\tisFilled = false\n\tisClosed = true\n\tisLabel = false\n\tisInternal = false\n\tdebugColor?: string\n\tignore?: boolean\n\n\tconstructor(opts: Geometry2dOptions) {\n\t\tthis.isFilled = opts.isFilled\n\t\tthis.isClosed = opts.isClosed\n\t\tthis.isLabel = opts.isLabel ?? false\n\t\tthis.isInternal = opts.isInternal ?? false\n\t\tthis.debugColor = opts.debugColor\n\t\tthis.ignore = opts.ignore\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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",
6
6
  "names": ["import_utils"]
7
7
  }
@@ -24,23 +24,23 @@ module.exports = __toCommonJS(Point2d_exports);
24
24
  var import_Vec = require("../Vec");
25
25
  var import_Geometry2d = require("./Geometry2d");
26
26
  class Point2d extends import_Geometry2d.Geometry2d {
27
- point;
27
+ _point;
28
28
  constructor(config) {
29
29
  super({ ...config, isClosed: true, isFilled: true });
30
30
  const { point } = config;
31
- this.point = point;
31
+ this._point = point;
32
32
  }
33
33
  getVertices() {
34
- return [this.point];
34
+ return [this._point];
35
35
  }
36
36
  nearestPoint() {
37
- return this.point;
37
+ return this._point;
38
38
  }
39
39
  hitTestLineSegment(A, B, margin) {
40
- return import_Vec.Vec.DistanceToLineSegment(A, B, this.point) < margin;
40
+ return import_Vec.Vec.DistanceToLineSegment(A, B, this._point) < margin;
41
41
  }
42
42
  getSvgPathData() {
43
- const { point } = this;
43
+ const { _point: point } = this;
44
44
  return `M${point.toFixed()}`;
45
45
  }
46
46
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Point2d.ts"],
4
- "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Point2d extends Geometry2d {\n\tpoint: Vec\n\n\tconstructor(\n\t\tconfig: Omit<Geometry2dOptions, 'isClosed' | 'isFilled'> & { margin: number; point: Vec }\n\t) {\n\t\tsuper({ ...config, isClosed: true, isFilled: true })\n\t\tconst { point } = config\n\n\t\tthis.point = point\n\t}\n\n\tgetVertices() {\n\t\treturn [this.point]\n\t}\n\n\tnearestPoint(): Vec {\n\t\treturn this.point\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike, margin: number): boolean {\n\t\treturn Vec.DistanceToLineSegment(A, B, this.point) < margin\n\t}\n\n\tgetSvgPathData() {\n\t\tconst { point } = this\n\t\treturn `M${point.toFixed()}`\n\t}\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAA6B;AAC7B,wBAA8C;AAGvC,MAAM,gBAAgB,6BAAW;AAAA,EACvC;AAAA,EAEA,YACC,QACC;AACD,UAAM,EAAE,GAAG,QAAQ,UAAU,MAAM,UAAU,KAAK,CAAC;AACnD,UAAM,EAAE,MAAM,IAAI;AAElB,SAAK,QAAQ;AAAA,EACd;AAAA,EAEA,cAAc;AACb,WAAO,CAAC,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,eAAoB;AACnB,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,mBAAmB,GAAY,GAAY,QAAyB;AACnE,WAAO,eAAI,sBAAsB,GAAG,GAAG,KAAK,KAAK,IAAI;AAAA,EACtD;AAAA,EAEA,iBAAiB;AAChB,UAAM,EAAE,MAAM,IAAI;AAClB,WAAO,IAAI,MAAM,QAAQ,CAAC;AAAA,EAC3B;AACD;",
4
+ "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Point2d extends Geometry2d {\n\tprivate _point: Vec\n\n\tconstructor(\n\t\tconfig: Omit<Geometry2dOptions, 'isClosed' | 'isFilled'> & { margin: number; point: Vec }\n\t) {\n\t\tsuper({ ...config, isClosed: true, isFilled: true })\n\t\tconst { point } = config\n\n\t\tthis._point = point\n\t}\n\n\tgetVertices() {\n\t\treturn [this._point]\n\t}\n\n\tnearestPoint(): Vec {\n\t\treturn this._point\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike, margin: number): boolean {\n\t\treturn Vec.DistanceToLineSegment(A, B, this._point) < margin\n\t}\n\n\tgetSvgPathData() {\n\t\tconst { _point: point } = this\n\t\treturn `M${point.toFixed()}`\n\t}\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAA6B;AAC7B,wBAA8C;AAGvC,MAAM,gBAAgB,6BAAW;AAAA,EAC/B;AAAA,EAER,YACC,QACC;AACD,UAAM,EAAE,GAAG,QAAQ,UAAU,MAAM,UAAU,KAAK,CAAC;AACnD,UAAM,EAAE,MAAM,IAAI;AAElB,SAAK,SAAS;AAAA,EACf;AAAA,EAEA,cAAc;AACb,WAAO,CAAC,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,eAAoB;AACnB,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,mBAAmB,GAAY,GAAY,QAAyB;AACnE,WAAO,eAAI,sBAAsB,GAAG,GAAG,KAAK,MAAM,IAAI;AAAA,EACvD;AAAA,EAEA,iBAAiB;AAChB,UAAM,EAAE,QAAQ,MAAM,IAAI;AAC1B,WAAO,IAAI,MAAM,QAAQ,CAAC;AAAA,EAC3B;AACD;",
6
6
  "names": []
7
7
  }
@@ -26,6 +26,9 @@ class Polygon2d extends import_Polyline2d.Polyline2d {
26
26
  constructor(config) {
27
27
  super({ ...config });
28
28
  this.isClosed = true;
29
+ if (config.points.length < 3) {
30
+ throw new Error("Polygon2d: points must be an array of at least 3 points");
31
+ }
29
32
  }
30
33
  }
31
34
  //# sourceMappingURL=Polygon2d.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Polygon2d.ts"],
4
- "sourcesContent": ["import { Vec } from '../Vec'\nimport { Geometry2dOptions } from './Geometry2d'\nimport { Polyline2d } from './Polyline2d'\n\n/** @public */\nexport class Polygon2d extends Polyline2d {\n\tconstructor(config: Omit<Geometry2dOptions, 'isClosed'> & { points: Vec[] }) {\n\t\tsuper({ ...config })\n\t\tthis.isClosed = true\n\t}\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,wBAA2B;AAGpB,MAAM,kBAAkB,6BAAW;AAAA,EACzC,YAAY,QAAiE;AAC5E,UAAM,EAAE,GAAG,OAAO,CAAC;AACnB,SAAK,WAAW;AAAA,EACjB;AACD;",
4
+ "sourcesContent": ["import { Vec } from '../Vec'\nimport { Geometry2dOptions } from './Geometry2d'\nimport { Polyline2d } from './Polyline2d'\n\n/** @public */\nexport class Polygon2d extends Polyline2d {\n\tconstructor(config: Omit<Geometry2dOptions, 'isClosed'> & { points: Vec[] }) {\n\t\tsuper({ ...config })\n\t\tthis.isClosed = true\n\n\t\tif (config.points.length < 3) {\n\t\t\tthrow new Error('Polygon2d: points must be an array of at least 3 points')\n\t\t}\n\t}\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,wBAA2B;AAGpB,MAAM,kBAAkB,6BAAW;AAAA,EACzC,YAAY,QAAiE;AAC5E,UAAM,EAAE,GAAG,OAAO,CAAC;AACnB,SAAK,WAAW;AAEhB,QAAI,OAAO,OAAO,SAAS,GAAG;AAC7B,YAAM,IAAI,MAAM,yDAAyD;AAAA,IAC1E;AAAA,EACD;AACD;",
6
6
  "names": []
7
7
  }