@js-draw/math 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. package/README.md +3 -0
  2. package/build-config.json +4 -0
  3. package/dist/cjs/Color4.d.ts +83 -0
  4. package/dist/cjs/Color4.js +277 -0
  5. package/dist/cjs/Mat33.d.ts +131 -0
  6. package/dist/cjs/Mat33.js +345 -0
  7. package/dist/cjs/Vec2.d.ts +42 -0
  8. package/dist/cjs/Vec2.js +48 -0
  9. package/dist/cjs/Vec3.d.ts +126 -0
  10. package/dist/cjs/Vec3.js +203 -0
  11. package/dist/cjs/lib.d.ts +27 -0
  12. package/dist/cjs/lib.js +42 -0
  13. package/dist/cjs/polynomial/solveQuadratic.d.ts +9 -0
  14. package/dist/cjs/polynomial/solveQuadratic.js +39 -0
  15. package/dist/cjs/rounding.d.ts +15 -0
  16. package/dist/cjs/rounding.js +146 -0
  17. package/dist/cjs/shapes/Abstract2DShape.d.ts +49 -0
  18. package/dist/cjs/shapes/Abstract2DShape.js +38 -0
  19. package/dist/cjs/shapes/BezierJSWrapper.d.ts +36 -0
  20. package/dist/cjs/shapes/BezierJSWrapper.js +94 -0
  21. package/dist/cjs/shapes/CubicBezier.d.ts +17 -0
  22. package/dist/cjs/shapes/CubicBezier.js +35 -0
  23. package/dist/cjs/shapes/LineSegment2.d.ts +70 -0
  24. package/dist/cjs/shapes/LineSegment2.js +183 -0
  25. package/dist/cjs/shapes/Path.d.ts +96 -0
  26. package/dist/cjs/shapes/Path.js +766 -0
  27. package/dist/cjs/shapes/PointShape2D.d.ts +18 -0
  28. package/dist/cjs/shapes/PointShape2D.js +31 -0
  29. package/dist/cjs/shapes/QuadraticBezier.d.ts +35 -0
  30. package/dist/cjs/shapes/QuadraticBezier.js +120 -0
  31. package/dist/cjs/shapes/Rect2.d.ts +58 -0
  32. package/dist/cjs/shapes/Rect2.js +259 -0
  33. package/dist/cjs/shapes/Triangle.d.ts +46 -0
  34. package/dist/cjs/shapes/Triangle.js +126 -0
  35. package/dist/mjs/Color4.d.ts +83 -0
  36. package/dist/mjs/Color4.mjs +271 -0
  37. package/dist/mjs/Mat33.d.ts +131 -0
  38. package/dist/mjs/Mat33.mjs +338 -0
  39. package/dist/mjs/Vec2.d.ts +42 -0
  40. package/dist/mjs/Vec2.mjs +42 -0
  41. package/dist/mjs/Vec3.d.ts +126 -0
  42. package/dist/mjs/Vec3.mjs +199 -0
  43. package/dist/mjs/lib.d.ts +27 -0
  44. package/dist/mjs/lib.mjs +29 -0
  45. package/dist/mjs/polynomial/solveQuadratic.d.ts +9 -0
  46. package/dist/mjs/polynomial/solveQuadratic.mjs +37 -0
  47. package/dist/mjs/rounding.d.ts +15 -0
  48. package/dist/mjs/rounding.mjs +139 -0
  49. package/dist/mjs/shapes/Abstract2DShape.d.ts +49 -0
  50. package/dist/mjs/shapes/Abstract2DShape.mjs +36 -0
  51. package/dist/mjs/shapes/BezierJSWrapper.d.ts +36 -0
  52. package/dist/mjs/shapes/BezierJSWrapper.mjs +89 -0
  53. package/dist/mjs/shapes/CubicBezier.d.ts +17 -0
  54. package/dist/mjs/shapes/CubicBezier.mjs +30 -0
  55. package/dist/mjs/shapes/LineSegment2.d.ts +70 -0
  56. package/dist/mjs/shapes/LineSegment2.mjs +176 -0
  57. package/dist/mjs/shapes/Path.d.ts +96 -0
  58. package/dist/mjs/shapes/Path.mjs +759 -0
  59. package/dist/mjs/shapes/PointShape2D.d.ts +18 -0
  60. package/dist/mjs/shapes/PointShape2D.mjs +26 -0
  61. package/dist/mjs/shapes/QuadraticBezier.d.ts +35 -0
  62. package/dist/mjs/shapes/QuadraticBezier.mjs +113 -0
  63. package/dist/mjs/shapes/Rect2.d.ts +58 -0
  64. package/dist/mjs/shapes/Rect2.mjs +252 -0
  65. package/dist/mjs/shapes/Triangle.d.ts +46 -0
  66. package/dist/mjs/shapes/Triangle.mjs +121 -0
  67. package/package.json +48 -0
  68. package/tsconfig.json +7 -0
  69. package/typedoc.json +5 -0
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # `@js-draw/math`
2
+
3
+ A library with math utilities used by `js-draw`.
@@ -0,0 +1,4 @@
1
+ {
2
+ "inDirectory": "./src",
3
+ "outDirectory": "./dist"
4
+ }
@@ -0,0 +1,83 @@
1
+ import Vec3 from './Vec3';
2
+ /**
3
+ * Represents a color.
4
+ *
5
+ * @example
6
+ * ```ts,runnable,console
7
+ * import { Color4 } from '@js-draw/math';
8
+ *
9
+ * console.log('Red:', Color4.fromString('#f00'));
10
+ * console.log('Also red:', Color4.ofRGB(1, 0, 0), Color4.red);
11
+ * console.log('Mixing red and blue:', Color4.red.mix(Color4.blue, 0.5));
12
+ * console.log('To string:', Color4.orange.toHexString());
13
+ * ```
14
+ */
15
+ export default class Color4 {
16
+ /** Red component. Should be in the range [0, 1]. */
17
+ readonly r: number;
18
+ /** Green component. ${\tt g} \in [0, 1]$ */
19
+ readonly g: number;
20
+ /** Blue component. ${\tt b} \in [0, 1]$ */
21
+ readonly b: number;
22
+ /** Alpha/transparent component. ${\tt a} \in [0, 1]$. 0 = transparent */
23
+ readonly a: number;
24
+ private constructor();
25
+ /**
26
+ * Create a color from red, green, blue components. The color is fully opaque (`a = 1.0`).
27
+ *
28
+ * Each component should be in the range [0, 1].
29
+ */
30
+ static ofRGB(red: number, green: number, blue: number): Color4;
31
+ static ofRGBA(red: number, green: number, blue: number, alpha: number): Color4;
32
+ static fromHex(hexString: string): Color4;
33
+ /** Like fromHex, but can handle additional colors if an `HTMLCanvasElement` is available. */
34
+ static fromString(text: string): Color4;
35
+ /** @returns true if `this` and `other` are approximately equal. */
36
+ eq(other: Color4 | null | undefined): boolean;
37
+ /**
38
+ * If `fractionTo` is not in the range $[0, 1]$, it will be clamped to the nearest number
39
+ * in that range. For example, `a.mix(b, -1)` is equivalent to `a.mix(b, 0)`.
40
+ *
41
+ * @returns a color `fractionTo` of the way from this color to `other`.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * Color4.ofRGB(1, 0, 0).mix(Color4.ofRGB(0, 1, 0), 0.1) // -> Color4(0.9, 0.1, 0)
46
+ * ```
47
+ */
48
+ mix(other: Color4, fractionTo: number): Color4;
49
+ /**
50
+ * @returns the component-wise average of `colors`, or `Color4.transparent` if `colors` is empty.
51
+ */
52
+ static average(colors: Color4[]): Color4;
53
+ /**
54
+ * Converts to (hue, saturation, value).
55
+ * See also https://en.wikipedia.org/wiki/HSL_and_HSV#General_approach
56
+ *
57
+ * The resultant hue is represented in radians and is thus in $[0, 2\pi]$.
58
+ */
59
+ asHSV(): Vec3;
60
+ private hexString;
61
+ /**
62
+ * @returns a hexadecimal color string representation of `this`, in the form `#rrggbbaa`.
63
+ *
64
+ * @example
65
+ * ```
66
+ * Color4.red.toHexString(); // -> #ff0000ff
67
+ * ```
68
+ */
69
+ toHexString(): string;
70
+ toString(): string;
71
+ static transparent: Color4;
72
+ static red: Color4;
73
+ static orange: Color4;
74
+ static green: Color4;
75
+ static blue: Color4;
76
+ static purple: Color4;
77
+ static yellow: Color4;
78
+ static clay: Color4;
79
+ static black: Color4;
80
+ static gray: Color4;
81
+ static white: Color4;
82
+ }
83
+ export { Color4 };
@@ -0,0 +1,277 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Color4 = void 0;
7
+ const Vec3_1 = __importDefault(require("./Vec3"));
8
+ /**
9
+ * Represents a color.
10
+ *
11
+ * @example
12
+ * ```ts,runnable,console
13
+ * import { Color4 } from '@js-draw/math';
14
+ *
15
+ * console.log('Red:', Color4.fromString('#f00'));
16
+ * console.log('Also red:', Color4.ofRGB(1, 0, 0), Color4.red);
17
+ * console.log('Mixing red and blue:', Color4.red.mix(Color4.blue, 0.5));
18
+ * console.log('To string:', Color4.orange.toHexString());
19
+ * ```
20
+ */
21
+ class Color4 {
22
+ constructor(
23
+ /** Red component. Should be in the range [0, 1]. */
24
+ r,
25
+ /** Green component. ${\tt g} \in [0, 1]$ */
26
+ g,
27
+ /** Blue component. ${\tt b} \in [0, 1]$ */
28
+ b,
29
+ /** Alpha/transparent component. ${\tt a} \in [0, 1]$. 0 = transparent */
30
+ a) {
31
+ this.r = r;
32
+ this.g = g;
33
+ this.b = b;
34
+ this.a = a;
35
+ this.hexString = null;
36
+ }
37
+ /**
38
+ * Create a color from red, green, blue components. The color is fully opaque (`a = 1.0`).
39
+ *
40
+ * Each component should be in the range [0, 1].
41
+ */
42
+ static ofRGB(red, green, blue) {
43
+ return Color4.ofRGBA(red, green, blue, 1.0);
44
+ }
45
+ static ofRGBA(red, green, blue, alpha) {
46
+ red = Math.max(0, Math.min(red, 1));
47
+ green = Math.max(0, Math.min(green, 1));
48
+ blue = Math.max(0, Math.min(blue, 1));
49
+ alpha = Math.max(0, Math.min(alpha, 1));
50
+ return new Color4(red, green, blue, alpha);
51
+ }
52
+ static fromHex(hexString) {
53
+ // Remove starting '#' (if present)
54
+ hexString = (hexString.match(/^[#]?(.*)$/) ?? [])[1];
55
+ hexString = hexString.toUpperCase();
56
+ if (!hexString.match(/^[0-9A-F]+$/)) {
57
+ throw new Error(`${hexString} is not in a valid format.`);
58
+ }
59
+ // RGBA or RGB
60
+ if (hexString.length === 3 || hexString.length === 4) {
61
+ // Each character is a component
62
+ const components = hexString.split('');
63
+ // Convert to RRGGBBAA or RRGGBB format
64
+ hexString = components.map(component => `${component}0`).join('');
65
+ }
66
+ if (hexString.length === 6) {
67
+ // Alpha component
68
+ hexString += 'FF';
69
+ }
70
+ const components = [];
71
+ for (let i = 2; i <= hexString.length; i += 2) {
72
+ const chunk = hexString.substring(i - 2, i);
73
+ components.push(parseInt(chunk, 16) / 255);
74
+ }
75
+ if (components.length !== 4) {
76
+ throw new Error(`Unable to parse ${hexString}: Wrong number of components.`);
77
+ }
78
+ return Color4.ofRGBA(components[0], components[1], components[2], components[3]);
79
+ }
80
+ /** Like fromHex, but can handle additional colors if an `HTMLCanvasElement` is available. */
81
+ static fromString(text) {
82
+ if (text.startsWith('#')) {
83
+ return Color4.fromHex(text);
84
+ }
85
+ if (text === 'none' || text === 'transparent') {
86
+ return Color4.transparent;
87
+ }
88
+ // rgba?: Match both rgb and rgba strings.
89
+ // ([,0-9.]+): Match any string of only numeric, '.' and ',' characters.
90
+ const rgbRegex = /^rgba?\(([,0-9.]+)\)$/i;
91
+ const rgbMatch = text.replace(/\s*/g, '').match(rgbRegex);
92
+ if (rgbMatch) {
93
+ const componentsListStr = rgbMatch[1];
94
+ const componentsList = JSON.parse(`[ ${componentsListStr} ]`);
95
+ if (componentsList.length === 3) {
96
+ return Color4.ofRGB(componentsList[0] / 255, componentsList[1] / 255, componentsList[2] / 255);
97
+ }
98
+ else if (componentsList.length === 4) {
99
+ return Color4.ofRGBA(componentsList[0] / 255, componentsList[1] / 255, componentsList[2] / 255, componentsList[3]);
100
+ }
101
+ else {
102
+ throw new Error(`RGB string, ${text}, has wrong number of components: ${componentsList.length}`);
103
+ }
104
+ }
105
+ // Otherwise, try to use an HTMLCanvasElement to determine the color.
106
+ // Note: We may be unable to create an HTMLCanvasElement if running as a unit test.
107
+ const canvas = document.createElement('canvas');
108
+ canvas.width = 1;
109
+ canvas.height = 1;
110
+ const ctx = canvas.getContext('2d');
111
+ ctx.fillStyle = text;
112
+ ctx.fillRect(0, 0, 1, 1);
113
+ const data = ctx.getImageData(0, 0, 1, 1);
114
+ const red = data.data[0] / 255;
115
+ const green = data.data[1] / 255;
116
+ const blue = data.data[2] / 255;
117
+ const alpha = data.data[3] / 255;
118
+ return Color4.ofRGBA(red, green, blue, alpha);
119
+ }
120
+ /** @returns true if `this` and `other` are approximately equal. */
121
+ eq(other) {
122
+ if (other == null) {
123
+ return false;
124
+ }
125
+ // If both completely transparent,
126
+ if (this.a === 0 && other.a === 0) {
127
+ return true;
128
+ }
129
+ return this.toHexString() === other.toHexString();
130
+ }
131
+ /**
132
+ * If `fractionTo` is not in the range $[0, 1]$, it will be clamped to the nearest number
133
+ * in that range. For example, `a.mix(b, -1)` is equivalent to `a.mix(b, 0)`.
134
+ *
135
+ * @returns a color `fractionTo` of the way from this color to `other`.
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * Color4.ofRGB(1, 0, 0).mix(Color4.ofRGB(0, 1, 0), 0.1) // -> Color4(0.9, 0.1, 0)
140
+ * ```
141
+ */
142
+ mix(other, fractionTo) {
143
+ fractionTo = Math.min(Math.max(fractionTo, 0), 1);
144
+ const fractionOfThis = 1 - fractionTo;
145
+ return new Color4(this.r * fractionOfThis + other.r * fractionTo, this.g * fractionOfThis + other.g * fractionTo, this.b * fractionOfThis + other.b * fractionTo, this.a * fractionOfThis + other.a * fractionTo);
146
+ }
147
+ /**
148
+ * @returns the component-wise average of `colors`, or `Color4.transparent` if `colors` is empty.
149
+ */
150
+ static average(colors) {
151
+ let averageA = 0;
152
+ let averageR = 0;
153
+ let averageG = 0;
154
+ let averageB = 0;
155
+ for (const color of colors) {
156
+ averageA += color.a;
157
+ averageR += color.r;
158
+ averageG += color.g;
159
+ averageB += color.b;
160
+ }
161
+ if (colors.length > 0) {
162
+ averageA /= colors.length;
163
+ averageR /= colors.length;
164
+ averageG /= colors.length;
165
+ averageB /= colors.length;
166
+ }
167
+ return new Color4(averageR, averageG, averageB, averageA);
168
+ }
169
+ /**
170
+ * Converts to (hue, saturation, value).
171
+ * See also https://en.wikipedia.org/wiki/HSL_and_HSV#General_approach
172
+ *
173
+ * The resultant hue is represented in radians and is thus in $[0, 2\pi]$.
174
+ */
175
+ asHSV() {
176
+ // Ref: https://en.wikipedia.org/wiki/HSL_and_HSV#General_approach
177
+ //
178
+ // HUE:
179
+ // First, consider the unit cube. Rotate it such that one vertex is at the origin
180
+ // of a plane and its three neighboring vertices are equidistant from that plane:
181
+ //
182
+ // /\
183
+ // / | \
184
+ // 2 / 3 \ 1
185
+ // \ | /
186
+ // \ | /
187
+ // . \/ .
188
+ //
189
+ // .
190
+ //
191
+ // Let z be up and (x, y, 0) be in the plane.
192
+ //
193
+ // Label vectors 1,2,3 with R, G, and B, respectively. Let R's projection into the plane
194
+ // lie along the x axis.
195
+ //
196
+ // Because R is a unit vector and R, G, B are equidistant from the plane, they must
197
+ // form 30-60-90 triangles, which have side lengths proportional to (1, √3, 2)
198
+ //
199
+ // /|
200
+ // 1/ | (√3)/2
201
+ // / |
202
+ // 1/2
203
+ //
204
+ const minComponent = Math.min(this.r, this.g, this.b);
205
+ const maxComponent = Math.max(this.r, this.g, this.b);
206
+ const chroma = maxComponent - minComponent;
207
+ let hue;
208
+ // See https://en.wikipedia.org/wiki/HSL_and_HSV#General_approach
209
+ if (chroma === 0) {
210
+ hue = 0;
211
+ }
212
+ else if (this.r >= this.g && this.r >= this.b) {
213
+ hue = ((this.g - this.b) / chroma) % 6;
214
+ }
215
+ else if (this.g >= this.r && this.g >= this.b) {
216
+ hue = (this.b - this.r) / chroma + 2;
217
+ }
218
+ else {
219
+ hue = (this.r - this.g) / chroma + 4;
220
+ }
221
+ // Convert to degree representation, then to radians.
222
+ hue *= 60;
223
+ hue *= Math.PI / 180;
224
+ // Ensure positivity.
225
+ if (hue < 0) {
226
+ hue += Math.PI * 2;
227
+ }
228
+ const value = maxComponent;
229
+ const saturation = value > 0 ? chroma / value : 0;
230
+ return Vec3_1.default.of(hue, saturation, value);
231
+ }
232
+ /**
233
+ * @returns a hexadecimal color string representation of `this`, in the form `#rrggbbaa`.
234
+ *
235
+ * @example
236
+ * ```
237
+ * Color4.red.toHexString(); // -> #ff0000ff
238
+ * ```
239
+ */
240
+ toHexString() {
241
+ if (this.hexString) {
242
+ return this.hexString;
243
+ }
244
+ const componentToHex = (component) => {
245
+ const res = Math.round(255 * component).toString(16);
246
+ if (res.length === 1) {
247
+ return `0${res}`;
248
+ }
249
+ return res;
250
+ };
251
+ const alpha = componentToHex(this.a);
252
+ const red = componentToHex(this.r);
253
+ const green = componentToHex(this.g);
254
+ const blue = componentToHex(this.b);
255
+ if (alpha === 'ff') {
256
+ return `#${red}${green}${blue}`;
257
+ }
258
+ this.hexString = `#${red}${green}${blue}${alpha}`;
259
+ return this.hexString;
260
+ }
261
+ toString() {
262
+ return this.toHexString();
263
+ }
264
+ }
265
+ exports.Color4 = Color4;
266
+ Color4.transparent = Color4.ofRGBA(0, 0, 0, 0);
267
+ Color4.red = Color4.ofRGB(1.0, 0.0, 0.0);
268
+ Color4.orange = Color4.ofRGB(1.0, 0.65, 0.0);
269
+ Color4.green = Color4.ofRGB(0.0, 1.0, 0.0);
270
+ Color4.blue = Color4.ofRGB(0.0, 0.0, 1.0);
271
+ Color4.purple = Color4.ofRGB(0.5, 0.2, 0.5);
272
+ Color4.yellow = Color4.ofRGB(1, 1, 0.1);
273
+ Color4.clay = Color4.ofRGB(0.8, 0.4, 0.2);
274
+ Color4.black = Color4.ofRGB(0, 0, 0);
275
+ Color4.gray = Color4.ofRGB(0.5, 0.5, 0.5);
276
+ Color4.white = Color4.ofRGB(1, 1, 1);
277
+ exports.default = Color4;
@@ -0,0 +1,131 @@
1
+ import { Point2, Vec2 } from './Vec2';
2
+ import Vec3 from './Vec3';
3
+ export type Mat33Array = [
4
+ number,
5
+ number,
6
+ number,
7
+ number,
8
+ number,
9
+ number,
10
+ number,
11
+ number,
12
+ number
13
+ ];
14
+ /**
15
+ * Represents a three dimensional linear transformation or
16
+ * a two-dimensional affine transformation. (An affine transformation scales/rotates/shears
17
+ * **and** translates while a linear transformation just scales/rotates/shears).
18
+ */
19
+ export declare class Mat33 {
20
+ readonly a1: number;
21
+ readonly a2: number;
22
+ readonly a3: number;
23
+ readonly b1: number;
24
+ readonly b2: number;
25
+ readonly b3: number;
26
+ readonly c1: number;
27
+ readonly c2: number;
28
+ readonly c3: number;
29
+ private readonly rows;
30
+ /**
31
+ * Creates a matrix from inputs in the form,
32
+ * $$
33
+ * \begin{bmatrix}
34
+ * a1 & a2 & a3 \\
35
+ * b1 & b2 & b3 \\
36
+ * c1 & c2 & c3
37
+ * \end{bmatrix}
38
+ * $$
39
+ */
40
+ constructor(a1: number, a2: number, a3: number, b1: number, b2: number, b3: number, c1: number, c2: number, c3: number);
41
+ /**
42
+ * Creates a matrix from the given rows:
43
+ * $$
44
+ * \begin{bmatrix}
45
+ * \texttt{r1.x} & \texttt{r1.y} & \texttt{r1.z}\\
46
+ * \texttt{r2.x} & \texttt{r2.y} & \texttt{r2.z}\\
47
+ * \texttt{r3.x} & \texttt{r3.y} & \texttt{r3.z}\\
48
+ * \end{bmatrix}
49
+ * $$
50
+ */
51
+ static ofRows(r1: Vec3, r2: Vec3, r3: Vec3): Mat33;
52
+ static identity: Mat33;
53
+ /**
54
+ * Either returns the inverse of this, or, if this matrix is singular/uninvertable,
55
+ * returns Mat33.identity.
56
+ *
57
+ * This may cache the computed inverse and return the cached version instead of recomputing
58
+ * it.
59
+ */
60
+ inverse(): Mat33;
61
+ invertable(): boolean;
62
+ private cachedInverse;
63
+ private computeInverse;
64
+ transposed(): Mat33;
65
+ rightMul(other: Mat33): Mat33;
66
+ /**
67
+ * Applies this as an **affine** transformation to the given vector.
68
+ * Returns a transformed version of `other`.
69
+ *
70
+ * Unlike {@link transformVec3}, this **does** translate the given vector.
71
+ */
72
+ transformVec2(other: Vec2): Vec2;
73
+ /**
74
+ * Applies this as a linear transformation to the given vector (doesn't translate).
75
+ * This is the standard way of transforming vectors in ℝ³.
76
+ */
77
+ transformVec3(other: Vec3): Vec3;
78
+ /** @returns true iff this is the identity matrix. */
79
+ isIdentity(): boolean;
80
+ /** Returns true iff this = other ± fuzz */
81
+ eq(other: Mat33, fuzz?: number): boolean;
82
+ toString(): string;
83
+ /**
84
+ * ```
85
+ * result[0] = top left element
86
+ * result[1] = element at row zero, column 1
87
+ * ...
88
+ * ```
89
+ */
90
+ toArray(): Mat33Array;
91
+ /**
92
+ * Returns a new `Mat33` where each entry is the output of the function
93
+ * `mapping`.
94
+ *
95
+ * @example
96
+ * ```
97
+ * new Mat33(
98
+ * 1, 2, 3,
99
+ * 4, 5, 6,
100
+ * 7, 8, 9,
101
+ * ).mapEntries(component => component - 1);
102
+ * // → ⎡ 0, 1, 2 ⎤
103
+ * // ⎢ 3, 4, 5 ⎥
104
+ * // ⎣ 6, 7, 8 ⎦
105
+ * ```
106
+ */
107
+ mapEntries(mapping: (component: number, rowcol: [number, number]) => number): Mat33;
108
+ /** Estimate the scale factor of this matrix (based on the first row). */
109
+ getScaleFactor(): number;
110
+ /**
111
+ * Constructs a 3x3 translation matrix (for translating `Vec2`s) using
112
+ * **transformVec2**.
113
+ */
114
+ static translation(amount: Vec2): Mat33;
115
+ static zRotation(radians: number, center?: Point2): Mat33;
116
+ static scaling2D(amount: number | Vec2, center?: Point2): Mat33;
117
+ /** @see {@link fromCSSMatrix} */
118
+ toCSSMatrix(): string;
119
+ /**
120
+ * Converts a CSS-form `matrix(a, b, c, d, e, f)` to a Mat33.
121
+ *
122
+ * Note that such a matrix has the form,
123
+ * ```
124
+ * ⎡ a c e ⎤
125
+ * ⎢ b d f ⎥
126
+ * ⎣ 0 0 1 ⎦
127
+ * ```
128
+ */
129
+ static fromCSSMatrix(cssString: string): Mat33;
130
+ }
131
+ export default Mat33;