@js-draw/math 1.21.2 → 1.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. package/build-config.json +1 -1
  2. package/dist/cjs/Color4.js +2 -2
  3. package/dist/cjs/Mat33.d.ts +1 -11
  4. package/dist/cjs/Mat33.js +8 -24
  5. package/dist/cjs/Vec3.js +9 -7
  6. package/dist/cjs/shapes/BezierJSWrapper.js +20 -13
  7. package/dist/cjs/shapes/LineSegment2.js +13 -17
  8. package/dist/cjs/shapes/Parameterized2DShape.js +1 -1
  9. package/dist/cjs/shapes/Path.js +49 -47
  10. package/dist/cjs/shapes/Rect2.js +13 -15
  11. package/dist/cjs/shapes/Triangle.js +4 -5
  12. package/dist/cjs/utils/convexHull2Of.js +3 -3
  13. package/dist/mjs/Color4.mjs +2 -2
  14. package/dist/mjs/Mat33.d.ts +1 -11
  15. package/dist/mjs/Mat33.mjs +8 -24
  16. package/dist/mjs/Vec3.mjs +9 -7
  17. package/dist/mjs/shapes/BezierJSWrapper.mjs +20 -13
  18. package/dist/mjs/shapes/LineSegment2.mjs +13 -17
  19. package/dist/mjs/shapes/Parameterized2DShape.mjs +1 -1
  20. package/dist/mjs/shapes/Path.mjs +49 -47
  21. package/dist/mjs/shapes/Rect2.mjs +13 -15
  22. package/dist/mjs/shapes/Triangle.mjs +4 -5
  23. package/dist/mjs/utils/convexHull2Of.mjs +3 -3
  24. package/dist-test/test_imports/test-require.cjs +1 -1
  25. package/package.json +3 -3
  26. package/src/Color4.test.ts +16 -21
  27. package/src/Color4.ts +22 -17
  28. package/src/Mat33.fromCSSMatrix.test.ts +31 -45
  29. package/src/Mat33.test.ts +58 -96
  30. package/src/Mat33.ts +61 -104
  31. package/src/Vec2.test.ts +3 -3
  32. package/src/Vec3.test.ts +2 -3
  33. package/src/Vec3.ts +34 -58
  34. package/src/lib.ts +0 -2
  35. package/src/polynomial/solveQuadratic.test.ts +39 -13
  36. package/src/polynomial/solveQuadratic.ts +5 -6
  37. package/src/rounding/cleanUpNumber.test.ts +1 -1
  38. package/src/rounding/constants.ts +1 -3
  39. package/src/rounding/getLenAfterDecimal.ts +1 -2
  40. package/src/rounding/lib.ts +1 -2
  41. package/src/rounding/toRoundedString.test.ts +1 -1
  42. package/src/rounding/toStringOfSamePrecision.test.ts +1 -2
  43. package/src/rounding/toStringOfSamePrecision.ts +1 -1
  44. package/src/shapes/BezierJSWrapper.ts +54 -37
  45. package/src/shapes/CubicBezier.ts +3 -3
  46. package/src/shapes/LineSegment2.test.ts +24 -17
  47. package/src/shapes/LineSegment2.ts +26 -29
  48. package/src/shapes/Parameterized2DShape.ts +5 -4
  49. package/src/shapes/Path.fromString.test.ts +5 -5
  50. package/src/shapes/Path.test.ts +122 -120
  51. package/src/shapes/Path.toString.test.ts +7 -7
  52. package/src/shapes/Path.ts +378 -352
  53. package/src/shapes/PointShape2D.ts +3 -3
  54. package/src/shapes/QuadraticBezier.test.ts +27 -21
  55. package/src/shapes/QuadraticBezier.ts +4 -9
  56. package/src/shapes/Rect2.test.ts +44 -75
  57. package/src/shapes/Rect2.ts +30 -35
  58. package/src/shapes/Triangle.test.ts +31 -29
  59. package/src/shapes/Triangle.ts +17 -18
  60. package/src/utils/convexHull2Of.test.ts +54 -15
  61. package/src/utils/convexHull2Of.ts +9 -7
  62. package/tsconfig.json +1 -3
  63. package/typedoc.json +2 -2
package/src/Mat33.ts CHANGED
@@ -4,11 +4,7 @@ import Vec3 from './Vec3';
4
4
  /**
5
5
  * See {@link Mat33.toArray}.
6
6
  */
