@js-draw/math 1.17.0 → 1.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. package/dist/cjs/Mat33.js +6 -1
  2. package/dist/cjs/Vec3.d.ts +2 -1
  3. package/dist/cjs/Vec3.js +5 -7
  4. package/dist/cjs/lib.d.ts +2 -1
  5. package/dist/cjs/lib.js +5 -1
  6. package/dist/cjs/shapes/BezierJSWrapper.d.ts +4 -0
  7. package/dist/cjs/shapes/BezierJSWrapper.js +35 -0
  8. package/dist/cjs/shapes/LineSegment2.d.ts +11 -0
  9. package/dist/cjs/shapes/LineSegment2.js +26 -1
  10. package/dist/cjs/shapes/Parameterized2DShape.d.ts +6 -1
  11. package/dist/cjs/shapes/Parameterized2DShape.js +6 -1
  12. package/dist/cjs/shapes/Path.d.ts +96 -12
  13. package/dist/cjs/shapes/Path.js +338 -15
  14. package/dist/cjs/shapes/QuadraticBezier.d.ts +2 -3
  15. package/dist/cjs/shapes/QuadraticBezier.js +2 -3
  16. package/dist/cjs/shapes/Rect2.d.ts +6 -1
  17. package/dist/cjs/shapes/Rect2.js +5 -1
  18. package/dist/cjs/utils/convexHull2Of.d.ts +9 -0
  19. package/dist/cjs/utils/convexHull2Of.js +61 -0
  20. package/dist/cjs/utils/convexHull2Of.test.d.ts +1 -0
  21. package/dist/mjs/Mat33.mjs +6 -1
  22. package/dist/mjs/Vec3.d.ts +2 -1
  23. package/dist/mjs/Vec3.mjs +5 -7
  24. package/dist/mjs/lib.d.ts +2 -1
  25. package/dist/mjs/lib.mjs +2 -1
  26. package/dist/mjs/shapes/BezierJSWrapper.d.ts +4 -0
  27. package/dist/mjs/shapes/BezierJSWrapper.mjs +35 -0
  28. package/dist/mjs/shapes/LineSegment2.d.ts +11 -0
  29. package/dist/mjs/shapes/LineSegment2.mjs +26 -1
  30. package/dist/mjs/shapes/Parameterized2DShape.d.ts +6 -1
  31. package/dist/mjs/shapes/Parameterized2DShape.mjs +6 -1
  32. package/dist/mjs/shapes/Path.d.ts +96 -12
  33. package/dist/mjs/shapes/Path.mjs +335 -14
  34. package/dist/mjs/shapes/QuadraticBezier.d.ts +2 -3
  35. package/dist/mjs/shapes/QuadraticBezier.mjs +2 -3
  36. package/dist/mjs/shapes/Rect2.d.ts +6 -1
  37. package/dist/mjs/shapes/Rect2.mjs +5 -1
  38. package/dist/mjs/utils/convexHull2Of.d.ts +9 -0
  39. package/dist/mjs/utils/convexHull2Of.mjs +59 -0
  40. package/dist/mjs/utils/convexHull2Of.test.d.ts +1 -0
  41. package/package.json +2 -2
  42. package/src/Mat33.ts +8 -2
  43. package/src/Vec3.test.ts +16 -0
  44. package/src/Vec3.ts +7 -8
  45. package/src/lib.ts +3 -0
  46. package/src/shapes/BezierJSWrapper.ts +41 -0
  47. package/src/shapes/LineSegment2.test.ts +26 -0
  48. package/src/shapes/LineSegment2.ts +31 -1
  49. package/src/shapes/Parameterized2DShape.ts +6 -1
  50. package/src/shapes/Path.test.ts +173 -5
  51. package/src/shapes/Path.ts +390 -18
  52. package/src/shapes/QuadraticBezier.test.ts +21 -0
  53. package/src/shapes/QuadraticBezier.ts +2 -3
  54. package/src/shapes/Rect2.ts +6 -2
  55. package/src/utils/convexHull2Of.test.ts +43 -0
  56. package/src/utils/convexHull2Of.ts +71 -0
