@js-draw/math 1.17.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/cjs/Mat33.js
CHANGED
@@ -340,7 +340,11 @@ class Mat33 {
|
|
340
340
|
return Mat33.identity;
|
341
341
|
}
|
342
342
|
const parseArguments = (argumentString) => {
|
343
|
-
|
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) => {
|
package/dist/cjs/Vec3.d.ts
CHANGED
@@ -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
|
-
|
234
|
-
|
235
|
-
|
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
|
-
|
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
|
-
/**
|
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
|
-
/**
|
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
|
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;
|