@js-draw/math 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. package/README.md +3 -0
  2. package/build-config.json +4 -0
  3. package/dist/cjs/Color4.d.ts +83 -0
  4. package/dist/cjs/Color4.js +277 -0
  5. package/dist/cjs/Mat33.d.ts +131 -0
  6. package/dist/cjs/Mat33.js +345 -0
  7. package/dist/cjs/Vec2.d.ts +42 -0
  8. package/dist/cjs/Vec2.js +48 -0
  9. package/dist/cjs/Vec3.d.ts +126 -0
  10. package/dist/cjs/Vec3.js +203 -0
  11. package/dist/cjs/lib.d.ts +27 -0
  12. package/dist/cjs/lib.js +42 -0
  13. package/dist/cjs/polynomial/solveQuadratic.d.ts +9 -0
  14. package/dist/cjs/polynomial/solveQuadratic.js +39 -0
  15. package/dist/cjs/rounding.d.ts +15 -0
  16. package/dist/cjs/rounding.js +146 -0
  17. package/dist/cjs/shapes/Abstract2DShape.d.ts +49 -0
  18. package/dist/cjs/shapes/Abstract2DShape.js +38 -0
  19. package/dist/cjs/shapes/BezierJSWrapper.d.ts +36 -0
  20. package/dist/cjs/shapes/BezierJSWrapper.js +94 -0
  21. package/dist/cjs/shapes/CubicBezier.d.ts +17 -0
  22. package/dist/cjs/shapes/CubicBezier.js +35 -0
  23. package/dist/cjs/shapes/LineSegment2.d.ts +70 -0
  24. package/dist/cjs/shapes/LineSegment2.js +183 -0
  25. package/dist/cjs/shapes/Path.d.ts +96 -0
  26. package/dist/cjs/shapes/Path.js +766 -0
  27. package/dist/cjs/shapes/PointShape2D.d.ts +18 -0
  28. package/dist/cjs/shapes/PointShape2D.js +31 -0
  29. package/dist/cjs/shapes/QuadraticBezier.d.ts +35 -0
  30. package/dist/cjs/shapes/QuadraticBezier.js +120 -0
  31. package/dist/cjs/shapes/Rect2.d.ts +58 -0
  32. package/dist/cjs/shapes/Rect2.js +259 -0
  33. package/dist/cjs/shapes/Triangle.d.ts +46 -0
  34. package/dist/cjs/shapes/Triangle.js +126 -0
  35. package/dist/mjs/Color4.d.ts +83 -0
  36. package/dist/mjs/Color4.mjs +271 -0
  37. package/dist/mjs/Mat33.d.ts +131 -0
  38. package/dist/mjs/Mat33.mjs +338 -0
  39. package/dist/mjs/Vec2.d.ts +42 -0
  40. package/dist/mjs/Vec2.mjs +42 -0
  41. package/dist/mjs/Vec3.d.ts +126 -0
  42. package/dist/mjs/Vec3.mjs +199 -0
  43. package/dist/mjs/lib.d.ts +27 -0
  44. package/dist/mjs/lib.mjs +29 -0
  45. package/dist/mjs/polynomial/solveQuadratic.d.ts +9 -0
  46. package/dist/mjs/polynomial/solveQuadratic.mjs +37 -0
  47. package/dist/mjs/rounding.d.ts +15 -0
  48. package/dist/mjs/rounding.mjs +139 -0
  49. package/dist/mjs/shapes/Abstract2DShape.d.ts +49 -0
  50. package/dist/mjs/shapes/Abstract2DShape.mjs +36 -0
  51. package/dist/mjs/shapes/BezierJSWrapper.d.ts +36 -0
  52. package/dist/mjs/shapes/BezierJSWrapper.mjs +89 -0
  53. package/dist/mjs/shapes/CubicBezier.d.ts +17 -0
  54. package/dist/mjs/shapes/CubicBezier.mjs +30 -0
  55. package/dist/mjs/shapes/LineSegment2.d.ts +70 -0
  56. package/dist/mjs/shapes/LineSegment2.mjs +176 -0
  57. package/dist/mjs/shapes/Path.d.ts +96 -0
  58. package/dist/mjs/shapes/Path.mjs +759 -0
  59. package/dist/mjs/shapes/PointShape2D.d.ts +18 -0
  60. package/dist/mjs/shapes/PointShape2D.mjs +26 -0
  61. package/dist/mjs/shapes/QuadraticBezier.d.ts +35 -0
  62. package/dist/mjs/shapes/QuadraticBezier.mjs +113 -0
  63. package/dist/mjs/shapes/Rect2.d.ts +58 -0
  64. package/dist/mjs/shapes/Rect2.mjs +252 -0
  65. package/dist/mjs/shapes/Triangle.d.ts +46 -0
  66. package/dist/mjs/shapes/Triangle.mjs +121 -0
  67. package/package.json +48 -0
  68. package/tsconfig.json +7 -0
  69. package/typedoc.json +5 -0
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
7
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
8
+ if (kind === "m") throw new TypeError("Private method is not writable");
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
11
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ var _BezierJSWrapper_bezierJs;
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ const bezier_js_1 = require("bezier-js");
19
+ const Vec2_1 = require("../Vec2");
20
+ const Abstract2DShape_1 = __importDefault(require("./Abstract2DShape"));
21
+ const Rect2_1 = __importDefault(require("./Rect2"));
22
+ /**
23
+ * A lazy-initializing wrapper around Bezier-js.
24
+ *
25
+ * Subclasses may override `at`, `derivativeAt`, and `normal` with functions
26
+ * that do not initialize a `bezier-js` `Bezier`.
27
+ *
28
+ * Do not use this class directly. It may be removed/replaced in a future release.
29
+ * @internal
30
+ */
31
+ class BezierJSWrapper extends Abstract2DShape_1.default {
32
+ constructor() {
33
+ super(...arguments);
34
+ _BezierJSWrapper_bezierJs.set(this, null);
35
+ }
36
+ getBezier() {
37
+ if (!__classPrivateFieldGet(this, _BezierJSWrapper_bezierJs, "f")) {
38
+ __classPrivateFieldSet(this, _BezierJSWrapper_bezierJs, new bezier_js_1.Bezier(this.getPoints().map(p => p.xy)), "f");
39
+ }
40
+ return __classPrivateFieldGet(this, _BezierJSWrapper_bezierJs, "f");
41
+ }
42
+ signedDistance(point) {
43
+ // .d: Distance
44
+ return this.getBezier().project(point.xy).d;
45
+ }
46
+ /**
47
+ * @returns the (more) exact distance from `point` to this.
48
+ *
49
+ * @see {@link approximateDistance}
50
+ */
51
+ distance(point) {
52
+ // A Bézier curve has no interior, thus, signed distance is the same as distance.
53
+ return this.signedDistance(point);
54
+ }
55
+ /**
56
+ * @returns the curve evaluated at `t`.
57
+ */
58
+ at(t) {
59
+ return Vec2_1.Vec2.ofXY(this.getBezier().get(t));
60
+ }
61
+ derivativeAt(t) {
62
+ return Vec2_1.Vec2.ofXY(this.getBezier().derivative(t));
63
+ }
64
+ normal(t) {
65
+ return Vec2_1.Vec2.ofXY(this.getBezier().normal(t));
66
+ }
67
+ getTightBoundingBox() {
68
+ const bbox = this.getBezier().bbox();
69
+ const width = bbox.x.max - bbox.x.min;
70
+ const height = bbox.y.max - bbox.y.min;
71
+ return new Rect2_1.default(bbox.x.min, bbox.y.min, width, height);
72
+ }
73
+ intersectsLineSegment(line) {
74
+ const bezier = this.getBezier();
75
+ const intersectionPoints = bezier.intersects(line).map(t => {
76
+ // We're using the .intersects(line) function, which is documented
77
+ // to always return numbers. However, to satisfy the type checker (and
78
+ // possibly improperly-defined types),
79
+ if (typeof t === 'string') {
80
+ t = parseFloat(t);
81
+ }
82
+ const point = Vec2_1.Vec2.ofXY(bezier.get(t));
83
+ // Ensure that the intersection is on the line segment
84
+ if (point.minus(line.p1).magnitude() > line.length
85
+ || point.minus(line.p2).magnitude() > line.length) {
86
+ return null;
87
+ }
88
+ return point;
89
+ }).filter(entry => entry !== null);
90
+ return intersectionPoints;
91
+ }
92
+ }
93
+ _BezierJSWrapper_bezierJs = new WeakMap();
94
+ exports.default = BezierJSWrapper;
@@ -0,0 +1,17 @@
1
+ import { Point2 } from '../Vec2';
2
+ import BezierJSWrapper from './BezierJSWrapper';
3
+ import Rect2 from './Rect2';
4
+ /**
5
+ * A wrapper around [`bezier-js`](https://github.com/Pomax/bezierjs)'s cubic Bezier.
6
+ */
7
+ declare class CubicBezier extends BezierJSWrapper {
8
+ readonly p0: Point2;
9
+ readonly p1: Point2;
10
+ readonly p2: Point2;
11
+ readonly p3: Point2;
12
+ constructor(p0: Point2, p1: Point2, p2: Point2, p3: Point2);
13
+ getPoints(): import("../Vec3").Vec3[];
14
+ /** Returns an overestimate of this shape's bounding box. */
15
+ getLooseBoundingBox(): Rect2;
16
+ }
17
+ export default CubicBezier;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const BezierJSWrapper_1 = __importDefault(require("./BezierJSWrapper"));
7
+ const Rect2_1 = __importDefault(require("./Rect2"));
8
+ /**
9
+ * A wrapper around [`bezier-js`](https://github.com/Pomax/bezierjs)'s cubic Bezier.
10
+ */
11
+ class CubicBezier extends BezierJSWrapper_1.default {
12
+ constructor(
13
+ // Start point
14
+ p0,
15
+ // Control point 1
16
+ p1,
17
+ // Control point 2
18
+ p2,
19
+ // End point
20
+ p3) {
21
+ super();
22
+ this.p0 = p0;
23
+ this.p1 = p1;
24
+ this.p2 = p2;
25
+ this.p3 = p3;
26
+ }
27
+ getPoints() {
28
+ return [this.p0, this.p1, this.p2, this.p3];
29
+ }
30
+ /** Returns an overestimate of this shape's bounding box. */
31
+ getLooseBoundingBox() {
32
+ return Rect2_1.default.bboxOf([this.p0, this.p1, this.p2, this.p3]);
33
+ }
34
+ }
35
+ exports.default = CubicBezier;
@@ -0,0 +1,70 @@
1
+ import Mat33 from '../Mat33';
2
+ import Rect2 from './Rect2';
3
+ import { Vec2, Point2 } from '../Vec2';
4
+ import Abstract2DShape from './Abstract2DShape';
5
+ interface IntersectionResult {
6
+ point: Point2;
7
+ t: number;
8
+ }
9
+ /** Represents a line segment. A `LineSegment2` is immutable. */
10
+ export declare class LineSegment2 extends Abstract2DShape {
11
+ private readonly point1;
12
+ private readonly point2;
13
+ /**
14
+ * The **unit** direction vector of this line segment, from
15
+ * `point1` to `point2`.
16
+ *
17
+ * In other words, `direction` is `point2.minus(point1).normalized()`
18
+ * (perhaps except when `point1` is equal to `point2`).
19
+ */
20
+ readonly direction: Vec2;
21
+ /** The distance between `point1` and `point2`. */
22
+ readonly length: number;
23
+ /** The bounding box of this line segment. */
24
+ readonly bbox: Rect2;
25
+ /** Creates a new `LineSegment2` from its endpoints. */
26
+ constructor(point1: Point2, point2: Point2);
27
+ /** Alias for `point1`. */
28
+ get p1(): Point2;
29
+ /** Alias for `point2`. */
30
+ get p2(): Point2;
31
+ /**
32
+ * Gets a point a distance `t` along this line.
33
+ *
34
+ * @deprecated
35
+ */
36
+ get(t: number): Point2;
37
+ /**
38
+ * Returns a point a fraction, `t`, along this line segment.
39
+ * Thus, `segment.at(0)` returns `segment.p1` and `segment.at(1)` returns
40
+ * `segment.p2`.
41
+ *
42
+ * `t` should be in `[0, 1]`.
43
+ */
44
+ at(t: number): Point2;
45
+ intersection(other: LineSegment2): IntersectionResult | null;
46
+ intersects(other: LineSegment2): boolean;
47
+ /**
48
+ * Returns the points at which this line segment intersects the
49
+ * given line segment.
50
+ *
51
+ * Note that {@link intersects} returns *whether* this line segment intersects another
52
+ * line segment. This method, by contrast, returns **the point** at which the intersection
53
+ * occurs, if such a point exists.
54
+ */
55
+ intersectsLineSegment(lineSegment: LineSegment2): import("../Vec3").Vec3[];
56
+ closestPointTo(target: Point2): import("../Vec3").Vec3;
57
+ /**
58
+ * Returns the distance from this line segment to `target`.
59
+ *
60
+ * Because a line segment has no interior, this signed distance is equivalent to
61
+ * the full distance between `target` and this line segment.
62
+ */
63
+ signedDistance(target: Point2): number;
64
+ /** Returns a copy of this line segment transformed by the given `affineTransfm`. */
65
+ transformedBy(affineTransfm: Mat33): LineSegment2;
66
+ /** @inheritdoc */
67
+ getTightBoundingBox(): Rect2;
68
+ toString(): string;
69
+ }
70
+ export default LineSegment2;
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.LineSegment2 = void 0;
7
+ const Rect2_1 = __importDefault(require("./Rect2"));
8
+ const Vec2_1 = require("../Vec2");
9
+ const Abstract2DShape_1 = __importDefault(require("./Abstract2DShape"));
10
+ /** Represents a line segment. A `LineSegment2` is immutable. */
11
+ class LineSegment2 extends Abstract2DShape_1.default {
12
+ /** Creates a new `LineSegment2` from its endpoints. */
13
+ constructor(point1, point2) {
14
+ super();
15
+ this.point1 = point1;
16
+ this.point2 = point2;
17
+ this.bbox = Rect2_1.default.bboxOf([point1, point2]);
18
+ this.direction = point2.minus(point1);
19
+ this.length = this.direction.magnitude();
20
+ // Normalize
21
+ if (this.length > 0) {
22
+ this.direction = this.direction.times(1 / this.length);
23
+ }
24
+ }
25
+ // Accessors to make LineSegment2 compatible with bezier-js's
26
+ // interface
27
+ /** Alias for `point1`. */
28
+ get p1() {
29
+ return this.point1;
30
+ }
31
+ /** Alias for `point2`. */
32
+ get p2() {
33
+ return this.point2;
34
+ }
35
+ /**
36
+ * Gets a point a distance `t` along this line.
37
+ *
38
+ * @deprecated
39
+ */
40
+ get(t) {
41
+ return this.point1.plus(this.direction.times(t));
42
+ }
43
+ /**
44
+ * Returns a point a fraction, `t`, along this line segment.
45
+ * Thus, `segment.at(0)` returns `segment.p1` and `segment.at(1)` returns
46
+ * `segment.p2`.
47
+ *
48
+ * `t` should be in `[0, 1]`.
49
+ */
50
+ at(t) {
51
+ return this.get(t * this.length);
52
+ }
53
+ intersection(other) {
54
+ // We want x₁(t) = x₂(t) and y₁(t) = y₂(t)
55
+ // Observe that
56
+ // x = this.point1.x + this.direction.x · t₁
57
+ // = other.point1.x + other.direction.x · t₂
58
+ // Thus,
59
+ // t₁ = (x - this.point1.x) / this.direction.x
60
+ // = (y - this.point1.y) / this.direction.y
61
+ // and
62
+ // t₂ = (x - other.point1.x) / other.direction.x
63
+ // (and similarly for y)
64
+ //
65
+ // Letting o₁ₓ = this.point1.x, o₂ₓ = other.point1.x,
66
+ // d₁ᵧ = this.direction.y, ...
67
+ //
68
+ // We can substitute these into the equations for y:
69
+ // y = o₁ᵧ + d₁ᵧ · (x - o₁ₓ) / d₁ₓ
70
+ // = o₂ᵧ + d₂ᵧ · (x - o₂ₓ) / d₂ₓ
71
+ // ⇒ o₁ᵧ - o₂ᵧ = d₂ᵧ · (x - o₂ₓ) / d₂ₓ - d₁ᵧ · (x - o₁ₓ) / d₁ₓ
72
+ // = (d₂ᵧ/d₂ₓ)(x) - (d₂ᵧ/d₂ₓ)(o₂ₓ) - (d₁ᵧ/d₁ₓ)(x) + (d₁ᵧ/d₁ₓ)(o₁ₓ)
73
+ // = (x)(d₂ᵧ/d₂ₓ - d₁ᵧ/d₁ₓ) - (d₂ᵧ/d₂ₓ)(o₂ₓ) + (d₁ᵧ/d₁ₓ)(o₁ₓ)
74
+ // ⇒ (x)(d₂ᵧ/d₂ₓ - d₁ᵧ/d₁ₓ) = o₁ᵧ - o₂ᵧ + (d₂ᵧ/d₂ₓ)(o₂ₓ) - (d₁ᵧ/d₁ₓ)(o₁ₓ)
75
+ // ⇒ x = (o₁ᵧ - o₂ᵧ + (d₂ᵧ/d₂ₓ)(o₂ₓ) - (d₁ᵧ/d₁ₓ)(o₁ₓ))/(d₂ᵧ/d₂ₓ - d₁ᵧ/d₁ₓ)
76
+ // = (d₁ₓd₂ₓ)(o₁ᵧ - o₂ᵧ + (d₂ᵧ/d₂ₓ)(o₂ₓ) - (d₁ᵧ/d₁ₓ)(o₁ₓ))/(d₂ᵧd₁ₓ - d₁ᵧd₂ₓ)
77
+ // = ((o₁ᵧ - o₂ᵧ)((d₁ₓd₂ₓ)) + (d₂ᵧd₁ₓ)(o₂ₓ) - (d₁ᵧd₂ₓ)(o₁ₓ))/(d₂ᵧd₁ₓ - d₁ᵧd₂ₓ)
78
+ // ⇒ y = o₁ᵧ + d₁ᵧ · (x - o₁ₓ) / d₁ₓ = ...
79
+ let resultPoint, resultT;
80
+ if (this.direction.x === 0) {
81
+ // Vertical line: Where does the other have x = this.point1.x?
82
+ // x = o₁ₓ = o₂ₓ + d₂ₓ · (y - o₂ᵧ) / d₂ᵧ
83
+ // ⇒ (o₁ₓ - o₂ₓ)(d₂ᵧ/d₂ₓ) + o₂ᵧ = y
84
+ // Avoid division by zero
85
+ if (other.direction.x === 0 || this.direction.y === 0) {
86
+ return null;
87
+ }
88
+ const xIntersect = this.point1.x;
89
+ const yIntersect = (this.point1.x - other.point1.x) * other.direction.y / other.direction.x + other.point1.y;
90
+ resultPoint = Vec2_1.Vec2.of(xIntersect, yIntersect);
91
+ resultT = (yIntersect - this.point1.y) / this.direction.y;
92
+ }
93
+ else {
94
+ // From above,
95
+ // x = ((o₁ᵧ - o₂ᵧ)(d₁ₓd₂ₓ) + (d₂ᵧd₁ₓ)(o₂ₓ) - (d₁ᵧd₂ₓ)(o₁ₓ))/(d₂ᵧd₁ₓ - d₁ᵧd₂ₓ)
96
+ const numerator = ((this.point1.y - other.point1.y) * this.direction.x * other.direction.x
97
+ + this.direction.x * other.direction.y * other.point1.x
98
+ - this.direction.y * other.direction.x * this.point1.x);
99
+ const denominator = (other.direction.y * this.direction.x
100
+ - this.direction.y * other.direction.x);
101
+ // Avoid dividing by zero. It means there is no intersection
102
+ if (denominator === 0) {
103
+ return null;
104
+ }
105
+ const xIntersect = numerator / denominator;
106
+ const t1 = (xIntersect - this.point1.x) / this.direction.x;
107
+ const yIntersect = this.point1.y + this.direction.y * t1;
108
+ resultPoint = Vec2_1.Vec2.of(xIntersect, yIntersect);
109
+ resultT = (xIntersect - this.point1.x) / this.direction.x;
110
+ }
111
+ // Ensure the result is in this/the other segment.
112
+ const resultToP1 = resultPoint.minus(this.point1).magnitude();
113
+ const resultToP2 = resultPoint.minus(this.point2).magnitude();
114
+ const resultToP3 = resultPoint.minus(other.point1).magnitude();
115
+ const resultToP4 = resultPoint.minus(other.point2).magnitude();
116
+ if (resultToP1 > this.length
117
+ || resultToP2 > this.length
118
+ || resultToP3 > other.length
119
+ || resultToP4 > other.length) {
120
+ return null;
121
+ }
122
+ return {
123
+ point: resultPoint,
124
+ t: resultT,
125
+ };
126
+ }
127
+ intersects(other) {
128
+ return this.intersection(other) !== null;
129
+ }
130
+ /**
131
+ * Returns the points at which this line segment intersects the
132
+ * given line segment.
133
+ *
134
+ * Note that {@link intersects} returns *whether* this line segment intersects another
135
+ * line segment. This method, by contrast, returns **the point** at which the intersection
136
+ * occurs, if such a point exists.
137
+ */
138
+ intersectsLineSegment(lineSegment) {
139
+ const intersection = this.intersection(lineSegment);
140
+ if (intersection) {
141
+ return [intersection.point];
142
+ }
143
+ return [];
144
+ }
145
+ // Returns the closest point on this to [target]
146
+ closestPointTo(target) {
147
+ // Distance from P1 along this' direction.
148
+ const projectedDistFromP1 = target.minus(this.p1).dot(this.direction);
149
+ const projectedDistFromP2 = this.length - projectedDistFromP1;
150
+ const projection = this.p1.plus(this.direction.times(projectedDistFromP1));
151
+ if (projectedDistFromP1 > 0 && projectedDistFromP1 < this.length) {
152
+ return projection;
153
+ }
154
+ if (Math.abs(projectedDistFromP2) < Math.abs(projectedDistFromP1)) {
155
+ return this.p2;
156
+ }
157
+ else {
158
+ return this.p1;
159
+ }
160
+ }
161
+ /**
162
+ * Returns the distance from this line segment to `target`.
163
+ *
164
+ * Because a line segment has no interior, this signed distance is equivalent to
165
+ * the full distance between `target` and this line segment.
166
+ */
167
+ signedDistance(target) {
168
+ return this.closestPointTo(target).minus(target).magnitude();
169
+ }
170
+ /** Returns a copy of this line segment transformed by the given `affineTransfm`. */
171
+ transformedBy(affineTransfm) {
172
+ return new LineSegment2(affineTransfm.transformVec2(this.p1), affineTransfm.transformVec2(this.p2));
173
+ }
174
+ /** @inheritdoc */
175
+ getTightBoundingBox() {
176
+ return this.bbox;
177
+ }
178
+ toString() {
179
+ return `LineSegment(${this.p1.toString()}, ${this.p2.toString()})`;
180
+ }
181
+ }
182
+ exports.LineSegment2 = LineSegment2;
183
+ exports.default = LineSegment2;
@@ -0,0 +1,96 @@
1
+ import LineSegment2 from './LineSegment2';
2
+ import Mat33 from '../Mat33';
3
+ import Rect2 from './Rect2';
4
+ import { Point2 } from '../Vec2';
5
+ import Abstract2DShape from './Abstract2DShape';
6
+ export declare enum PathCommandType {
7
+ LineTo = 0,
8
+ MoveTo = 1,
9
+ CubicBezierTo = 2,
10
+ QuadraticBezierTo = 3
11
+ }
12
+ export interface CubicBezierPathCommand {
13
+ kind: PathCommandType.CubicBezierTo;
14
+ controlPoint1: Point2;
15
+ controlPoint2: Point2;
16
+ endPoint: Point2;
17
+ }
18
+ export interface QuadraticBezierPathCommand {
19
+ kind: PathCommandType.QuadraticBezierTo;
20
+ controlPoint: Point2;
21
+ endPoint: Point2;
22
+ }
23
+ export interface LinePathCommand {
24
+ kind: PathCommandType.LineTo;
25
+ point: Point2;
26
+ }
27
+ export interface MoveToPathCommand {
28
+ kind: PathCommandType.MoveTo;
29
+ point: Point2;
30
+ }
31
+ export type PathCommand = CubicBezierPathCommand | QuadraticBezierPathCommand | MoveToPathCommand | LinePathCommand;
32
+ interface IntersectionResult {
33
+ curve: Abstract2DShape;
34
+ /** @internal @deprecated */
35
+ parameterValue?: number;
36
+ point: Point2;
37
+ }
38
+ type GeometryType = Abstract2DShape;
39
+ type GeometryArrayType = Array<GeometryType>;
40
+ /**
41
+ * Represents a union of lines and curves.
42
+ */
43
+ export declare class Path {
44
+ readonly startPoint: Point2;
45
+ readonly parts: PathCommand[];
46
+ /**
47
+ * A rough estimate of the bounding box of the path.
48
+ * A slight overestimate.
49
+ * See {@link getExactBBox}
50
+ */
51
+ readonly bbox: Rect2;
52
+ constructor(startPoint: Point2, parts: PathCommand[]);
53
+ getExactBBox(): Rect2;
54
+ private cachedGeometry;
55
+ get geometry(): GeometryArrayType;
56
+ private cachedPolylineApproximation;
57
+ polylineApproximation(): LineSegment2[];
58
+ static computeBBoxForSegment(startPoint: Point2, part: PathCommand): Rect2;
59
+ /**
60
+ * Let `S` be a closed path a distance `strokeRadius` from this path.
61
+ *
62
+ * @returns Approximate intersections of `line` with `S` using ray marching, starting from
63
+ * both end points of `line` and each point in `additionalRaymarchStartPoints`.
64
+ */
65
+ private raymarchIntersectionWith;
66
+ /**
67
+ * Returns a list of intersections with this path. If `strokeRadius` is given,
68
+ * intersections are approximated with the surface `strokeRadius` away from this.
69
+ *
70
+ * If `strokeRadius > 0`, the resultant `parameterValue` has no defined value.
71
+ */
72
+ intersection(line: LineSegment2, strokeRadius?: number): IntersectionResult[];
73
+ private static mapPathCommand;
74
+ mapPoints(mapping: (point: Point2) => Point2): Path;
75
+ transformedBy(affineTransfm: Mat33): Path;
76
+ union(other: Path | null): Path;
77
+ private getEndPoint;
78
+ roughlyIntersects(rect: Rect2, strokeWidth?: number): boolean;
79
+ closedRoughlyIntersects(rect: Rect2): boolean;
80
+ static fromRect(rect: Rect2, lineWidth?: number | null): Path;
81
+ private cachedStringVersion;
82
+ toString(useNonAbsCommands?: boolean): string;
83
+ serialize(): string;
84
+ static toString(startPoint: Point2, parts: PathCommand[], onlyAbsCommands?: boolean): string;
85
+ /**
86
+ * Create a Path from a SVG path specification.
87
+ *
88
+ * ## To-do
89
+ * - TODO: Support a larger subset of SVG paths
90
+ * - Elliptical arcs are currently unsupported.
91
+ * - TODO: Support `s`,`t` commands shorthands.
92
+ */
93
+ static fromString(pathString: string): Path;
94
+ static empty: Path;
95
+ }
96
+ export default Path;