@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.
@@ -1,5 +1,8 @@
1
1
  import { Point2, Vec2 } from './Vec2';
2
2
  import Vec3 from './Vec3';
3
+ /**
4
+ * See {@link Mat33.toArray}.
5
+ */
3
6
  export type Mat33Array = [
4
7
  number,
5
8
  number,
@@ -15,6 +18,46 @@ export type Mat33Array = [
15
18
  * Represents a three dimensional linear transformation or
16
19
  * a two-dimensional affine transformation. (An affine transformation scales/rotates/shears
17
20
  * **and** translates while a linear transformation just scales/rotates/shears).
21
+ *
22
+ * In addition to other matrices, {@link Mat33}s can be used to transform {@link Vec3}s and {@link Vec2}s.
23
+ *
24
+ * For example, to move the point $(1, 1)$ by 5 units to the left and 6 units up,
25
+ * ```ts,runnable,console
26
+ * import {Mat33, Vec2} from '@js-draw/math';
27
+ *
28
+ * const moveLeftAndUp = Mat33.translation(Vec2.of(5, 6));
29
+ * console.log(moveLeftAndUp);
30
+ * ```
31
+ *
32
+ * This `moveLeftAndUp` matrix could then translate (move) a {@link Vec2} using
33
+ * {@link Mat33.transformVec2}:
34
+ *
35
+ * ```ts,runnable,console
36
+ * ---use-previous---
37
+ * ---visible---
38
+ * console.log(moveLeftAndUp.transformVec2(Vec2.of(1, 1)));
39
+ * console.log(moveLeftAndUp.transformVec2(Vec2.of(-1, 2)));
40
+ * ```
41
+ *
42
+ * It's also possible to create transformation matrices that scale and rotate.
43
+ * A single transform matrix can be created from multiple using matrix multiplication
44
+ * (see {@link Mat33.rightMul}):
45
+ *
46
+ * ```ts,runnable,console
47
+ * ---use-previous---
48
+ * ---visible---
49
+ * // Create a matrix by right multiplying.
50
+ * const scaleThenRotate =
51
+ * // The resultant matrix first scales by a factor of two
52
+ * Mat33.scaling2D(2).rightMul(
53
+ * // ...then rotates by pi/2 radians = 90 degrees.
54
+ * Mat33.zRotation(Math.PI / 2)
55
+ * );
56
+ * console.log(scaleThenRotate);
57
+ *
58
+ * // Use scaleThenRotate to scale then rotate a vector.
59
+ * console.log(scaleThenRotate.transformVec2(Vec2.unitX));
60
+ * ```
18
61
  */
19
62
  export declare class Mat33 {
20
63
  readonly a1: number;
@@ -36,6 +79,9 @@ export declare class Mat33 {
36
79
  * c1 & c2 & c3
37
80
  * \end{bmatrix}
38
81
  * $$
82
+ *
83
+ * Static constructor methods are also available.
84
+ * See {@link Mat33.scaling2D}, {@link Mat33.zRotation}, {@link Mat33.translation}, and {@link Mat33.fromCSSMatrix}.
39
85
  */
40
86
  constructor(a1: number, a2: number, a3: number, b1: number, b2: number, b3: number, c1: number, c2: number, c3: number);
41
87
  /**
@@ -49,6 +95,7 @@ export declare class Mat33 {
49
95
  * $$
50
96
  */
51
97
  static ofRows(r1: Vec3, r2: Vec3, r3: Vec3): Mat33;
98
+ /** The 3x3 [identity matrix](https://en.wikipedia.org/wiki/Identity_matrix). */
52
99
  static identity: Mat33;
53
100
  /**
54
101
  * Either returns the inverse of this, or, if this matrix is singular/uninvertable,
@@ -62,6 +109,29 @@ export declare class Mat33 {
62
109
  private cachedInverse;
63
110
  private computeInverse;
64
111
  transposed(): Mat33;
112
+ /**
113
+ * [Right-multiplies](https://en.wikipedia.org/wiki/Matrix_multiplication) this by `other`.
114
+ *
115
+ * See also {@link transformVec3} and {@link transformVec2}.
116
+ *
117
+ * Example:
118
+ * ```ts,runnable,console
119
+ * import {Mat33, Vec2} from '@js-draw/math';
120
+ * console.log(Mat33.identity.rightMul(Mat33.identity));
121
+ *
122
+ * // Create a matrix by right multiplying.
123
+ * const scaleThenRotate =
124
+ * // The resultant matrix first scales by a factor of two
125
+ * Mat33.scaling2D(2).rightMul(
126
+ * // ...then rotates by pi/4 radians = 45 degrees.
127
+ * Mat33.zRotation(Math.PI / 4)
128
+ * );
129
+ * console.log(scaleThenRotate);
130
+ *
131
+ * // Use scaleThenRotate to scale then rotate a vector.
132
+ * console.log(scaleThenRotate.transformVec2(Vec2.unitX));
133
+ * ```
134
+ */
65
135
  rightMul(other: Mat33): Mat33;
66
136
  /**
67
137
  * Applies this as an **affine** transformation to the given vector.
@@ -79,6 +149,15 @@ export declare class Mat33 {
79
149
  isIdentity(): boolean;
80
150
  /** Returns true iff this = other ± fuzz */
81
151
  eq(other: Mat33, fuzz?: number): boolean;
152
+ /**
153
+ * Creates a human-readable representation of the matrix.
154
+ *
155
+ * Example:
156
+ * ```ts,runnable,console
157
+ * import { Mat33 } from '@js-draw/math';
158
+ * console.log(Mat33.identity.toString());
159
+ * ```
160
+ */
82
161
  toString(): string;
83
162
  /**
84
163
  * ```
@@ -86,6 +165,18 @@ export declare class Mat33 {
86
165
  * result[1] = element at row zero, column 1
87
166
  * ...
88
167
  * ```
168
+ *
169
+ * Example:
170
+ * ```ts,runnable,console
171
+ * import { Mat33 } from '@js-draw/math';
172
+ * console.log(
173
+ * new Mat33(
174
+ * 1, 2, 3,
175
+ * 4, 5, 6,
176
+ * 7, 8, 9,
177
+ * )
178
+ * );
179
+ * ```
89
180
  */
90
181
  toArray(): Mat33Array;
91
182
  /**
@@ -4,6 +4,46 @@ import Vec3 from './Vec3.mjs';
4
4
  * Represents a three dimensional linear transformation or
5
5
  * a two-dimensional affine transformation. (An affine transformation scales/rotates/shears
6
6
  * **and** translates while a linear transformation just scales/rotates/shears).
7
+ *
8
+ * In addition to other matrices, {@link Mat33}s can be used to transform {@link Vec3}s and {@link Vec2}s.
9
+ *
10
+ * For example, to move the point $(1, 1)$ by 5 units to the left and 6 units up,
11
+ * ```ts,runnable,console
12
+ * import {Mat33, Vec2} from '@js-draw/math';
13
+ *
14
+ * const moveLeftAndUp = Mat33.translation(Vec2.of(5, 6));
15
+ * console.log(moveLeftAndUp);
16
+ * ```
17
+ *
18
+ * This `moveLeftAndUp` matrix could then translate (move) a {@link Vec2} using
19
+ * {@link Mat33.transformVec2}:
20
+ *
21
+ * ```ts,runnable,console
22
+ * ---use-previous---
23
+ * ---visible---
24
+ * console.log(moveLeftAndUp.transformVec2(Vec2.of(1, 1)));
25
+ * console.log(moveLeftAndUp.transformVec2(Vec2.of(-1, 2)));
26
+ * ```
27
+ *
28
+ * It's also possible to create transformation matrices that scale and rotate.
29
+ * A single transform matrix can be created from multiple using matrix multiplication
30
+ * (see {@link Mat33.rightMul}):
31
+ *
32
+ * ```ts,runnable,console
33
+ * ---use-previous---
34
+ * ---visible---
35
+ * // Create a matrix by right multiplying.
36
+ * const scaleThenRotate =
37
+ * // The resultant matrix first scales by a factor of two
38
+ * Mat33.scaling2D(2).rightMul(
39
+ * // ...then rotates by pi/2 radians = 90 degrees.
40
+ * Mat33.zRotation(Math.PI / 2)
41
+ * );
42
+ * console.log(scaleThenRotate);
43
+ *
44
+ * // Use scaleThenRotate to scale then rotate a vector.
45
+ * console.log(scaleThenRotate.transformVec2(Vec2.unitX));
46
+ * ```
7
47
  */
8
48
  export class Mat33 {
9
49
  /**
@@ -15,6 +55,9 @@ export class Mat33 {
15
55
  * c1 & c2 & c3
16
56
  * \end{bmatrix}
17
57
  * $$
58
+ *
59
+ * Static constructor methods are also available.
60
+ * See {@link Mat33.scaling2D}, {@link Mat33.zRotation}, {@link Mat33.translation}, and {@link Mat33.fromCSSMatrix}.
18
61
  */
19
62
  constructor(a1, a2, a3, b1, b2, b3, c1, c2, c3) {
20
63
  this.a1 = a1;
@@ -125,6 +168,29 @@ export class Mat33 {
125
168
  transposed() {
126
169
  return new Mat33(this.a1, this.b1, this.c1, this.a2, this.b2, this.c2, this.a3, this.b3, this.c3);
127
170
  }
171
+ /**
172
+ * [Right-multiplies](https://en.wikipedia.org/wiki/Matrix_multiplication) this by `other`.
173
+ *
174
+ * See also {@link transformVec3} and {@link transformVec2}.
175
+ *
176
+ * Example:
177
+ * ```ts,runnable,console
178
+ * import {Mat33, Vec2} from '@js-draw/math';
179
+ * console.log(Mat33.identity.rightMul(Mat33.identity));
180
+ *
181
+ * // Create a matrix by right multiplying.
182
+ * const scaleThenRotate =
183
+ * // The resultant matrix first scales by a factor of two
184
+ * Mat33.scaling2D(2).rightMul(
185
+ * // ...then rotates by pi/4 radians = 45 degrees.
186
+ * Mat33.zRotation(Math.PI / 4)
187
+ * );
188
+ * console.log(scaleThenRotate);
189
+ *
190
+ * // Use scaleThenRotate to scale then rotate a vector.
191
+ * console.log(scaleThenRotate.transformVec2(Vec2.unitX));
192
+ * ```
193
+ */
128
194
  rightMul(other) {
129
195
  other = other.transposed();
130
196
  const at = (row, col) => {
@@ -174,6 +240,15 @@ export class Mat33 {
174
240
  }
175
241
  return true;
176
242
  }
243
+ /**
244
+ * Creates a human-readable representation of the matrix.
245
+ *
246
+ * Example:
247
+ * ```ts,runnable,console
248
+ * import { Mat33 } from '@js-draw/math';
249
+ * console.log(Mat33.identity.toString());
250
+ * ```
251
+ */
177
252
  toString() {
178
253
  let result = '';
179
254
  const maxColumnLens = [0, 0, 0];
@@ -222,6 +297,18 @@ export class Mat33 {
222
297
  * result[1] = element at row zero, column 1
223
298
  * ...
224
299
  * ```
300
+ *
301
+ * Example:
302
+ * ```ts,runnable,console
303
+ * import { Mat33 } from '@js-draw/math';
304
+ * console.log(
305
+ * new Mat33(
306
+ * 1, 2, 3,
307
+ * 4, 5, 6,
308
+ * 7, 8, 9,
309
+ * )
310
+ * );
311
+ * ```
225
312
  */
226
313
  toArray() {
227
314
  return [
@@ -429,5 +516,6 @@ export class Mat33 {
429
516
  return matrix ?? Mat33.identity;
430
517
  }
431
518
  }
519
+ /** The 3x3 [identity matrix](https://en.wikipedia.org/wiki/Identity_matrix). */
432
520
  Mat33.identity = new Mat33(1, 0, 0, 0, 1, 0, 0, 0, 1);
433
521
  export default Mat33;
@@ -1,42 +1,5 @@
1
- import Vec3 from './Vec3';
2
- /**
3
- * Utility functions that facilitate treating `Vec3`s as 2D vectors.
4
- *
5
- * @example
6
- * ```ts,runnable,console
7
- * import { Vec2 } from '@js-draw/math';
8
- * console.log(Vec2.of(1, 2));
9
- * ```
10
- */
11
- export declare namespace Vec2 {
12
- /**
13
- * Creates a `Vec2` from an x and y coordinate.
14
- *
15
- * For example,
16
- * ```ts
17
- * const v = Vec2.of(3, 4); // x=3, y=4.
18
- * ```
19
- */
20
- const of: (x: number, y: number) => Vec2;
21
- /**
22
- * Creates a `Vec2` from an object containing x and y coordinates.
23
- *
24
- * For example,
25
- * ```ts
26
- * const v1 = Vec2.ofXY({ x: 3, y: 4.5 });
27
- * const v2 = Vec2.ofXY({ x: -123.4, y: 1 });
28
- * ```
29
- */
30
- const ofXY: ({ x, y }: {
31
- x: number;
32
- y: number;
33
- }) => Vec2;
34
- /** A vector of length 1 in the X direction (→). */
35
- const unitX: Vec3;
36
- /** A vector of length 1 in the Y direction (↑). */
37
- const unitY: Vec3;
38
- /** The zero vector: A vector with x=0, y=0. */
39
- const zero: Vec3;
40
- }
1
+ import { Vec3, Vec2 } from './Vec3';
41
2
  export type Point2 = Vec3;
42
3
  export type Vec2 = Vec3;
4
+ export { Vec3, Vec2 };
5
+ export default Vec2;
package/dist/mjs/Vec2.mjs CHANGED
@@ -1,42 +1,6 @@
1
- import Vec3 from './Vec3.mjs';
2
- /**
3
- * Utility functions that facilitate treating `Vec3`s as 2D vectors.
4
- *
5
- * @example
6
- * ```ts,runnable,console
7
- * import { Vec2 } from '@js-draw/math';
8
- * console.log(Vec2.of(1, 2));
9
- * ```
10
- */
11
- export var Vec2;
12
- (function (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
- Vec2.of = (x, y) => {
22
- return Vec3.of(x, y, 0);
23
- };
24
- /**
25
- * Creates a `Vec2` from an object containing x and y coordinates.
26
- *
27
- * For example,
28
- * ```ts
29
- * const v1 = Vec2.ofXY({ x: 3, y: 4.5 });
30
- * const v2 = Vec2.ofXY({ x: -123.4, y: 1 });
31
- * ```
32
- */
33
- Vec2.ofXY = ({ x, y }) => {
34
- return Vec3.of(x, y, 0);
35
- };
36
- /** A vector of length 1 in the X direction (→). */
37
- Vec2.unitX = Vec2.of(1, 0);
38
- /** A vector of length 1 in the Y direction (↑). */
39
- Vec2.unitY = Vec2.of(0, 1);
40
- /** The zero vector: A vector with x=0, y=0. */
41
- Vec2.zero = Vec2.of(0, 0);
42
- })(Vec2 || (Vec2 = {}));
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.mjs';
5
+ export { Vec3, Vec2 };
6
+ export default Vec2;
@@ -17,22 +17,23 @@
17
17
  * console.log('As an array:', Vec3.unitZ.asArray());
18
18
  * ```
19
19
  */
20
- export declare class Vec3 {
20
+ export interface Vec3 {
21
21
  readonly x: number;
22
22
  readonly y: number;
23
23
  readonly z: number;
24
- private constructor();
25
- /** Returns the x, y components of this. */
26
- get xy(): {
24
+ /**
25
+ * Returns the x, y components of this.
26
+ * May be implemented as a getter method.
27
+ */
28
+ readonly xy: {
27
29
  x: number;
28
30
  y: number;
29
31
  };
30
- /** Construct a vector from three components. */
31
- static of(x: number, y: number, z: number): Vec3;
32
- /** Returns this' `idx`th component. For example, `Vec3.of(1, 2, 3).at(1) → 2`. */
33
- at(idx: number): number;
34
- /** Alias for this.magnitude. */
32
+ /** Returns the vector's `idx`th component. For example, `Vec3.of(1, 2, 3).at(1) → 2`. */
33
+ at(i: number): number;
34
+ /** Alias for `.magnitude`. */
35
35
  length(): number;
36
+ /** Returns the length of this vector in ℝ^3. */
36
37
  magnitude(): number;
37
38
  magnitudeSquared(): number;
38
39
  /**
@@ -41,7 +42,7 @@ export declare class Vec3 {
41
42
  *
42
43
  * Equivalent to `.minus(p).magnitudeSquared()`.
43
44
  */
44
- squareDistanceTo(p: Vec3): number;
45
+ squareDistanceTo(other: Vec3): number;
45
46
  /**
46
47
  * Interpreting this vector as a point in ℝ³, returns the distance to the point
47
48
  * `p`.
@@ -90,10 +91,17 @@ export declare class Vec3 {
90
91
  normalizedOrZero(): Vec3;
91
92
  /** @returns A copy of `this` multiplied by a scalar. */
92
93
  times(c: number): Vec3;
94
+ /** Performs vector addition. */
93
95
  plus(v: Vec3): Vec3;
94
96
  minus(v: Vec3): Vec3;
95
- dot(other: Vec3): number;
96
- cross(other: Vec3): Vec3;
97
+ /**
98
+ * Computes the scalar product between this and `v`.
99
+ *
100
+ * In particular, `a.dot(b)` is equivalent to `a.x * b.x + a.y * b.y + a.z * b.z`.
101
+ */
102
+ dot(v: Vec3): number;
103
+ /** Computes the cross product between this and `v` */
104
+ cross(v: Vec3): Vec3;
97
105
  /**
98
106
  * If `other` is a `Vec3`, multiplies `this` component-wise by `other`. Otherwise,
99
107
  * if `other is a `number`, returns the result of scalar multiplication.
@@ -154,11 +162,99 @@ export declare class Vec3 {
154
162
  * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 2.99); // → false
155
163
  * ```
156
164
  */
165
+ eq(other: Vec3, tolerance?: number): boolean;
166
+ toString(): string;
167
+ }
168
+ declare class Vec2Impl implements Vec3 {
169
+ readonly x: number;
170
+ readonly y: number;
171
+ constructor(x: number, y: number);
172
+ get z(): number;
173
+ get xy(): {
174
+ x: number;
175
+ y: number;
176
+ };
177
+ at(idx: number): number;
178
+ length(): number;
179
+ magnitude(): number;
180
+ magnitudeSquared(): number;
181
+ squareDistanceTo(p: Vec3): number;
182
+ distanceTo(p: Vec3): number;
183
+ maximumEntryMagnitude(): number;
184
+ angle(): number;
185
+ normalized(): Vec3;
186
+ normalizedOrZero(): Vec3;
187
+ times(c: number): Vec3;
188
+ plus(v: Vec3): Vec3;
189
+ minus(v: Vec3): Vec3;
190
+ dot(other: Vec3): number;
191
+ cross(other: Vec3): Vec3;
192
+ scale(other: Vec3 | number): Vec3;
193
+ orthog(): Vec3;
194
+ extend(distance: number, direction: Vec3): Vec3;
195
+ lerp(target: Vec3, fractionTo: number): Vec3;
196
+ zip(other: Vec3, zip: (componentInThis: number, componentInOther: number) => number): Vec3;
197
+ map(fn: (component: number, index: number) => number): Vec3;
198
+ asArray(): [number, number, number];
157
199
  eq(other: Vec3, fuzz?: number): boolean;
158
200
  toString(): string;
159
- static unitX: Vec3;
160
- static unitY: Vec3;
161
- static unitZ: Vec3;
162
- static zero: Vec3;
201
+ }
202
+ /**
203
+ * A `Vec2` is a `Vec3` optimized for working in a plane. As such, they have an
204
+ * always-zero `z` component.
205
+ *
206
+ * ```ts,runnable,console
207
+ * import { Vec2 } from '@js-draw/math';
208
+ * console.log(Vec2.of(1, 2));
209
+ * ```
210
+ */
211
+ export declare namespace Vec2 {
212
+ /**
213
+ * Creates a `Vec2` from an x and y coordinate.
214
+ *
215
+ * @example
216
+ * ```ts,runnable,console
217
+ * import { Vec2 } from '@js-draw/math';
218
+ * const v = Vec2.of(3, 4); // x=3, y=4.
219
+ * ```
220
+ */
221
+ const of: (x: number, y: number) => Vec2Impl;
222
+ /**
223
+ * Creates a `Vec2` from an object containing `x` and `y` coordinates.
224
+ *
225
+ * @example
226
+ * ```ts,runnable,console
227
+ * import { Vec2 } from '@js-draw/math';
228
+ * const v1 = Vec2.ofXY({ x: 3, y: 4.5 });
229
+ * const v2 = Vec2.ofXY({ x: -123.4, y: 1 });
230
+ * ```
231
+ */
232
+ const ofXY: ({ x, y }: {
233
+ x: number;
234
+ y: number;
235
+ }) => Vec2Impl;
236
+ /** A vector of length 1 in the X direction (→). */
237
+ const unitX: Vec2Impl;
238
+ /** A vector of length 1 in the Y direction (↑). */
239
+ const unitY: Vec2Impl;
240
+ /** The zero vector: A vector with x=0, y=0. */
241
+ const zero: Vec2Impl;
242
+ }
243
+ export declare namespace Vec3 {
244
+ /**
245
+ * Construct a vector from three components.
246
+ *
247
+ * @example
248
+ * ```ts,runnable,console
249
+ * import { Vec3 } from '@js-draw/math';
250
+ * const v1 = Vec3.of(1, 2, 3);
251
+ * ```
252
+ */
253
+ const of: (x: number, y: number, z: number) => Vec3;
254
+ const unitX: Vec2Impl;
255
+ const unitY: Vec2Impl;
256
+ const zero: Vec2Impl;
257
+ /** A vector of length 1 in the z direction. */
258
+ const unitZ: Vec3;
163
259
  }
164
260
  export default Vec3;