7
- export type Mat33Array = [
8
- number, number, number,
9
- number, number, number,
10
- number, number, number,
11
- ];
7
+ export type Mat33Array = [number, number, number, number, number, number, number, number, number];
12
8
 
13
9
  /**
14
10
  * Represents a three dimensional linear transformation or
@@ -82,13 +78,9 @@ export class Mat33 {
82
78
 
83
79
  public readonly c1: number,
84
80
  public readonly c2: number,
85
- public readonly c3: number
81
+ public readonly c3: number,
86
82
  ) {
87
- this.rows = [
88
- Vec3.of(a1, a2, a3),
89
- Vec3.of(b1, b2, b3),
90
- Vec3.of(c1, c2, c3),
91
- ];
83
+ this.rows = [Vec3.of(a1, a2, a3), Vec3.of(b1, b2, b3), Vec3.of(c1, c2, c3)];
92
84
  }
93
85
 
94
86
  /**
@@ -102,19 +94,11 @@ export class Mat33 {
102
94
  * $$
103
95
  */
104
96
  public static ofRows(r1: Vec3, r2: Vec3, r3: Vec3): Mat33 {
105
- return new Mat33(
106
- r1.x, r1.y, r1.z,
107
- r2.x, r2.y, r2.z,
108
- r3.x, r3.y, r3.z
109
- );
97
+ return new Mat33(r1.x, r1.y, r1.z, r2.x, r2.y, r2.z, r3.x, r3.y, r3.z);
110
98
  }
111
99
 
112
100
  /** The 3x3 [identity matrix](https://en.wikipedia.org/wiki/Identity_matrix). */
113
- public static identity = new Mat33(
114
- 1, 0, 0,
115
- 0, 1, 0,
116
- 0, 0, 1
117
- );
101
+ public static identity = new Mat33(1, 0, 0, 0, 1, 0, 0, 0, 1);
118
102
 
119
103
  /**
120
104
  * Either returns the inverse of this, or, if this matrix is singular/uninvertable,
@@ -131,23 +115,15 @@ export class Mat33 {
131
115
  return this.computeInverse() !== null;
132
116
  }
133
117
 
134
- private cachedInverse: Mat33|undefined|null = undefined;
135
- private computeInverse(): Mat33|null {
118
+ private cachedInverse: Mat33 | undefined | null = undefined;
119
+ private computeInverse(): Mat33 | null {
136
120
  if (this.cachedInverse !== undefined) {
137
121
  return this.cachedInverse;
138
122
  }
139
123
 
140
- const toIdentity = [
141
- this.rows[0],
142
- this.rows[1],
143
- this.rows[2],
144
- ];
124
+ const toIdentity = [this.rows[0], this.rows[1], this.rows[2]];
145
125
 
146
- const toResult = [
147
- Vec3.unitX,
148
- Vec3.unitY,
149
- Vec3.unitZ,
150
- ];
126
+ const toResult = [Vec3.unitX, Vec3.unitY, Vec3.unitZ];
151
127
 
152
128
  // Convert toIdentity to the identity matrix and
153
129
  // toResult to the inverse through elementary row operations
@@ -199,29 +175,27 @@ export class Mat33 {
199
175
  for (let i = 1; i <= 2; i++) {
200
176
  const otherRowIdx = (cursor + i) % 3;
201
177
  scale = -toIdentity[otherRowIdx].at(cursor);
202
- toIdentity[otherRowIdx] = toIdentity[otherRowIdx].plus(
203
- cursorToIdentityRow.times(scale)
204
- );
205
- toResult[otherRowIdx] = toResult[otherRowIdx].plus(
206
- cursorToResultRow.times(scale)
207
- );
178
+ toIdentity[otherRowIdx] = toIdentity[otherRowIdx].plus(cursorToIdentityRow.times(scale));
179
+ toResult[otherRowIdx] = toResult[otherRowIdx].plus(cursorToResultRow.times(scale));
208
180
  }
209
181
  }
210
182
 
211
- const inverse = Mat33.ofRows(
212
- toResult[0],
213
- toResult[1],
214
- toResult[2]
215
- );
183
+ const inverse = Mat33.ofRows(toResult[0], toResult[1], toResult[2]);
216
184
  this.cachedInverse = inverse;
217
185
  return inverse;
218
186
  }
219
187
 
220
188
  public transposed(): Mat33 {
221
189
  return new Mat33(
222
- this.a1, this.b1, this.c1,
223
- this.a2, this.b2, this.c2,
224
- this.a3, this.b3, this.c3
190
+ this.a1,
191
+ this.b1,
192
+ this.c1,
193
+ this.a2,
194
+ this.b2,
195
+ this.c2,
196
+ this.a3,
197
+ this.b3,
198
+ this.c3,
225
199
  );
226
200
  }
227
201
 
@@ -256,9 +230,15 @@ export class Mat33 {
256
230
  };
257
231
 
258
232
  return new Mat33(
259
- at(0, 0), at(0, 1), at(0, 2),
260
- at(1, 0), at(1, 1), at(1, 2),
261
- at(2, 0), at(2, 1), at(2, 2)
233
+ at(0, 0),
234
+ at(0, 1),
235
+ at(0, 2),
236
+ at(1, 0),
237
+ at(1, 1),
238
+ at(1, 2),
239
+ at(2, 0),
240
+ at(2, 1),
241
+ at(2, 2),
262
242
  );
263
243
  }
264
244
 
@@ -288,11 +268,7 @@ export class Mat33 {
288
268
  * This is the standard way of transforming vectors in ℝ³.
289
269
  */
