@js-draw/math 1.18.0 → 1.21.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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;