@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/src/Mat33.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import { Point2, Vec2 } from './Vec2';
2
2
  import Vec3 from './Vec3';
3
3
 
4
+ /**
5
+ * See {@link Mat33.toArray}.
6
+ */
4
7
  export type Mat33Array = [
5
8
  number, number, number,
6
9
  number, number, number,
@@ -11,6 +14,46 @@ export type Mat33Array = [
11
14
  * Represents a three dimensional linear transformation or
12
15
  * a two-dimensional affine transformation. (An affine transformation scales/rotates/shears
13
16
  * **and** translates while a linear transformation just scales/rotates/shears).
17
+ *
18
+ * In addition to other matrices, {@link Mat33}s can be used to transform {@link Vec3}s and {@link Vec2}s.
19
+ *
20
+ * For example, to move the point $(1, 1)$ by 5 units to the left and 6 units up,
21
+ * ```ts,runnable,console
22
+ * import {Mat33, Vec2} from '@js-draw/math';
23
+ *
24
+ * const moveLeftAndUp = Mat33.translation(Vec2.of(5, 6));
25
+ * console.log(moveLeftAndUp);
26
+ * ```
27
+ *
28
+ * This `moveLeftAndUp` matrix could then translate (move) a {@link Vec2} using
29
+ * {@link Mat33.transformVec2}:
30
+ *
31
+ * ```ts,runnable,console
32
+ * ---use-previous---
33
+ * ---visible---
34
+ * console.log(moveLeftAndUp.transformVec2(Vec2.of(1, 1)));
35
+ * console.log(moveLeftAndUp.transformVec2(Vec2.of(-1, 2)));
36
+ * ```
37
+ *
38
+ * It's also possible to create transformation matrices that scale and rotate.
39
+ * A single transform matrix can be created from multiple using matrix multiplication
40
+ * (see {@link Mat33.rightMul}):
41
+ *
42
+ * ```ts,runnable,console
43
+ * ---use-previous---
44
+ * ---visible---
45
+ * // Create a matrix by right multiplying.
46
+ * const scaleThenRotate =
47
+ * // The resultant matrix first scales by a factor of two
48
+ * Mat33.scaling2D(2).rightMul(
49
+ * // ...then rotates by pi/2 radians = 90 degrees.
50
+ * Mat33.zRotation(Math.PI / 2)
51
+ * );
52
+ * console.log(scaleThenRotate);
53
+ *
54
+ * // Use scaleThenRotate to scale then rotate a vector.
55
+ * console.log(scaleThenRotate.transformVec2(Vec2.unitX));
56
+ * ```
14
57
  */
15
58
  export class Mat33 {
16
59
  private readonly rows: Vec3[];
@@ -24,6 +67,9 @@ export class Mat33 {
24
67
  * c1 & c2 & c3
25
68
  * \end{bmatrix}
26
69
  * $$
70
+ *
71
+ * Static constructor methods are also available.
72
+ * See {@link Mat33.scaling2D}, {@link Mat33.zRotation}, {@link Mat33.translation}, and {@link Mat33.fromCSSMatrix}.
27
73
  */
28
74
  public constructor(
29
75
  public readonly a1: number,
@@ -63,6 +109,7 @@ export class Mat33 {
63
109
  );
64
110
  }
65
111
 
112
+ /** The 3x3 [identity matrix](https://en.wikipedia.org/wiki/Identity_matrix). */
66
113
  public static identity = new Mat33(
67
114
  1, 0, 0,
68
115
  0, 1, 0,
@@ -178,6 +225,29 @@ export class Mat33 {
178
225
  );
179
226
  }
180
227
 
228
+ /**
229
+ * [Right-multiplies](https://en.wikipedia.org/wiki/Matrix_multiplication) this by `other`.
230
+ *
231
+ * See also {@link transformVec3} and {@link transformVec2}.
232
+ *
233
+ * Example:
234
+ * ```ts,runnable,console
235
+ * import {Mat33, Vec2} from '@js-draw/math';
236
+ * console.log(Mat33.identity.rightMul(Mat33.identity));
237
+ *
238
+ * // Create a matrix by right multiplying.
239
+ * const scaleThenRotate =
240
+ * // The resultant matrix first scales by a factor of two
241
+ * Mat33.scaling2D(2).rightMul(
242
+ * // ...then rotates by pi/4 radians = 45 degrees.
243
+ * Mat33.zRotation(Math.PI / 4)
244
+ * );
245
+ * console.log(scaleThenRotate);
246
+ *
247
+ * // Use scaleThenRotate to scale then rotate a vector.
248
+ * console.log(scaleThenRotate.transformVec2(Vec2.unitX));
249
+ * ```
250
+ */
181
251
  public rightMul(other: Mat33): Mat33 {
182
252
  other = other.transposed();
183
253
 
@@ -245,6 +315,15 @@ export class Mat33 {
245
315
  return true;
246
316
  }
247
317
 
318
+ /**
319
+ * Creates a human-readable representation of the matrix.
320
+ *
321
+ * Example:
322
+ * ```ts,runnable,console
323
+ * import { Mat33 } from '@js-draw/math';
324
+ * console.log(Mat33.identity.toString());
325
+ * ```
326
+ */
248
327
  public toString(): string {
249
328
  let result = '';
250
329
  const maxColumnLens = [ 0, 0, 0 ];
@@ -297,6 +376,18 @@ export class Mat33 {
297
376
  * result[1] = element at row zero, column 1
298
377
  * ...
299
378
  * ```
379
+ *
380
+ * Example:
381
+ * ```ts,runnable,console
382
+ * import { Mat33 } from '@js-draw/math';
383
+ * console.log(
384
+ * new Mat33(
385
+ * 1, 2, 3,
386
+ * 4, 5, 6,
387
+ * 7, 8, 9,
388
+ * )
389
+ * );
390
+ * ```
300
391
  */
301
392
  public toArray(): Mat33Array {
302
393
  return [
@@ -481,7 +572,7 @@ export class Mat33 {
481
572
 
482
573
  return argNumber;
483
574
  });
484
- return parsed.filter(n => n !== null) as number[];
575
+ return parsed.filter(n => n !== null);
485
576
  };
486
577
 
487
578
 
package/src/Vec2.test.ts CHANGED
@@ -8,10 +8,12 @@ describe('Vec2', () => {
8
8
 
9
9
  it('Addition', () => {
10
10
  expect(Vec2.of(1, 2).plus(Vec2.of(3, 4))).objEq(Vec2.of(4, 6));
11
+ expect(Vec2.of(1, 2).plus(Vec3.of(3, 4, 1))).objEq(Vec3.of(4, 6, 1));
11
12
  });
12
13
 
13
14
  it('Multiplication', () => {
14
15
  expect(Vec2.of(1, -1).times(22)).objEq(Vec2.of(22, -22));
16
+ expect(Vec2.of(1, -1).scale(Vec3.of(-1, 2, 3))).objEq(Vec2.of(-1, -2));
15
17
  });
16
18
 
17
19
  it('More complicated expressions', () => {
@@ -23,8 +25,8 @@ describe('Vec2', () => {
23
25
  });
24
26
 
25
27
  it('Perpindicular', () => {
26
- const fuzz = 0.001;
27
- expect(Vec2.unitX.cross(Vec3.unitZ)).objEq(Vec2.unitY.times(-1), fuzz);
28
- expect(Vec2.unitX.orthog()).objEq(Vec2.unitY, fuzz);
28
+ const tolerance = 0.001;
29
+ expect(Vec2.unitX.cross(Vec3.unitZ)).objEq(Vec2.unitY.times(-1), tolerance);
30
+ expect(Vec2.unitX.orthog()).objEq(Vec2.unitY, tolerance);
29
31
  });
30
32
  });
package/src/Vec2.ts CHANGED
@@ -1,49 +1,9 @@
1
- import Vec3 from './Vec3';
2
-
3
- /**
4
- * Utility functions that facilitate treating `Vec3`s as 2D vectors.
5
- *
6
- * @example
7
- * ```ts,runnable,console
8
- * import { Vec2 } from '@js-draw/math';
9
- * console.log(Vec2.of(1, 2));
10
- * ```
11
- */
12
- export namespace Vec2 {
13
- /**
14
- * Creates a `Vec2` from an x and y coordinate.
15
- *
16
- * For example,
17
- * ```ts
18
- * const v = Vec2.of(3, 4); // x=3, y=4.
19
- * ```
20
- */
21
- export const of = (x: number, y: number): Vec2 => {
22
- return Vec3.of(x, y, 0);
23
- };
24
-
25
- /**
26
- * Creates a `Vec2` from an object containing x and y coordinates.
27
- *
28
- * For example,
29
- * ```ts
30
- * const v1 = Vec2.ofXY({ x: 3, y: 4.5 });
31
- * const v2 = Vec2.ofXY({ x: -123.4, y: 1 });
32
- * ```
33
- */
34
- export const ofXY = ({x, y}: { x: number, y: number }): Vec2 => {
35
- return Vec3.of(x, y, 0);
36
- };
37
-
38
- /** A vector of length 1 in the X direction (→). */
39
- export const unitX = Vec2.of(1, 0);
40
-
41
- /** A vector of length 1 in the Y direction (↑). */
42
- export const unitY = Vec2.of(0, 1);
43
-
44
- /** The zero vector: A vector with x=0, y=0. */
45
- export const zero = Vec2.of(0, 0);
46
- }
1
+ // Internally, we define Vec2 as a namespace within Vec3 --
2
+ // this allows referencing Vec2s from Vec3 constructors without
3
+ // cyclic references.
4
+ import { Vec3, Vec2 } from './Vec3';
47
5
 
48
6
  export type Point2 = Vec3;
49
- export type Vec2 = Vec3; // eslint-disable-line
7
+ export type Vec2 = Vec3;
8
+ export { Vec3, Vec2 };
9
+ export default Vec2;