290
270
  public transformVec3(other: Vec3): Vec3 {
291
- return Vec3.of(
292
- this.rows[0].dot(other),
293
- this.rows[1].dot(other),
294
- this.rows[2].dot(other)
295
- );
271
+ return Vec3.of(this.rows[0].dot(other), this.rows[1].dot(other), this.rows[2].dot(other));
296
272
  }
297
273
 
298
274
  /** @returns true iff this is the identity matrix. */
@@ -326,7 +302,7 @@ export class Mat33 {
326
302
  */
327
303
  public toString(): string {
328
304
  let result = '';
329
- const maxColumnLens = [ 0, 0, 0 ];
305
+ const maxColumnLens = [0, 0, 0];
330
306
 
331
307
  // Determine the longest item in each column so we can pad the others to that
332
308
  // length.
@@ -390,11 +366,7 @@ export class Mat33 {
390
366
  * ```
391
367
  */
392
368
  public toArray(): Mat33Array {
393
- return [
394
- this.a1, this.a2, this.a3,
395
- this.b1, this.b2, this.b3,
396
- this.c1, this.c2, this.c3,
397
- ];
369
+ return [this.a1, this.a2, this.a3, this.b1, this.b2, this.b3, this.c1, this.c2, this.c3];
398
370
  }
399
371
 
400
372
  /**
@@ -413,11 +385,17 @@ export class Mat33 {
413
385
  * // ⎣ 6, 7, 8 ⎦
414
386
  * ```
415
387
  */
416
- public mapEntries(mapping: (component: number, rowcol: [number, number])=>number): Mat33 {
388
+ public mapEntries(mapping: (component: number, rowcol: [number, number]) => number): Mat33 {
417
389
  return new Mat33(
418
- mapping(this.a1, [0, 0]), mapping(this.a2, [0, 1]), mapping(this.a3, [0, 2]),
419
- mapping(this.b1, [1, 0]), mapping(this.b2, [1, 1]), mapping(this.b3, [1, 2]),
420
- mapping(this.c1, [2, 0]), mapping(this.c2, [2, 1]), mapping(this.c3, [2, 2]),
390
+ mapping(this.a1, [0, 0]),
391
+ mapping(this.a2, [0, 1]),
392
+ mapping(this.a3, [0, 2]),
393
+ mapping(this.b1, [1, 0]),
394
+ mapping(this.b2, [1, 1]),
395
+ mapping(this.b3, [1, 2]),
396
+ mapping(this.c1, [2, 0]),
397
+ mapping(this.c2, [2, 1]),
398
+ mapping(this.c3, [2, 2]),
421
399
  );
422
400
  }
423
401
 
@@ -428,11 +406,7 @@ export class Mat33 {
428
406
 
429
407
  /** Returns the `idx`-th column (`idx` is 0-indexed). */
430
408
  public getColumn(idx: number) {
431
- return Vec3.of(
432
- this.rows[0].at(idx),
433
- this.rows[1].at(idx),
434
- this.rows[2].at(idx),
435
- );
409
+ return Vec3.of(this.rows[0].at(idx), this.rows[1].at(idx), this.rows[2].at(idx));
436
410
  }
437
411
 
438
412
  /** Returns the magnitude of the entry with the largest entry */
@@ -463,11 +437,7 @@ export class Mat33 {
463
437
  // Vec2s z = 1. As such,
464
438
  // outVec2.x = inVec2.x * 1 + inVec2.y * 0 + 1 * amount.x
465
439
  // ...
466
- return new Mat33(
467
- 1, 0, amount.x,
468
- 0, 1, amount.y,
469
- 0, 0, 1
470
- );
440
+ return new Mat33(1, 0, amount.x, 0, 1, amount.y, 0, 0, 1);
471
441
  }
472
442
 
473
443
  public static zRotation(radians: number, center: Point2 = Vec2.zero): Mat33 {
@@ -481,15 +451,11 @@ export class Mat33 {
481
451
  // Translate everything so that rotation is about the origin
482
452
  let result = Mat33.translation(center);
483
453
 
484
- result = result.rightMul(new Mat33(
485
- cos, -sin, 0,
486
- sin, cos, 0,
487
- 0, 0, 1
488
- ));
454
+ result = result.rightMul(new Mat33(cos, -sin, 0, sin, cos, 0, 0, 0, 1));
489
455
  return result.rightMul(Mat33.translation(center.times(-1)));
490
456
  }
491
457
 
492
- public static scaling2D(amount: number|Vec2, center: Point2 = Vec2.zero): Mat33 {
458
+ public static scaling2D(amount: number | Vec2, center: Point2 = Vec2.zero): Mat33 {
493
459
  let result = Mat33.translation(center);
494
460
  let xAmount, yAmount;
495
461
 
@@ -501,11 +467,7 @@ export class Mat33 {
501
467
  yAmount = amount.y;
502
468
  }
503
469
 
504
- result = result.rightMul(new Mat33(
505
- xAmount, 0, 0,
506
- 0, yAmount, 0,
507
- 0, 0, 1
508
- ));
470
+ result = result.rightMul(new Mat33(xAmount, 0, 0, 0, yAmount, 0, 0, 0, 1));
509
471
 
510
472
  // Translate such that [center] goes to (0, 0)
511
473
  return result.rightMul(Mat33.translation(center.times(-1)));
@@ -536,7 +498,7 @@ export class Mat33 {
536
498
  }
537
499
 
538
500
  const parseArguments = (argumentString: string): number[] => {
539
- const parsed = argumentString.split(/[, \t\n]+/g).map(argString => {
501
+ const parsed = argumentString.split(/[, \t\n]+/g).map((argString) => {
540
502
  // Handle trailing spaces/commands
541
503
  if (argString.trim() === '') {
542
504
  return null;
@@ -549,18 +511,16 @@ export class Mat33 {
549
511
  }
550
512
 
551
513
  // Remove trailing px units.
552
- argString = argString.replace(/px$/ig, '');
514
+ argString = argString.replace(/px$/gi, '');
553
515
 
554
516
  const numberExp = /^[-]?\d*(?:\.\d*)?(?:[eE][-+]?\d+)?$/i;
555
517
 
556
518
  if (!numberExp.exec(argString)) {
557
519
  throw new Error(
558
- `All arguments to transform functions must be numeric (state: ${
559
- JSON.stringify({
560
- currentArgument: argString,
561
- allArguments: argumentString,
562
- })
563
- })`
520
+ `All arguments to transform functions must be numeric (state: ${JSON.stringify({
521
+ currentArgument: argString,
522
+ allArguments: argumentString,
523
+ })})`,
564
524
  );
565
525
  }
566
526
 
@@ -572,10 +532,9 @@ export class Mat33 {
572
532
 
573
533
  return argNumber;
574
534
  });
575
- return parsed.filter(n => n !== null);
535
+ return parsed.filter((n) => n !== null);
576
536
  };
577
537
 
578
-
579
538
  const keywordToAction = {
580
539
  matrix: (matrixData: number[]) => {
581
540
  if (matrixData.length !== 6) {
@@ -589,11 +548,7 @@ export class Mat33 {
589
548
  const e = matrixData[4];
590
549
  const f = matrixData[5];
591
550
 
592
- const transform = new Mat33(
593
- a, c, e,
594
- b, d, f,
595
- 0, 0, 1
596
- );
551
+ const transform = new Mat33(a, c, e, b, d, f, 0, 0, 1);
597
552
  return transform;
598
553
  },
599
554
 
@@ -623,7 +578,9 @@ export class Mat33 {
623
578
  translateX = translateArgs[0];
624
579
  translateY = translateArgs[1];
625
580
  } else {
626
- throw new Error(`The translate() function requires either 1 or 2 arguments. Given ${translateArgs}`);
581
+ throw new Error(
582
+ `The translate() function requires either 1 or 2 arguments. Given ${translateArgs}`,
583
+ );
627
584
  }
628
585
 
629
586
  return Mat33.translation(Vec2.of(translateX, translateY));
@@ -632,9 +589,9 @@ export class Mat33 {
632
589
 
633
590
  // A command (\w+)
634
591
  // followed by a set of arguments ([ \t\n0-9eE.,\-%]+)
635
- const partRegex = /\s*(\w+)\s*\(([^)]*)\)/ig;
592
+ const partRegex = /\s*(\w+)\s*\(([^)]*)\)/gi;
636
593
  let match;
637
- let matrix: Mat33|null = null;
594
+ let matrix: Mat33 | null = null;
638
595
 
639
596
  while ((match = partRegex.exec(cssString)) !== null) {
640
597
  const action = match[1].toLowerCase();
package/src/Vec2.test.ts CHANGED
@@ -17,11 +17,11 @@ describe('Vec2', () => {
17
17
  });
18
18
 
19
19
  it('More complicated expressions', () => {
20
- expect((Vec2.of(1, 2).plus(Vec2.of(3, 4))).times(2)).objEq(Vec2.of(8, 12));
20
+ expect(Vec2.of(1, 2).plus(Vec2.of(3, 4)).times(2)).objEq(Vec2.of(8, 12));
21
21
  });
22
22
 
23
23
  it('Angle', () => {
24
- expect(Vec2.of(-1, 1).angle()).toBeCloseTo(3 * Math.PI / 4);
24
+ expect(Vec2.of(-1, 1).angle()).toBeCloseTo((3 * Math.PI) / 4);
25
25
  });
26
26
 
27
27
  it('Perpindicular', () => {
@@ -29,4 +29,4 @@ describe('Vec2', () => {
29
29
  expect(Vec2.unitX.cross(Vec3.unitZ)).objEq(Vec2.unitY.times(-1), tolerance);
30
30
  expect(Vec2.unitX.orthog()).objEq(Vec2.unitY, tolerance);
31
31
  });
32
- });
32
+ });
package/src/Vec3.test.ts CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  import Vec3 from './Vec3';
3
2
 
4
3
  describe('Vec3', () => {
@@ -60,7 +59,7 @@ describe('Vec3', () => {
60
59
  { from: Vec3.of(-1, -10, 0), to: Vec3.of(1, 2, 0), expected: 148 },
61
60
  ])(
62
61
  '.squareDistanceTo and .distanceTo should return correct square and euclidean distances (%j)',
63
- ({ from , to, expected }) => {
62
+ ({ from, to, expected }) => {
64
63
  expect(from.squareDistanceTo(to)).toBe(expected);
65
64
  expect(to.squareDistanceTo(from)).toBe(expected);
66
65
  expect(to.distanceTo(from)).toBeCloseTo(Math.sqrt(expected));
@@ -83,4 +82,4 @@ describe('Vec3', () => {
83
82
  expect(a.eq(b, tolerance)).toBe(eq);
84
83
  expect(b.eq(a, tolerance)).toBe(eq);
85
84
  });
86
- });
85
+ });
package/src/Vec3.ts CHANGED
@@ -1,5 +1,3 @@
1
-
2
-
3
1
  /**
4
2
  * A vector with three components, $\begin{pmatrix} x \\ y \\ z \end{pmatrix}$.
5
3
  * Can also be used to represent a two-component vector.
@@ -28,7 +26,7 @@ export interface Vec3 {
28
26
  * Returns the x, y components of this.
29
27
  * May be implemented as a getter method.
30
28
  */
31
- readonly xy: { x: number, y: number };
29
+ readonly xy: { x: number; y: number };
32
30
 
33
31
  /** Returns the vector's `idx`th component. For example, `Vec3.of(1, 2, 3).at(1) → 2`. */
34
32
  at(i: number): number;
@@ -124,7 +122,7 @@ export interface Vec3 {
124
122
  * Vec3.of(1, 2, 3).scale(Vec3.of(2, 4, 6)); // → Vec3(2, 8, 18)
125
123
  * ```
126
124
  */
127
- scale(other: Vec3|number): Vec3;
125
+ scale(other: Vec3 | number): Vec3;
128
126
 
129
127
  /**
130
128
  * Returns a vector orthogonal to this. If this is a Vec2, returns `this` rotated
@@ -154,9 +152,7 @@ export interface Vec3 {
154
152
  * console.log(zipped.toString()); // → Vec(0.5, 2, 2.9)
155
153
  * ```
156
154
  */
157
- zip(
158
- other: Vec3, zip: (componentInThis: number, componentInOther: number)=> number
159
- ): Vec3;
155
+ zip(other: Vec3, zip: (componentInThis: number, componentInOther: number) => number): Vec3;
160
156
 
161
157
  /**
162
158
  * Returns a vector with each component acted on by `fn`.
@@ -167,10 +163,9 @@ export interface Vec3 {
167
163
  * console.log(Vec3.of(1, 2, 3).map(val => val + 1)); // → Vec(2, 3, 4)
168
164
  * ```
169
165
  */
170
- map(fn: (component: number, index: number)=> number): Vec3;
171
-
172
- asArray(): [ number, number, number ];
166
+ map(fn: (component: number, index: number) => number): Vec3;
173
167
 
168
+ asArray(): [number, number, number];
174
169
 
175
170
  /**
176
171
  * [fuzz] The maximum difference between two components for this and [other]
@@ -196,9 +191,8 @@ class Vec3Impl implements Vec3 {
196
191
  public constructor(
197
192
  public readonly x: number,
198
193
  public readonly y: number,
199
- public readonly z: number
200
- ) {
201
- }
194
+ public readonly z: number,
195
+ ) {}
202
196
 
203
197
  public get xy(): { x: number; y: number } {
204
198
  // Useful for APIs that behave differently if .z is present.
@@ -288,16 +282,12 @@ class Vec3Impl implements Vec3 {
288
282
  );
289
283
  }
290
284
 
291
- public scale(other: Vec3|number): Vec3 {
285
+ public scale(other: Vec3 | number): Vec3 {
292
286
  if (typeof other === 'number') {
293
287
  return this.times(other);
294
288
  }
295
289
 
296
- return Vec3.of(
297
- this.x * other.x,
298
- this.y * other.y,
299
- this.z * other.z,
300
- );
290
+ return Vec3.of(this.x * other.x, this.y * other.y, this.z * other.z);
301
291
  }
302
292
 
303
293
  public orthog(): Vec3 {
@@ -318,28 +308,25 @@ class Vec3Impl implements Vec3 {
318
308
  }
319
309
 
320
310
  public zip(
321
- other: Vec3, zip: (componentInThis: number, componentInOther: number)=> number
311
+ other: Vec3,
312
+ zip: (componentInThis: number, componentInOther: number) => number,
322
313
  ): Vec3 {
323
- return Vec3.of(
324
- zip(other.x, this.x),
325
- zip(other.y, this.y),
326
- zip(other.z, this.z)
327
- );
314
+ return Vec3.of(zip(other.x, this.x), zip(other.y, this.y), zip(other.z, this.z));
328
315
  }
329
316
 
330
- public map(fn: (component: number, index: number)=> number): Vec3 {
317
+ public map(fn: (component: number, index: number) => number): Vec3 {
331
318
  return Vec3.of(fn(this.x, 0), fn(this.y, 1), fn(this.z, 2));
332
319
  }
333
320
 
334
- public asArray(): [ number, number, number ] {
321
+ public asArray(): [number, number, number] {
335
322
  return [this.x, this.y, this.z];
336
323
  }
337
324
 
338
325
  public eq(other: Vec3, fuzz: number = defaultEqlTolerance): boolean {
339
326
  return (
340
- Math.abs(other.x - this.x) <= fuzz
341
- && Math.abs(other.y - this.y) <= fuzz
342
- && Math.abs(other.z - this.z) <= fuzz
327
+ Math.abs(other.x - this.x) <= fuzz &&
328
+ Math.abs(other.y - this.y) <= fuzz &&
329
+ Math.abs(other.z - this.z) <= fuzz
343
330
  );
344
331
  }
345
332
 
@@ -352,10 +339,11 @@ class Vec2Impl implements Vec3 {
352
339
  public constructor(
353
340
  public readonly x: number,
354
341
  public readonly y: number,
355
- ) {
356
- }
342
+ ) {}
357
343
 
358
- public get z() { return 0; }
344
+ public get z() {
345
+ return 0;
346
+ }
359
347
 
360
348
  public get xy(): { x: number; y: number } {
361
349
  // Useful for APIs that behave differently if .z is present.
@@ -436,22 +424,15 @@ class Vec2Impl implements Vec3 {
436
424
  // | i j k |
437
425
  // | x1 y1 z1| = (i)(y1z2 - y2z1) - (j)(x1z2 - x2z1) + (k)(x1y2 - x2y1)
438
426
  // | x2 y2 z2|
439
- return Vec3.of(
440
- this.y * other.z,
441
- -this.x * other.z,
442
- this.x * other.y - other.x * this.y,
443
- );
427
+ return Vec3.of(this.y * other.z, -this.x * other.z, this.x * other.y - other.x * this.y);
444
428
  }
445
429
 
446
- public scale(other: Vec3|number): Vec3 {
430
+ public scale(other: Vec3 | number): Vec3 {
447
431
  if (typeof other === 'number') {
448
432
  return this.times(other);
449
433
  }
450
434
 
451
- return Vec2.of(
452
- this.x * other.x,
453
- this.y * other.y,
454
- );
435
+ return Vec2.of(this.x * other.x, this.y * other.y);
455
436
  }
456
437
 
457
438
  public orthog(): Vec3 {
@@ -472,30 +453,25 @@ class Vec2Impl implements Vec3 {
472
453
  }
473
454
 
474
455
  public zip(
475
- other: Vec3, zip: (componentInThis: number, componentInOther: number)=> number
456
+ other: Vec3,
457
+ zip: (componentInThis: number, componentInOther: number) => number,
476
458
  ): Vec3 {
477
- return Vec3.of(
478
- zip(other.x, this.x),
479
- zip(other.y, this.y),
480
- zip(other.z, 0),
481
- );
459
+ return Vec3.of(zip(other.x, this.x), zip(other.y, this.y), zip(other.z, 0));
482
460
  }
483
461
 
484
- public map(fn: (component: number, index: number)=> number): Vec3 {
485
- return Vec3.of(
486
- fn(this.x, 0), fn(this.y, 1), fn(0, 2)
487
- );
462
+ public map(fn: (component: number, index: number) => number): Vec3 {
463
+ return Vec3.of(fn(this.x, 0), fn(this.y, 1), fn(0, 2));
488
464
  }
489
465
 
490
- public asArray(): [ number, number, number ] {
466
+ public asArray(): [number, number, number] {
491
467
  return [this.x, this.y, 0];
492
468
  }
493
469
 
494
470
  public eq(other: Vec3, fuzz: number = defaultEqlTolerance): boolean {
495
471
  return (
496
- Math.abs(other.x - this.x) <= fuzz
497
- && Math.abs(other.y - this.y) <= fuzz
498
- && Math.abs(other.z) <= fuzz
472
+ Math.abs(other.x - this.x) <= fuzz &&
473
+ Math.abs(other.y - this.y) <= fuzz &&
474
+ Math.abs(other.z) <= fuzz
499
475
  );
500
476
  }
501
477
 
@@ -537,7 +513,7 @@ export namespace Vec2 {
537
513
  * const v2 = Vec2.ofXY({ x: -123.4, y: 1 });
538
514
  * ```
539
515
  */
540
- export const ofXY = ({x, y}: {x: number, y: number}) => {
516
+ export const ofXY = ({ x, y }: { x: number; y: number }) => {
541
517
  return Vec2.of(x, y);
542
518
  };
543
519
 
package/src/lib.ts CHANGED
@@ -20,7 +20,6 @@
20
20
  export { LineSegment2 } from './shapes/LineSegment2';
21
21
  export {
22
22
  Path,
23
-
24
23
  IntersectionResult as PathIntersectionResult,
25
24
  CurveIndexRecord as PathCurveIndex,
26
25
  stepCurveIndexBy as stepPathIndexBy,
@@ -43,6 +42,5 @@ export { Vec3 } from './Vec3';
43
42
  export { Color4 } from './Color4';
44
43
  export * from './rounding/lib';
45
44
 
46
-
47
45
  // Note: All above exports cannot use `export { default as ... } from "..."` because this
48
46
  // breaks TypeDoc -- TypeDoc otherwise labels any imports of these classes as `default`.
@@ -1,9 +1,8 @@
1
-
2
1
  import solveQuadratic from './solveQuadratic';
3
2
 
4
3
  describe('solveQuadratic', () => {
5
4
  it('should solve linear equations', () => {
6
- expect(solveQuadratic(0, 1, 2)).toMatchObject([ -2, -2 ]);
5
+ expect(solveQuadratic(0, 1, 2)).toMatchObject([-2, -2]);
7
6
  expect(solveQuadratic(0, 0, 2)[0]).toBeNaN();
8
7
  });
9
8
 
@@ -11,21 +10,48 @@ describe('solveQuadratic', () => {
11
10
  type TestCase = [[number, number, number], [number, number]];
12
11
 
13
12
  const testCases: TestCase[] = [
14
- [ [ 1, 0, 0 ], [ 0, 0 ] ],
15
- [ [ 2, 0, 0 ], [ 0, 0 ] ],
13
+ [
14
+ [1, 0, 0],
15
+ [0, 0],
16
+ ],
17
+ [
18
+ [2, 0, 0],
19
+ [0, 0],
20
+ ],
16
21
 
17
- [ [ 1, 0, -1 ], [ 1, -1 ] ],
18
- [ [ 1, 0, -4 ], [ 2, -2 ] ],
19
- [ [ 1, 0, 4 ], [ NaN, NaN ] ],
22
+ [
23
+ [1, 0, -1],
24
+ [1, -1],
25
+ ],
26
+ [
27
+ [1, 0, -4],
28
+ [2, -2],
29
+ ],
30
+ [
31
+ [1, 0, 4],
32
+ [NaN, NaN],
33
+ ],
20
34
 
21
- [ [ 1, 1, 0 ], [ 0, -1 ] ],
22
- [ [ 1, 2, 0 ], [ 0, -2 ] ],
35
+ [
36
+ [1, 1, 0],
37
+ [0, -1],
38
+ ],
39
+ [
40
+ [1, 2, 0],
41
+ [0, -2],
42
+ ],
23
43
 
24
- [ [ 1, 2, 1 ], [ -1, -1 ] ],
25
- [ [ -9, 2, 1/3 ], [ 1/3, -1/9 ] ],
44
+ [
45
+ [1, 2, 1],
46
+ [-1, -1],
47
+ ],
48
+ [
49
+ [-9, 2, 1 / 3],
50
+ [1 / 3, -1 / 9],
51
+ ],
26
52
  ];
27
53
 
28
- for (const [ testCase, solution ] of testCases) {
54
+ for (const [testCase, solution] of testCases) {
29
55
  const foundSolutions = solveQuadratic(...testCase);
30
56
  for (let i = 0; i < 2; i++) {
31
57
  if (isNaN(solution[i]) && isNaN(foundSolutions[i])) {
@@ -36,4 +62,4 @@ describe('solveQuadratic', () => {
36
62
  }
37
63
  }
38
64
  });
39
- });
65
+ });
@@ -1,4 +1,3 @@
1
-
2
1
  /**
3
2
  * Solves an equation of the form ax² + bx + c = 0.
4
3
  * The larger solution is returned first.
@@ -21,13 +20,13 @@ const solveQuadratic = (a: number, b: number, c: number): [number, number] => {
21
20
  solution = -c / b;
22
21
  }
23
22
 
24
- return [ solution, solution ];
23
+ return [solution, solution];
25
24
  }
26
25
 
27
26
  const discriminant = b * b - 4 * a * c;
28
27
 
29
28
  if (discriminant < 0) {
30
- return [ NaN, NaN ];
29
+ return [NaN, NaN];
31
30
  }
32
31
 
33
32
  const rootDiscriminant = Math.sqrt(discriminant);
@@ -35,9 +34,9 @@ const solveQuadratic = (a: number, b: number, c: number): [number, number] => {
35
34
  const solution2 = (-b - rootDiscriminant) / (2 * a);
36
35
 
37
36
  if (solution1 > solution2) {
38
- return [ solution1, solution2 ];
37
+ return [solution1, solution2];
39
38
  } else {
40
- return [ solution2, solution1 ];
39
+ return [solution2, solution1];
41
40
  }
42
41
  };
43
- export default solveQuadratic;
42
+ export default solveQuadratic;
@@ -12,4 +12,4 @@ it('cleanUpNumber', () => {
12
12
  expect(cleanUpNumber('1234.5')).toBe('1234.5');
13
13
  expect(cleanUpNumber('1234.500')).toBe('1234.5');
14
14
  expect(cleanUpNumber('1.1368683772161603e-13')).toBe('0');
15
- });
15
+ });