@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.
- package/dist/cjs/Mat33.js +6 -1
- package/dist/cjs/Vec3.d.ts +2 -1
- package/dist/cjs/Vec3.js +5 -7
- package/dist/cjs/lib.d.ts +2 -1
- package/dist/cjs/lib.js +5 -1
- package/dist/cjs/shapes/BezierJSWrapper.d.ts +4 -0
- package/dist/cjs/shapes/BezierJSWrapper.js +35 -0
- package/dist/cjs/shapes/LineSegment2.d.ts +11 -0
- package/dist/cjs/shapes/LineSegment2.js +26 -1
- package/dist/cjs/shapes/Parameterized2DShape.d.ts +6 -1
- package/dist/cjs/shapes/Parameterized2DShape.js +6 -1
- package/dist/cjs/shapes/Path.d.ts +96 -12
- package/dist/cjs/shapes/Path.js +338 -15
- package/dist/cjs/shapes/QuadraticBezier.d.ts +2 -3
- package/dist/cjs/shapes/QuadraticBezier.js +2 -3
- package/dist/cjs/shapes/Rect2.d.ts +6 -1
- package/dist/cjs/shapes/Rect2.js +5 -1
- package/dist/cjs/utils/convexHull2Of.d.ts +9 -0
- package/dist/cjs/utils/convexHull2Of.js +61 -0
- package/dist/cjs/utils/convexHull2Of.test.d.ts +1 -0
- package/dist/mjs/Mat33.mjs +6 -1
- package/dist/mjs/Vec3.d.ts +2 -1
- package/dist/mjs/Vec3.mjs +5 -7
- package/dist/mjs/lib.d.ts +2 -1
- package/dist/mjs/lib.mjs +2 -1
- package/dist/mjs/shapes/BezierJSWrapper.d.ts +4 -0
- package/dist/mjs/shapes/BezierJSWrapper.mjs +35 -0
- package/dist/mjs/shapes/LineSegment2.d.ts +11 -0
- package/dist/mjs/shapes/LineSegment2.mjs +26 -1
- package/dist/mjs/shapes/Parameterized2DShape.d.ts +6 -1
- package/dist/mjs/shapes/Parameterized2DShape.mjs +6 -1
- package/dist/mjs/shapes/Path.d.ts +96 -12
- package/dist/mjs/shapes/Path.mjs +335 -14
- package/dist/mjs/shapes/QuadraticBezier.d.ts +2 -3
- package/dist/mjs/shapes/QuadraticBezier.mjs +2 -3
- package/dist/mjs/shapes/Rect2.d.ts +6 -1
- package/dist/mjs/shapes/Rect2.mjs +5 -1
- package/dist/mjs/utils/convexHull2Of.d.ts +9 -0
- package/dist/mjs/utils/convexHull2Of.mjs +59 -0
- package/dist/mjs/utils/convexHull2Of.test.d.ts +1 -0
- package/package.json +2 -2
- package/src/Mat33.ts +8 -2
- package/src/Vec3.test.ts +16 -0
- package/src/Vec3.ts +7 -8
- package/src/lib.ts +3 -0
- package/src/shapes/BezierJSWrapper.ts +41 -0
- package/src/shapes/LineSegment2.test.ts +26 -0
- package/src/shapes/LineSegment2.ts +31 -1
- package/src/shapes/Parameterized2DShape.ts +6 -1
- package/src/shapes/Path.test.ts +173 -5
- package/src/shapes/Path.ts +390 -18
- package/src/shapes/QuadraticBezier.test.ts +21 -0
- package/src/shapes/QuadraticBezier.ts +2 -3
- package/src/shapes/Rect2.ts +6 -2
- package/src/utils/convexHull2Of.test.ts +43 -0
- package/src/utils/convexHull2Of.ts +71 -0
package/dist/mjs/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/mjs/lib.mjs
CHANGED
@@ -17,8 +17,9 @@
|
|
17
17
|
* @packageDocumentation
|
18
18
|
*/
|
19
19
|
export { LineSegment2 } from './shapes/LineSegment2.mjs';
|
20
|
-
export { Path, PathCommandType, } from './shapes/Path.mjs';
|
20
|
+
export { Path, stepCurveIndexBy as stepPathIndexBy, compareCurveIndices as comparePathIndices, PathCommandType, } from './shapes/Path.mjs';
|
21
21
|
export { Rect2 } from './shapes/Rect2.mjs';
|
22
|
+
export { Parameterized2DShape } from './shapes/Parameterized2DShape.mjs';
|
22
23
|
export { QuadraticBezier } from './shapes/QuadraticBezier.mjs';
|
23
24
|
export { Abstract2DShape } from './shapes/Abstract2DShape.mjs';
|
24
25
|
export { Mat33 } from './Mat33.mjs';
|
@@ -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;
|
@@ -12,6 +12,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
12
12
|
var _BezierJSWrapper_bezierJs;
|
13
13
|
import { Bezier } from 'bezier-js';
|
14
14
|
import { Vec2 } from '../Vec2.mjs';
|
15
|
+
import LineSegment2 from './LineSegment2.mjs';
|
15
16
|
import Rect2 from './Rect2.mjs';
|
16
17
|
import Parameterized2DShape from './Parameterized2DShape.mjs';
|
17
18
|
/**
|
@@ -78,6 +79,17 @@ export class BezierJSWrapper extends Parameterized2DShape {
|
|
78
79
|
return new Rect2(bbox.x.min, bbox.y.min, width, height);
|
79
80
|
}
|
80
81
|
argIntersectsLineSegment(line) {
|
82
|
+
// Bezier-js has a bug when all control points of a Bezier curve lie on
|
83
|
+
// a line. Our solution involves converting the Bezier into a line, then
|
84
|
+
// finding the parameter value that produced the intersection.
|
85
|
+
//
|
86
|
+
// TODO: This is unnecessarily slow. A better solution would be to fix
|
87
|
+
// the bug upstream.
|
88
|
+
const asLine = LineSegment2.ofSmallestContainingPoints(this.getPoints());
|
89
|
+
if (asLine) {
|
90
|
+
const intersection = asLine.intersectsLineSegment(line);
|
91
|
+
return intersection.map(p => this.nearestPointTo(p).parameterValue);
|
92
|
+
}
|
81
93
|
const bezier = this.getBezier();
|
82
94
|
return bezier.intersects(line).map(t => {
|
83
95
|
// We're using the .intersects(line) function, which is documented
|
@@ -160,6 +172,8 @@ export class BezierJSWrapper extends Parameterized2DShape {
|
|
160
172
|
};
|
161
173
|
const iterate = () => {
|
162
174
|
const slope = secondDerivativeAt(t);
|
175
|
+
if (slope === 0)
|
176
|
+
return;
|
163
177
|
// We intersect a line through the point on f'(t) at t with the x-axis:
|
164
178
|
// y = m(x - x₀) + y₀
|
165
179
|
// ⇒ x - x₀ = (y - y₀) / m
|
@@ -183,6 +197,27 @@ export class BezierJSWrapper extends Parameterized2DShape {
|
|
183
197
|
}
|
184
198
|
return { parameterValue: t, point: this.at(t) };
|
185
199
|
}
|
200
|
+
intersectsBezier(other) {
|
201
|
+
const intersections = this.getBezier().intersects(other.getBezier());
|
202
|
+
if (!intersections || intersections.length === 0) {
|
203
|
+
return [];
|
204
|
+
}
|
205
|
+
const result = [];
|
206
|
+
for (const intersection of intersections) {
|
207
|
+
// From http://pomax.github.io/bezierjs/#intersect-curve,
|
208
|
+
// .intersects returns an array of 't1/t2' pairs, where curve1.at(t1) gives the point.
|
209
|
+
const match = /^([-0-9.eE]+)\/([-0-9.eE]+)$/.exec(intersection);
|
210
|
+
if (!match) {
|
211
|
+
throw new Error(`Incorrect format returned by .intersects: ${intersections} should be array of "number/number"!`);
|
212
|
+
}
|
213
|
+
const t = parseFloat(match[1]);
|
214
|
+
result.push({
|
215
|
+
parameterValue: t,
|
216
|
+
point: this.at(t),
|
217
|
+
});
|
218
|
+
}
|
219
|
+
return result;
|
220
|
+
}
|
186
221
|
toString() {
|
187
222
|
return `Bézier(${this.getPoints().map(point => point.toString()).join(', ')})`;
|
188
223
|
}
|
@@ -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`. */
|
@@ -16,6 +16,28 @@ export class LineSegment2 extends Parameterized2DShape {
|
|
16
16
|
this.direction = this.direction.times(1 / this.length);
|
17
17
|
}
|
18
18
|
}
|
19
|
+
/**
|
20
|
+
* Returns the smallest line segment that contains all points in `points`, or `null`
|
21
|
+
* if no such line segment exists.
|
22
|
+
*
|
23
|
+
* @example
|
24
|
+
* ```ts,runnable
|
25
|
+
* import {LineSegment2, Vec2} from '@js-draw/math';
|
26
|
+
* console.log(LineSegment2.ofSmallestContainingPoints([Vec2.of(1, 0), Vec2.of(0, 1)]));
|
27
|
+
* ```
|
28
|
+
*/
|
29
|
+
static ofSmallestContainingPoints(points) {
|
30
|
+
if (points.length <= 1)
|
31
|
+
return null;
|
32
|
+
const sorted = [...points].sort((a, b) => a.x !== b.x ? a.x - b.x : a.y - b.y);
|
33
|
+
const line = new LineSegment2(sorted[0], sorted[sorted.length - 1]);
|
34
|
+
for (const point of sorted) {
|
35
|
+
if (!line.containsPoint(point)) {
|
36
|
+
return null;
|
37
|
+
}
|
38
|
+
}
|
39
|
+
return line;
|
40
|
+
}
|
19
41
|
// Accessors to make LineSegment2 compatible with bezier-js's
|
20
42
|
// interface
|
21
43
|
/** Alias for `point1`. */
|
@@ -98,7 +120,10 @@ export class LineSegment2 extends Parameterized2DShape {
|
|
98
120
|
// = ((o₁ᵧ - o₂ᵧ)((d₁ₓd₂ₓ)) + (d₂ᵧd₁ₓ)(o₂ₓ) - (d₁ᵧd₂ₓ)(o₁ₓ))/(d₂ᵧd₁ₓ - d₁ᵧd₂ₓ)
|
99
121
|
// ⇒ y = o₁ᵧ + d₁ᵧ · (x - o₁ₓ) / d₁ₓ = ...
|
100
122
|
let resultPoint, resultT;
|
101
|
-
|
123
|
+
// Consider very-near-vertical lines to be vertical --- not doing so can lead to
|
124
|
+
// precision error when dividing by this.direction.x.
|
125
|
+
const small = 4e-13;
|
126
|
+
if (Math.abs(this.direction.x) < small) {
|
102
127
|
// Vertical line: Where does the other have x = this.point1.x?
|
103
128
|
// x = o₁ₓ = o₂ₓ + d₂ₓ · (y - o₂ᵧ) / d₂ᵧ
|
104
129
|
// ⇒ (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
|
-
/**
|
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;
|
@@ -1,5 +1,10 @@
|
|
1
1
|
import Abstract2DShape from './Abstract2DShape.mjs';
|
2
|
-
/**
|
2
|
+
/**
|
3
|
+
* A 2-dimensional path with parameter interval $t \in [0, 1]$.
|
4
|
+
*
|
5
|
+
* **Note:** Avoid extending this class outside of `js-draw` --- new abstract methods
|
6
|
+
* may be added between minor versions.
|
7
|
+
*/
|
3
8
|
export class Parameterized2DShape extends Abstract2DShape {
|
4
9
|
intersectsLineSegment(line) {
|
5
10
|
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
|
36
|
-
parameterValue
|
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
|
-
/**
|
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
|
-
|
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
|
-
|
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
|
-
*
|
164
|
-
*
|
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;
|