@js-draw/math 1.18.0 → 1.21.1

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/Vec3.js CHANGED
@@ -1,32 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Vec3 = void 0;
4
- /**
5
- * A vector with three components, $\begin{pmatrix} x \\ y \\ z \end{pmatrix}$.
6
- * Can also be used to represent a two-component vector.
7
- *
8
- * A `Vec3` is immutable.
9
- *
10
- * @example
11
- *
12
- * ```ts,runnable,console
13
- * import { Vec3 } from '@js-draw/math';
14
- *
15
- * console.log('Vector addition:', Vec3.of(1, 2, 3).plus(Vec3.of(0, 1, 0)));
16
- * console.log('Scalar multiplication:', Vec3.of(1, 2, 3).times(2));
17
- * console.log('Cross products:', Vec3.unitX.cross(Vec3.unitY));
18
- * console.log('Magnitude:', Vec3.of(1, 2, 3).length(), 'or', Vec3.of(1, 2, 3).magnitude());
19
- * console.log('Square Magnitude:', Vec3.of(1, 2, 3).magnitudeSquared());
20
- * console.log('As an array:', Vec3.unitZ.asArray());
21
- * ```
22
- */
23
- class Vec3 {
3
+ exports.Vec3 = exports.Vec2 = void 0;
4
+ const defaultEqlTolerance = 1e-10;
5
+ class Vec3Impl {
24
6
  constructor(x, y, z) {
25
7
  this.x = x;
26
8
  this.y = y;
27
9
  this.z = z;
28
10
  }
29
- /** Returns the x, y components of this. */
30
11
  get xy() {
31
12
  // Useful for APIs that behave differently if .z is present.
32
13
  return {
@@ -34,10 +15,6 @@ class Vec3 {
34
15
  y: this.y,
35
16
  };
36
17
  }
37
- /** Construct a vector from three components. */
38
- static of(x, y, z) {
39
- return new Vec3(x, y, z);
40
- }
41
18
  /** Returns this' `idx`th component. For example, `Vec3.of(1, 2, 3).at(1) → 2`. */
42
19
  at(idx) {
43
20
  if (idx === 0)
@@ -48,89 +25,40 @@ class Vec3 {
48
25
  return this.z;
49
26
  throw new Error(`${idx} out of bounds!`);
50
27
  }
51
- /** Alias for this.magnitude. */
52
28
  length() {
53
29
  return this.magnitude();
54
30
  }
55
31
  magnitude() {
56
- return Math.sqrt(this.dot(this));
32
+ return Math.sqrt(this.magnitudeSquared());
57
33
  }
58
34
  magnitudeSquared() {
59
- return this.dot(this);
35
+ return this.x * this.x + this.y * this.y + this.z * this.z;
60
36
  }
61
- /**
62
- * Interpreting this vector as a point in ℝ^3, computes the square distance
63
- * to another point, `p`.
64
- *
65
- * Equivalent to `.minus(p).magnitudeSquared()`.
66
- */
67
37
  squareDistanceTo(p) {
68
38
  const dx = this.x - p.x;
69
39
  const dy = this.y - p.y;
70
40
  const dz = this.z - p.z;
71
41
  return dx * dx + dy * dy + dz * dz;
72
42
  }
73
- /**
74
- * Interpreting this vector as a point in ℝ³, returns the distance to the point
75
- * `p`.
76
- *
77
- * Equivalent to `.minus(p).magnitude()`.
78
- */
79
43
  distanceTo(p) {
80
44
  return Math.sqrt(this.squareDistanceTo(p));
81
45
  }
82
- /**
83
- * Returns the entry of this with the greatest magnitude.
84
- *
85
- * In other words, returns $\max \{ |x| : x \in {\bf v} \}$, where ${\bf v}$ is the set of
86
- * all entries of this vector.
87
- *
88
- * **Example**:
89
- * ```ts,runnable,console
90
- * import { Vec3 } from '@js-draw/math';
91
- * console.log(Vec3.of(-1, -10, 8).maximumEntryMagnitude()); // -> 10
92
- * ```
93
- */
94
46
  maximumEntryMagnitude() {
95
47
  return Math.max(Math.abs(this.x), Math.max(Math.abs(this.y), Math.abs(this.z)));
96
48
  }
97
- /**
98
- * Return this' angle in the XY plane (treats this as a Vec2).
99
- *
100
- * This is equivalent to `Math.atan2(vec.y, vec.x)`.
101
- *
102
- * As such, observing that `Math.atan2(-0, -1)` $\approx -\pi$ and `Math.atan2(0, -1)`$\approx \pi$
103
- * the resultant angle is in the range $[-\pi, pi]$.
104
- *
105
- * **Example**:
106
- * ```ts,runnable,console
107
- * import { Vec2 } from '@js-draw/math';
108
- * console.log(Vec2.of(-1, -0).angle()); // atan2(-0, -1)
109
- * console.log(Vec2.of(-1, 0).angle()); // atan2(0, -1)
110
- * ```
111
- */
112
49
  angle() {
113
50
  return Math.atan2(this.y, this.x);
114
51
  }
115
- /**
116
- * Returns a unit vector in the same direction as this.
117
- *
118
- * If `this` has zero length, the resultant vector has `NaN` components.
119
- */
120
52
  normalized() {
121
53
  const norm = this.magnitude();
122
54
  return Vec3.of(this.x / norm, this.y / norm, this.z / norm);
123
55
  }
124
- /**
125
- * Like {@link normalized}, except returns zero if this has zero magnitude.
126
- */
127
56
  normalizedOrZero() {
128
57
  if (this.eq(Vec3.zero)) {
129
58
  return Vec3.zero;
130
59
  }
131
60
  return this.normalized();
132
61
  }
133
- /** @returns A copy of `this` multiplied by a scalar. */
134
62
  times(c) {
135
63
  return Vec3.of(this.x * c, this.y * c, this.z * c);
136
64
  }
@@ -149,25 +77,12 @@ class Vec3 {
149
77
  // | x2 y2 z2|
150
78
  return Vec3.of(this.y * other.z - other.y * this.z, other.x * this.z - this.x * other.z, this.x * other.y - other.x * this.y);
151
79
  }
152
- /**
153
- * If `other` is a `Vec3`, multiplies `this` component-wise by `other`. Otherwise,
154
- * if `other is a `number`, returns the result of scalar multiplication.
155
- *
156
- * @example
157
- * ```
158
- * Vec3.of(1, 2, 3).scale(Vec3.of(2, 4, 6)); // → Vec3(2, 8, 18)
159
- * ```
160
- */
161
80
  scale(other) {
162
81
  if (typeof other === 'number') {
163
82
  return this.times(other);
164
83
  }
165
84
  return Vec3.of(this.x * other.x, this.y * other.y, this.z * other.z);
166
85
  }
167
- /**
168
- * Returns a vector orthogonal to this. If this is a Vec2, returns `this` rotated
169
- * 90 degrees counter-clockwise.
170
- */
171
86
  orthog() {
172
87
  // If parallel to the z-axis
173
88
  if (this.dot(Vec3.unitX) === 0 && this.dot(Vec3.unitY) === 0) {
@@ -175,62 +90,22 @@ class Vec3 {
175
90
  }
176
91
  return this.cross(Vec3.unitZ.times(-1)).normalized();
177
92
  }
178
- /** Returns this plus a vector of length `distance` in `direction`. */
179
93
  extend(distance, direction) {
180
94
  return this.plus(direction.normalized().times(distance));
181
95
  }
182
- /** Returns a vector `fractionTo` of the way to target from this. */
183
96
  lerp(target, fractionTo) {
184
97
  return this.times(1 - fractionTo).plus(target.times(fractionTo));
185
98
  }
186
- /**
187
- * `zip` Maps a component of this and a corresponding component of
188
- * `other` to a component of the output vector.
189
- *
190
- * @example
191
- * ```
192
- * const a = Vec3.of(1, 2, 3);
193
- * const b = Vec3.of(0.5, 2.1, 2.9);
194
- *
195
- * const zipped = a.zip(b, (aComponent, bComponent) => {
196
- * return Math.min(aComponent, bComponent);
197
- * });
198
- *
199
- * console.log(zipped.toString()); // → Vec(0.5, 2, 2.9)
200
- * ```
201
- */
202
99
  zip(other, zip) {
203
100
  return Vec3.of(zip(other.x, this.x), zip(other.y, this.y), zip(other.z, this.z));
204
101
  }
205
- /**
206
- * Returns a vector with each component acted on by `fn`.
207
- *
208
- * @example
209
- * ```ts,runnable,console
210
- * import { Vec3 } from '@js-draw/math';
211
- * console.log(Vec3.of(1, 2, 3).map(val => val + 1)); // → Vec(2, 3, 4)
212
- * ```
213
- */
214
102
  map(fn) {
215
103
  return Vec3.of(fn(this.x, 0), fn(this.y, 1), fn(this.z, 2));
216
104
  }
217
105
  asArray() {
218
106
  return [this.x, this.y, this.z];
219
107
  }
220
- /**
221
- * [fuzz] The maximum difference between two components for this and [other]
222
- * to be considered equal.
223
- *
224
- * @example
225
- * ```
226
- * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 100); // → true
227
- * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 0.1); // → false
228
- * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 3); // → true
229
- * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 3.01); // → true
230
- * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 2.99); // → false
231
- * ```
232
- */
233
- eq(other, fuzz = 1e-10) {
108
+ eq(other, fuzz = defaultEqlTolerance) {
234
109
  return (Math.abs(other.x - this.x) <= fuzz
235
110
  && Math.abs(other.y - this.y) <= fuzz
236
111
  && Math.abs(other.z - this.z) <= fuzz);
@@ -239,9 +114,182 @@ class Vec3 {
239
114
  return `Vec(${this.x}, ${this.y}, ${this.z})`;
240
115
  }
241
116
  }
242
- exports.Vec3 = Vec3;
243
- Vec3.unitX = Vec3.of(1, 0, 0);
244
- Vec3.unitY = Vec3.of(0, 1, 0);
245
- Vec3.unitZ = Vec3.of(0, 0, 1);
246
- Vec3.zero = Vec3.of(0, 0, 0);
117
+ class Vec2Impl {
118
+ constructor(x, y) {
119
+ this.x = x;
120
+ this.y = y;
121
+ }
122
+ get z() { return 0; }
123
+ get xy() {
124
+ // Useful for APIs that behave differently if .z is present.
125
+ return {
126
+ x: this.x,
127
+ y: this.y,
128
+ };
129
+ }
130
+ at(idx) {
131
+ if (idx === 0)
132
+ return this.x;
133
+ if (idx === 1)
134
+ return this.y;
135
+ if (idx === 2)
136
+ return 0;
137
+ throw new Error(`${idx} out of bounds!`);
138
+ }
139
+ length() {
140
+ return this.magnitude();
141
+ }
142
+ magnitude() {
143
+ return Math.sqrt(this.x * this.x + this.y * this.y);
144
+ }
145
+ magnitudeSquared() {
146
+ return this.x * this.x + this.y * this.y;
147
+ }
148
+ squareDistanceTo(p) {
149
+ const dx = this.x - p.x;
150
+ const dy = this.y - p.y;
151
+ return dx * dx + dy * dy + p.z * p.z;
152
+ }
153
+ distanceTo(p) {
154
+ return Math.sqrt(this.squareDistanceTo(p));
155
+ }
156
+ maximumEntryMagnitude() {
157
+ return Math.max(Math.abs(this.x), Math.abs(this.y));
158
+ }
159
+ angle() {
160
+ return Math.atan2(this.y, this.x);
161
+ }
162
+ normalized() {
163
+ const norm = this.magnitude();
164
+ return Vec2.of(this.x / norm, this.y / norm);
165
+ }
166
+ normalizedOrZero() {
167
+ if (this.eq(Vec3.zero)) {
168
+ return Vec3.zero;
169
+ }
170
+ return this.normalized();
171
+ }
172
+ times(c) {
173
+ return Vec2.of(this.x * c, this.y * c);
174
+ }
175
+ plus(v) {
176
+ return Vec3.of(this.x + v.x, this.y + v.y, v.z);
177
+ }
178
+ minus(v) {
179
+ return Vec3.of(this.x - v.x, this.y - v.y, -v.z);
180
+ }
181
+ dot(other) {
182
+ return this.x * other.x + this.y * other.y;
183
+ }
184
+ cross(other) {
185
+ // | i j k |
186
+ // | x1 y1 z1| = (i)(y1z2 - y2z1) - (j)(x1z2 - x2z1) + (k)(x1y2 - x2y1)
187
+ // | x2 y2 z2|
188
+ return Vec3.of(this.y * other.z, -this.x * other.z, this.x * other.y - other.x * this.y);
189
+ }
190
+ scale(other) {
191
+ if (typeof other === 'number') {
192
+ return this.times(other);
193
+ }
194
+ return Vec2.of(this.x * other.x, this.y * other.y);
195
+ }
196
+ orthog() {
197
+ // If parallel to the z-axis
198
+ if (this.dot(Vec3.unitX) === 0 && this.dot(Vec3.unitY) === 0) {
199
+ return this.dot(Vec3.unitX) === 0 ? Vec3.unitX : this.cross(Vec3.unitX).normalized();
200
+ }
201
+ return this.cross(Vec3.unitZ.times(-1)).normalized();
202
+ }
203
+ extend(distance, direction) {
204
+ return this.plus(direction.normalized().times(distance));
205
+ }
206
+ lerp(target, fractionTo) {
207
+ return this.times(1 - fractionTo).plus(target.times(fractionTo));
208
+ }
209
+ zip(other, zip) {
210
+ return Vec3.of(zip(other.x, this.x), zip(other.y, this.y), zip(other.z, 0));
211
+ }
212
+ map(fn) {
213
+ return Vec3.of(fn(this.x, 0), fn(this.y, 1), fn(0, 2));
214
+ }
215
+ asArray() {
216
+ return [this.x, this.y, 0];
217
+ }
218
+ eq(other, fuzz = defaultEqlTolerance) {
219
+ return (Math.abs(other.x - this.x) <= fuzz
220
+ && Math.abs(other.y - this.y) <= fuzz
221
+ && Math.abs(other.z) <= fuzz);
222
+ }
223
+ toString() {
224
+ return `Vec(${this.x}, ${this.y})`;
225
+ }
226
+ }
227
+ /**
228
+ * A `Vec2` is a `Vec3` optimized for working in a plane. As such, they have an
229
+ * always-zero `z` component.
230
+ *
231
+ * ```ts,runnable,console
232
+ * import { Vec2 } from '@js-draw/math';
233
+ * console.log(Vec2.of(1, 2));
234
+ * ```
235
+ */
236
+ var Vec2;
237
+ (function (Vec2) {
238
+ /**
239
+ * Creates a `Vec2` from an x and y coordinate.
240
+ *
241
+ * @example
242
+ * ```ts,runnable,console
243
+ * import { Vec2 } from '@js-draw/math';
244
+ * const v = Vec2.of(3, 4); // x=3, y=4.
245
+ * ```
246
+ */
247
+ Vec2.of = (x, y) => {
248
+ return new Vec2Impl(x, y);
249
+ };
250
+ /**
251
+ * Creates a `Vec2` from an object containing `x` and `y` coordinates.
252
+ *
253
+ * @example
254
+ * ```ts,runnable,console
255
+ * import { Vec2 } from '@js-draw/math';
256
+ * const v1 = Vec2.ofXY({ x: 3, y: 4.5 });
257
+ * const v2 = Vec2.ofXY({ x: -123.4, y: 1 });
258
+ * ```
259
+ */
260
+ Vec2.ofXY = ({ x, y }) => {
261
+ return Vec2.of(x, y);
262
+ };
263
+ /** A vector of length 1 in the X direction (→). */
264
+ Vec2.unitX = Vec2.of(1, 0);
265
+ /** A vector of length 1 in the Y direction (↑). */
266
+ Vec2.unitY = Vec2.of(0, 1);
267
+ /** The zero vector: A vector with x=0, y=0. */
268
+ Vec2.zero = Vec2.of(0, 0);
269
+ })(Vec2 || (exports.Vec2 = Vec2 = {}));
270
+ var Vec3;
271
+ (function (Vec3) {
272
+ /**
273
+ * Construct a vector from three components.
274
+ *
275
+ * @example
276
+ * ```ts,runnable,console
277
+ * import { Vec3 } from '@js-draw/math';
278
+ * const v1 = Vec3.of(1, 2, 3);
279
+ * ```
280
+ */
281
+ Vec3.of = (x, y, z) => {
282
+ if (z === 0) {
283
+ return Vec2.of(x, y);
284
+ }
285
+ else {
286
+ return new Vec3Impl(x, y, z);
287
+ }
288
+ };
289
+ Vec3.unitX = Vec2.unitX;
290
+ Vec3.unitY = Vec2.unitY;
291
+ Vec3.zero = Vec2.zero;
292
+ /** A vector of length 1 in the z direction. */
293
+ Vec3.unitZ = Vec3.of(0, 0, 1);
294
+ })(Vec3 || (exports.Vec3 = Vec3 = {}));
247
295
  exports.default = Vec3;
@@ -7,7 +7,18 @@ interface IntersectionResult {
7
7
  point: Point2;
8
8
  t: number;
9
9
  }
10
- /** Represents a line segment. A `LineSegment2` is immutable. */
10
+ /**
11
+ * Represents a line segment. A `LineSegment2` is immutable.
12
+ *
13
+ * @example
14
+ * ```ts,runnable,console
15
+ * import {LineSegment2, Vec2} from '@js-draw/math';
16
+ * const l = new LineSegment2(Vec2.of(1, 1), Vec2.of(2, 2));
17
+ * console.log('length: ', l.length);
18
+ * console.log('direction: ', l.direction);
19
+ * console.log('bounding box: ', l.bbox);
20
+ * ```
21
+ */
11
22
  export declare class LineSegment2 extends Parameterized2DShape {
12
23
  private readonly point1;
13
24
  private readonly point2;
@@ -30,7 +41,7 @@ export declare class LineSegment2 extends Parameterized2DShape {
30
41
  * if no such line segment exists.
31
42
  *
32
43
  * @example
33
- * ```ts,runnable
44
+ * ```ts,runnable,console
34
45
  * import {LineSegment2, Vec2} from '@js-draw/math';
35
46
  * console.log(LineSegment2.ofSmallestContainingPoints([Vec2.of(1, 0), Vec2.of(0, 1)]));
36
47
  * ```
@@ -7,7 +7,18 @@ exports.LineSegment2 = void 0;
7
7
  const Rect2_1 = __importDefault(require("./Rect2"));
8
8
  const Vec2_1 = require("../Vec2");
9
9
  const Parameterized2DShape_1 = __importDefault(require("./Parameterized2DShape"));
10
- /** Represents a line segment. A `LineSegment2` is immutable. */
10
+ /**
11
+ * Represents a line segment. A `LineSegment2` is immutable.
12
+ *
13
+ * @example
14
+ * ```ts,runnable,console
15
+ * import {LineSegment2, Vec2} from '@js-draw/math';
16
+ * const l = new LineSegment2(Vec2.of(1, 1), Vec2.of(2, 2));
17
+ * console.log('length: ', l.length);
18
+ * console.log('direction: ', l.direction);
19
+ * console.log('bounding box: ', l.bbox);
20
+ * ```
21
+ */
11
22
  class LineSegment2 extends Parameterized2DShape_1.default {
12
23
  /** Creates a new `LineSegment2` from its endpoints. */
13
24
  constructor(point1, point2) {
@@ -27,7 +38,7 @@ class LineSegment2 extends Parameterized2DShape_1.default {
27
38
  * if no such line segment exists.
28
39
  *
29
40
  * @example
30
- * ```ts,runnable
41
+ * ```ts,runnable,console
31
42
  * import {LineSegment2, Vec2} from '@js-draw/math';
32
43
  * console.log(LineSegment2.ofSmallestContainingPoints([Vec2.of(1, 0), Vec2.of(0, 1)]));
33
44
  * ```
@@ -18,7 +18,39 @@ declare class PointShape2D extends Parameterized2DShape {
18
18
  /**
19
19
  * Returns an arbitrary unit-length vector.
20
20
  */
21
- normalAt(_t: number): Vec3;
21
+ normalAt(_t: number): {
22
+ readonly x: number;
23
+ readonly y: number;
24
+ readonly z: number;
25
+ readonly xy: {
26
+ x: number;
27
+ y: number;
28
+ };
29
+ at(idx: number): number;
30
+ length(): number;
31
+ magnitude(): number;
32
+ magnitudeSquared(): number;
33
+ squareDistanceTo(p: Vec3): number;
34
+ distanceTo(p: Vec3): number;
35
+ maximumEntryMagnitude(): number;
36
+ angle(): number;
37
+ normalized(): Vec3;
38
+ normalizedOrZero(): Vec3;
39
+ times(c: number): Vec3;
40
+ plus(v: Vec3): Vec3;
41
+ minus(v: Vec3): Vec3;
42
+ dot(other: Vec3): number;
43
+ cross(other: Vec3): Vec3;
44
+ scale(other: Vec3 | number): Vec3;
45
+ orthog(): Vec3;
46
+ extend(distance: number, direction: Vec3): Vec3;
47
+ lerp(target: Vec3, fractionTo: number): Vec3;
48
+ zip(other: Vec3, zip: (componentInThis: number, componentInOther: number) => number): Vec3;
49
+ map(fn: (component: number, index: number) => number): Vec3;
50
+ asArray(): [number, number, number];
51
+ eq(other: Vec3, fuzz?: number): boolean;
52
+ toString(): string;
53
+ };
22
54
  tangentAt(_t: number): Vec3;
23
55
  splitAt(_t: number): [PointShape2D];
24
56
  nearestPointTo(_point: Point2): {
@@ -57,14 +57,46 @@ export declare class Rect2 extends Abstract2DShape {
57
57
  get bottomLeft(): Vec3;
58
58
  get width(): number;
59
59
  get height(): number;
60
- get center(): Vec3;
60
+ get center(): {
61
+ readonly x: number;
62
+ readonly y: number;
63
+ readonly z: number;
64
+ readonly xy: {
65
+ x: number;
66
+ y: number;
67
+ };
68
+ at(idx: number): number;
69
+ length(): number;
70
+ magnitude(): number;
71
+ magnitudeSquared(): number;
72
+ squareDistanceTo(p: Vec3): number;
73
+ distanceTo(p: Vec3): number;
74
+ maximumEntryMagnitude(): number;
75
+ angle(): number;
76
+ normalized(): Vec3;
77
+ normalizedOrZero(): Vec3;
78
+ times(c: number): Vec3;
79
+ plus(v: Vec3): Vec3;
80
+ minus(v: Vec3): Vec3;
81
+ dot(other: Vec3): number;
82
+ cross(other: Vec3): Vec3;
83
+ scale(other: Vec3 | number): Vec3;
84
+ orthog(): Vec3;
85
+ extend(distance: number, direction: Vec3): Vec3;
86
+ lerp(target: Vec3, fractionTo: number): Vec3;
87
+ zip(other: Vec3, zip: (componentInThis: number, componentInOther: number) => number): Vec3;
88
+ map(fn: (component: number, index: number) => number): Vec3;
89
+ asArray(): [number, number, number];
90
+ eq(other: Vec3, fuzz?: number): boolean;
91
+ toString(): string;
92
+ };
61
93
  getEdges(): LineSegment2[];
62
94
  intersectsLineSegment(lineSegment: LineSegment2): Point2[];
63
95
  signedDistance(point: Vec3): number;
64
96
  getTightBoundingBox(): Rect2;
65
97
  transformedBoundingBox(affineTransform: Mat33): Rect2;
66
- /** @return true iff this is equal to [other] ± fuzz */
67
- eq(other: Rect2, fuzz?: number): boolean;
98
+ /** @return true iff this is equal to `other ± tolerance` */
99
+ eq(other: Rect2, tolerance?: number): boolean;
68
100
  toString(): string;
69
101
  static fromCorners(corner1: Point2, corner2: Point2): Rect2;
70
102
  static bboxOf(points: Point2[], margin?: number): Rect2;
@@ -227,9 +227,9 @@ class Rect2 extends Abstract2DShape_1.default {
227
227
  transformedBoundingBox(affineTransform) {
228
228
  return Rect2.bboxOf(this.corners.map(corner => affineTransform.transformVec2(corner)));
229
229
  }
230
- /** @return true iff this is equal to [other] ± fuzz */
231
- eq(other, fuzz = 0) {
232
- return this.topLeft.eq(other.topLeft, fuzz) && this.size.eq(other.size, fuzz);
230
+ /** @return true iff this is equal to `other ± tolerance` */
231
+ eq(other, tolerance = 0) {
232
+ return this.topLeft.eq(other.topLeft, tolerance) && this.size.eq(other.size, tolerance);
233
233
  }
234
234
  toString() {
235
235
  return `Rect(point(${this.x}, ${this.y}), size(${this.w}, ${this.h}))`;