package/dist/cjs/Mat33.js CHANGED
@@ -340,7 +340,11 @@ class Mat33 {
340
340
  return Mat33.identity;
341
341
  }
342
342
  const parseArguments = (argumentString) => {
343
- return argumentString.split(/[, \t\n]+/g).map(argString => {
343
+ const parsed = argumentString.split(/[, \t\n]+/g).map(argString => {
344
+ // Handle trailing spaces/commands
345
+ if (argString.trim() === '') {
346
+ return null;
347
+ }
344
348
  let isPercentage = false;
345
349
  if (argString.endsWith('%')) {
346
350
  isPercentage = true;
@@ -361,6 +365,7 @@ class Mat33 {
361
365
  }
362
366
  return argNumber;
363
367
  });
368
+ return parsed.filter(n => n !== null);
364
369
  };
365
370
  const keywordToAction = {
366
371
  matrix: (matrixData) => {
@@ -134,7 +134,8 @@ export declare class Vec3 {
134
134
  * Returns a vector with each component acted on by `fn`.
135
135
  *
136
136
  * @example
137
- * ```
137
+ * ```ts,runnable,console
138
+ * import { Vec3 } from '@js-draw/math';
138
139
  * console.log(Vec3.of(1, 2, 3).map(val => val + 1)); // → Vec(2, 3, 4)
139
140
  * ```
140
141
  */
package/dist/cjs/Vec3.js CHANGED
@@ -206,7 +206,8 @@ class Vec3 {
206
206
  * Returns a vector with each component acted on by `fn`.
207
207
  *
208
208
  * @example
209
- * ```
209
+ * ```ts,runnable,console
210
+ * import { Vec3 } from '@js-draw/math';
210
211
  * console.log(Vec3.of(1, 2, 3).map(val => val + 1)); // → Vec(2, 3, 4)
211
212
  * ```
212
213
  */
@@ -230,12 +231,9 @@ class Vec3 {
230
231
  * ```
231
232
  */
232
233
  eq(other, fuzz = 1e-10) {
233
- for (let i = 0; i < 3; i++) {
234
- if (Math.abs(other.at(i) - this.at(i)) > fuzz) {
235
- return false;
236
- }
237
- }
238
- return true;
234
+ return (Math.abs(other.x - this.x) <= fuzz
235
+ && Math.abs(other.y - this.y) <= fuzz
236
+ && Math.abs(other.z - this.z) <= fuzz);
239
237
  }
240
238
  toString() {
241
239
  return `Vec(${this.x}, ${this.y}, ${this.z})`;
package/dist/cjs/lib.d.ts CHANGED
@@ -17,8 +17,9 @@
17
17
  * @packageDocumentation
18
18
  */
19
19
  export { LineSegment2 } from './shapes/LineSegment2';
20
- export { Path, IntersectionResult as PathIntersectionResult, CurveIndexRecord as PathCurveIndex, PathCommandType, PathCommand, LinePathCommand, MoveToPathCommand, QuadraticBezierPathCommand, CubicBezierPathCommand, } from './shapes/Path';
20
+ export { Path, IntersectionResult as PathIntersectionResult, CurveIndexRecord as PathCurveIndex, stepCurveIndexBy as stepPathIndexBy, compareCurveIndices as comparePathIndices, PathCommandType, PathCommand, LinePathCommand, MoveToPathCommand, QuadraticBezierPathCommand, CubicBezierPathCommand, } from './shapes/Path';
21
21
  export { Rect2 } from './shapes/Rect2';
22
+ export { Parameterized2DShape } from './shapes/Parameterized2DShape';
22
23
  export { QuadraticBezier } from './shapes/QuadraticBezier';
23
24
  export { Abstract2DShape } from './shapes/Abstract2DShape';
24
25
  export { Mat33, Mat33Array } from './Mat33';
package/dist/cjs/lib.js CHANGED
@@ -32,14 +32,18 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
32
32
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
33
33
  };
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.Color4 = exports.Vec3 = exports.Vec2 = exports.Mat33 = exports.Abstract2DShape = exports.QuadraticBezier = exports.Rect2 = exports.PathCommandType = exports.Path = exports.LineSegment2 = void 0;
35
+ exports.Color4 = exports.Vec3 = exports.Vec2 = exports.Mat33 = exports.Abstract2DShape = exports.QuadraticBezier = exports.Parameterized2DShape = exports.Rect2 = exports.PathCommandType = exports.comparePathIndices = exports.stepPathIndexBy = exports.Path = exports.LineSegment2 = void 0;
36
36
  var LineSegment2_1 = require("./shapes/LineSegment2");
37
37
  Object.defineProperty(exports, "LineSegment2", { enumerable: true, get: function () { return LineSegment2_1.LineSegment2; } });
38
38
  var Path_1 = require("./shapes/Path");
39
39
  Object.defineProperty(exports, "Path", { enumerable: true, get: function () { return Path_1.Path; } });
40
+ Object.defineProperty(exports, "stepPathIndexBy", { enumerable: true, get: function () { return Path_1.stepCurveIndexBy; } });
41
+ Object.defineProperty(exports, "comparePathIndices", { enumerable: true, get: function () { return Path_1.compareCurveIndices; } });
40
42
  Object.defineProperty(exports, "PathCommandType", { enumerable: true, get: function () { return Path_1.PathCommandType; } });
41
43
  var Rect2_1 = require("./shapes/Rect2");
42
44
  Object.defineProperty(exports, "Rect2", { enumerable: true, get: function () { return Rect2_1.Rect2; } });
45
+ var Parameterized2DShape_1 = require("./shapes/Parameterized2DShape");
46
+ Object.defineProperty(exports, "Parameterized2DShape", { enumerable: true, get: function () { return Parameterized2DShape_1.Parameterized2DShape; } });
43
47
  var QuadraticBezier_1 = require("./shapes/QuadraticBezier");
44
48
  Object.defineProperty(exports, "QuadraticBezier", { enumerable: true, get: function () { return QuadraticBezier_1.QuadraticBezier; } });
45
49
  var Abstract2DShape_1 = require("./shapes/Abstract2DShape");
@@ -41,6 +41,10 @@ export declare abstract class BezierJSWrapper extends Parameterized2DShape {
41
41
  parameterValue: number;
42
42
  point: import("../Vec3").Vec3;
43
43
  };
44
+ intersectsBezier(other: BezierJSWrapper): {
45
+ parameterValue: number;
46
+ point: import("../Vec3").Vec3;
47
+ }[];
44
48
  toString(): string;
45
49
  }
46
50
  export default BezierJSWrapper;
@@ -18,6 +18,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.BezierJSWrapper = void 0;
19
19
  const bezier_js_1 = require("bezier-js");
20
20
  const Vec2_1 = require("../Vec2");
21
+ const LineSegment2_1 = __importDefault(require("./LineSegment2"));
21
22
  const Rect2_1 = __importDefault(require("./Rect2"));
22
23
  const Parameterized2DShape_1 = __importDefault(require("./Parameterized2DShape"));
23
24
  /**
@@ -84,6 +85,17 @@ class BezierJSWrapper extends Parameterized2DShape_1.default {
84
85
  return new Rect2_1.default(bbox.x.min, bbox.y.min, width, height);
85
86
  }
86
87
  argIntersectsLineSegment(line) {
88
+ // Bezier-js has a bug when all control points of a Bezier curve lie on
89
+ // a line. Our solution involves converting the Bezier into a line, then
90
+ // finding the parameter value that produced the intersection.
91
+ //
92
+ // TODO: This is unnecessarily slow. A better solution would be to fix
93
+ // the bug upstream.
94
+ const asLine = LineSegment2_1.default.ofSmallestContainingPoints(this.getPoints());
95
+ if (asLine) {
96
+ const intersection = asLine.intersectsLineSegment(line);
97
+ return intersection.map(p => this.nearestPointTo(p).parameterValue);
98
+ }
87
99
  const bezier = this.getBezier();
88
100
  return bezier.intersects(line).map(t => {
89
101
  // We're using the .intersects(line) function, which is documented
@@ -166,6 +178,8 @@ class BezierJSWrapper extends Parameterized2DShape_1.default {
166
178
  };
167
179
  const iterate = () => {
168
180
  const slope = secondDerivativeAt(t);
181
+ if (slope === 0)
182
+ return;
169
183
  // We intersect a line through the point on f'(t) at t with the x-axis:
170
184
  // y = m(x - x₀) + y₀
171
185
  // ⇒ x - x₀ = (y - y₀) / m
@@ -189,6 +203,27 @@ class BezierJSWrapper extends Parameterized2DShape_1.default {
189
203
  }
190
204
  return { parameterValue: t, point: this.at(t) };
191
205
  }
206
+ intersectsBezier(other) {
207
+ const intersections = this.getBezier().intersects(other.getBezier());
208
+ if (!intersections || intersections.length === 0) {
209
+ return [];
210
+ }
211
+ const result = [];
212
+ for (const intersection of intersections) {
213
+ // From http://pomax.github.io/bezierjs/#intersect-curve,
214
+ // .intersects returns an array of 't1/t2' pairs, where curve1.at(t1) gives the point.
215
+ const match = /^([-0-9.eE]+)\/([-0-9.eE]+)$/.exec(intersection);
216
+ if (!match) {
217
+ throw new Error(`Incorrect format returned by .intersects: ${intersections} should be array of "number/number"!`);
218
+ }
219
+ const t = parseFloat(match[1]);
220
+ result.push({
221
+ parameterValue: t,
222
+ point: this.at(t),
223
+ });
224
+ }
225
+ return result;
226
+ }
192
227
  toString() {
193
228
  return `Bézier(${this.getPoints().map(point => point.toString()).join(', ')})`;
194
229
  }
@@ -25,6 +25,17 @@ export declare class LineSegment2 extends Parameterized2DShape {
25
25
  readonly bbox: Rect2;
26
26
  /** Creates a new `LineSegment2` from its endpoints. */
27
27
  constructor(point1: Point2, point2: Point2);
28
+ /**
29
+ * Returns the smallest line segment that contains all points in `points`, or `null`
30
+ * if no such line segment exists.
31
+ *
32
+ * @example
33
+ * ```ts,runnable
34
+ * import {LineSegment2, Vec2} from '@js-draw/math';
35
+ * console.log(LineSegment2.ofSmallestContainingPoints([Vec2.of(1, 0), Vec2.of(0, 1)]));
36
+ * ```
37
+ */
38
+ static ofSmallestContainingPoints(points: readonly Point2[]): LineSegment2 | null;
28
39
  /** Alias for `point1`. */
29
40
  get p1(): Point2;
30
41
  /** Alias for `point2`. */
@@ -22,6 +22,28 @@ class LineSegment2 extends Parameterized2DShape_1.default {
22
22
  this.direction = this.direction.times(1 / this.length);
23
23
  }
24
24
  }
25
+ /**
26
+ * Returns the smallest line segment that contains all points in `points`, or `null`
27
+ * if no such line segment exists.
28
+ *
29
+ * @example
30
+ * ```ts,runnable
31
+ * import {LineSegment2, Vec2} from '@js-draw/math';
32
+ * console.log(LineSegment2.ofSmallestContainingPoints([Vec2.of(1, 0), Vec2.of(0, 1)]));
33
+ * ```
34
+ */
35
+ static ofSmallestContainingPoints(points) {
36
+ if (points.length <= 1)
37
+ return null;
38
+ const sorted = [...points].sort((a, b) => a.x !== b.x ? a.x - b.x : a.y - b.y);
39
+ const line = new LineSegment2(sorted[0], sorted[sorted.length - 1]);
40
+ for (const point of sorted) {
41
+ if (!line.containsPoint(point)) {
42
+ return null;
43
+ }
44
+ }
45
+ return line;
46
+ }
25
47
  // Accessors to make LineSegment2 compatible with bezier-js's
26
48
  // interface
27
49
  /** Alias for `point1`. */
@@ -104,7 +126,10 @@ class LineSegment2 extends Parameterized2DShape_1.default {
104
126
  // = ((o₁ᵧ - o₂ᵧ)((d₁ₓd₂ₓ)) + (d₂ᵧd₁ₓ)(o₂ₓ) - (d₁ᵧd₂ₓ)(o₁ₓ))/(d₂ᵧd₁ₓ - d₁ᵧd₂ₓ)
105
127
  // ⇒ y = o₁ᵧ + d₁ᵧ · (x - o₁ₓ) / d₁ₓ = ...
106
128
  let resultPoint, resultT;
107
- if (this.direction.x === 0) {
129
+ // Consider very-near-vertical lines to be vertical --- not doing so can lead to
130
+ // precision error when dividing by this.direction.x.
131
+ const small = 4e-13;
132
+ if (Math.abs(this.direction.x) < small) {
108
133
  // Vertical line: Where does the other have x = this.point1.x?
109
134
  // x = o₁ₓ = o₂ₓ + d₂ₓ · (y - o₂ᵧ) / d₂ᵧ
110
135
  // ⇒ (o₁ₓ - o₂ₓ)(d₂ᵧ/d₂ₓ) + o₂ᵧ = y
@@ -1,7 +1,12 @@
1
1
  import { Point2, Vec2 } from '../Vec2';
2
2
  import Abstract2DShape from './Abstract2DShape';
3
3
  import LineSegment2 from './LineSegment2';
4
- /** A 2-dimensional path with parameter interval $t \in [0, 1]$. */
4
+ /**
5
+ * A 2-dimensional path with parameter interval $t \in [0, 1]$.
6
+ *
7
+ * **Note:** Avoid extending this class outside of `js-draw` --- new abstract methods
8
+ * may be added between minor versions.
9
+ */
5
10
  export declare abstract class Parameterized2DShape extends Abstract2DShape {
6
11
  /** Returns this at a given parameter. $t \in [0, 1]$ */
7
12
  abstract at(t: number): Point2;
@@ -5,7 +5,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Parameterized2DShape = void 0;
7
7
  const Abstract2DShape_1 = __importDefault(require("./Abstract2DShape"));
8
- /** A 2-dimensional path with parameter interval $t \in [0, 1]$. */
8
+ /**
9
+ * A 2-dimensional path with parameter interval $t \in [0, 1]$.
10
+ *
11
+ * **Note:** Avoid extending this class outside of `js-draw` --- new abstract methods
12
+ * may be added between minor versions.
13
+ */
9
14
  class Parameterized2DShape extends Abstract2DShape_1.default {
10
15
  intersectsLineSegment(line) {
11
16
  return this.argIntersectsLineSegment(line).map(t => this.at(t));
@@ -32,11 +32,19 @@ export type PathCommand = CubicBezierPathCommand | QuadraticBezierPathCommand |
32
32
  export interface IntersectionResult {
33
33
  curve: Parameterized2DShape;
34
34
  curveIndex: number;
35
- /** Parameter value for the closest point **on** the path to the intersection. @internal @deprecated */
36
- parameterValue?: number;
35
+ /** Parameter value for the closest point **on** the path to the intersection. @internal */
36
+ parameterValue: number;
37
37
  /** Point at which the intersection occured. */
38
38
  point: Point2;
39
39
  }
40
+ /** Options for {@link Path.splitNear} and {@link Path.splitAt} */
41
+ export interface PathSplitOptions {
42
+ /**
43
+ * Allows mapping points on newly added segments. This is useful, for example,
44
+ * to round points to prevent long decimals when later saving.
45
+ */
46
+ mapNewPoint?: (point: Point2) => Point2;
47
+ }
40
48
  /**
41
49
  * Allows indexing a particular part of a path.
42
50
  *
@@ -46,8 +54,43 @@ export interface CurveIndexRecord {
46
54
  curveIndex: number;
47
55
  parameterValue: number;
48
56
  }
57
+ /** Returns a positive number if `a` comes after `b`, 0 if equal, and negative otherwise. */
58
+ export declare const compareCurveIndices: (a: CurveIndexRecord, b: CurveIndexRecord) => number;
59
+ /**
60
+ * Returns a version of `index` with its parameter value incremented by `stepBy`
61
+ * (which can be either positive or negative).
62
+ */
63
+ export declare const stepCurveIndexBy: (index: CurveIndexRecord, stepBy: number) => CurveIndexRecord;
49
64
  /**
50
65
  * Represents a union of lines and curves.
66
+ *
67
+ * To create a path from a string, see {@link fromString}.
68
+ *
69
+ * @example
70
+ * ```ts,runnable,console
71
+ * import {Path, Mat33, Vec2, LineSegment2} from '@js-draw/math';
72
+ *
73
+ * // Creates a path from an SVG path string.
74
+ * // In this case,
75
+ * // 1. Move to (0,0)
76
+ * // 2. Line to (100,0)
77
+ * const path = Path.fromString('M0,0 L100,0');
78
+ *
79
+ * // Logs the distance from (10,0) to the curve 1 unit
80
+ * // away from path. This curve forms a stroke with the path at
81
+ * // its center.
82
+ * const strokeRadius = 1;
83
+ * console.log(path.signedDistance(Vec2.of(10,0), strokeRadius));
84
+ *
85
+ * // Log a version of the path that's scaled by a factor of 4.
86
+ * console.log(path.transformedBy(Mat33.scaling2D(4)).toString());
87
+ *
88
+ * // Log all intersections of a stroked version of the path with
89
+ * // a vertical line segment.
90
+ * // (Try removing the `strokeRadius` parameter).
91
+ * const segment = new LineSegment2(Vec2.of(5, -100), Vec2.of(5, 100));
92
+ * console.log(path.intersection(segment, strokeRadius).map(i => i.point));
93
+ * ```
51
94
  */
52
95
  export declare class Path {
53
96
  readonly startPoint: Point2;
@@ -66,6 +109,12 @@ export declare class Path {
66
109
  * See also {@link fromString}
67
110
  */
68
111
  constructor(startPoint: Point2, parts: Readonly<PathCommand>[]);
112
+ /**
113
+ * Computes and returns the full bounding box for this path.
114
+ *
115
+ * If a slight over-estimate of a path's bounding box is sufficient, use
116
+ * {@link bbox} instead.
117
+ */
69
118
  getExactBBox(): Rect2;
70
119
  private cachedGeometry;
71
120
  get geometry(): Parameterized2DShape[];
@@ -79,7 +128,20 @@ export declare class Path {
79
128
  private cachedPolylineApproximation;
80
129
  polylineApproximation(): LineSegment2[];
81
130
  static computeBBoxForSegment(startPoint: Point2, part: PathCommand): Rect2;
82
- /** **Note**: `strokeRadius = strokeWidth / 2` */
131
+ /**
132
+ * Returns the signed distance between `point` and a curve `strokeRadius` units
133
+ * away from this path.
134
+ *
135
+ * This returns the **signed distance**, which means that points inside this shape
136
+ * have their distance negated. For example,
137
+ * ```ts,runnable,console
138
+ * import {Path, Vec2} from '@js-draw/math';
139
+ * console.log(Path.fromString('m0,0 L100,0').signedDistance(Vec2.zero, 1));
140
+ * ```
141
+ * would print `-1` because (0,0) is on `m0,0 L100,0` and thus one unit away from its boundary.
142
+ *
143
+ * **Note**: `strokeRadius = strokeWidth / 2`
144
+ */
83
145
  signedDistance(point: Point2, strokeRadius: number): number;
84
146
  /**
85
147
  * Let `S` be a closed path a distance `strokeRadius` from this path.
@@ -99,17 +161,33 @@ export declare class Path {
99
161
  intersection(line: LineSegment2, strokeRadius?: number): IntersectionResult[];
100
162
  /**
101
163
  * @returns the nearest point on this path to the given `point`.
102
- *
103
- * @internal
104
- * @beta
105
164
  */
106
165
  nearestPointTo(point: Point2): IntersectionResult;
107
166
  at(index: CurveIndexRecord): import("../Vec3").Vec3;
108
167
  tangentAt(index: CurveIndexRecord): import("../Vec3").Vec3;
168
+ /** Splits this path in two near the given `point`. */
169
+ splitNear(point: Point2, options?: PathSplitOptions): [Path] | [Path, Path];
170
+ /**
171
+ * Returns a copy of this path with `deleteFrom` until `deleteUntil` replaced with `insert`.
172
+ *
173
+ * This method is analogous to {@link Array.toSpliced}.
174
+ */
175
+ spliced(deleteFrom: CurveIndexRecord, deleteTo: CurveIndexRecord, insert: Path | undefined, options?: PathSplitOptions): Path;
176
+ splitAt(at: CurveIndexRecord, options?: PathSplitOptions): [Path] | [Path, Path];
177
+ splitAt(at: CurveIndexRecord[], options?: PathSplitOptions): Path[];
178
+ /**
179
+ * Replaces all `MoveTo` commands with `LineTo` commands and connects the end point of this
180
+ * path to the start point.
181
+ */
182
+ asClosed(): Path;
109
183
  private static mapPathCommand;
110
184
  mapPoints(mapping: (point: Point2) => Point2): Path;
111
185
  transformedBy(affineTransfm: Mat33): Path;
112
- union(other: Path | null, options?: {
186
+ /**
187
+ * @internal
188
+ */
189
+ closedContainsPoint(point: Point2): boolean;
190
+ union(other: Path | PathCommand[] | null, options?: {
113
191
  allowReverse?: boolean;
114
192
  }): Path;
115
193
  /**
@@ -122,7 +200,8 @@ export declare class Path {
122
200
  * ```
123
201
  */
124
202
  reversed(): Path;
125
- private getEndPoint;
203
+ /** Computes and returns the end point of this path */
204
+ getEndPoint(): import("../Vec3").Vec3;
126
205
  /**
127
206
  * Like {@link closedRoughlyIntersects} except takes stroke width into account.
128
207
  *
@@ -134,6 +213,12 @@ export declare class Path {
134
213
  * `strokeRadius` is half of `strokeWidth`.
135
214
  */
136
215
  roughlyIntersects(rect: Rect2, strokeWidth?: number): boolean;
216
+ /**
217
+ * Treats this as a closed path and returns true if part of `rect` is *roughly* within
218
+ * this path's interior.
219
+ *
220
+ * **Note**: Assumes that this is a closed, non-self-intersecting path.
221
+ */
137
222
  closedRoughlyIntersects(rect: Rect2): boolean;
138
223
  /** @returns true if all points on this are equivalent to the points on `other` */
139
224
  eq(other: Path, tolerance?: number): boolean;
@@ -160,10 +245,8 @@ export declare class Path {
160
245
  /**
161
246
  * Create a `Path` from a subset of the SVG path specification.
162
247
  *
163
- * ## To-do
164
- * - TODO: Support a larger subset of SVG paths
165
- * - Elliptical arcs are currently unsupported.
166
- * - TODO: Support `s`,`t` commands shorthands.
248
+ * Currently, this does not support elliptical arcs or `s` and `t` command
249
+ * shorthands. See https://github.com/personalizedrefrigerator/js-draw/pull/19.
167
250
  *
168
251
  * @example
169
252
  * ```ts,runnable,console
@@ -174,6 +257,7 @@ export declare class Path {
174
257
  * ```
175
258
  */
176
259
  static fromString(pathString: string): Path;
260
+ static fromConvexHullOf(points: Point2[]): Path;
177
261
  static empty: Path;
178
262
  }
179
263
  export default Path;