@js-draw/math 1.0.0
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/README.md +3 -0
- package/build-config.json +4 -0
- package/dist/cjs/Color4.d.ts +83 -0
- package/dist/cjs/Color4.js +277 -0
- package/dist/cjs/Mat33.d.ts +131 -0
- package/dist/cjs/Mat33.js +345 -0
- package/dist/cjs/Vec2.d.ts +42 -0
- package/dist/cjs/Vec2.js +48 -0
- package/dist/cjs/Vec3.d.ts +126 -0
- package/dist/cjs/Vec3.js +203 -0
- package/dist/cjs/lib.d.ts +27 -0
- package/dist/cjs/lib.js +42 -0
- package/dist/cjs/polynomial/solveQuadratic.d.ts +9 -0
- package/dist/cjs/polynomial/solveQuadratic.js +39 -0
- package/dist/cjs/rounding.d.ts +15 -0
- package/dist/cjs/rounding.js +146 -0
- package/dist/cjs/shapes/Abstract2DShape.d.ts +49 -0
- package/dist/cjs/shapes/Abstract2DShape.js +38 -0
- package/dist/cjs/shapes/BezierJSWrapper.d.ts +36 -0
- package/dist/cjs/shapes/BezierJSWrapper.js +94 -0
- package/dist/cjs/shapes/CubicBezier.d.ts +17 -0
- package/dist/cjs/shapes/CubicBezier.js +35 -0
- package/dist/cjs/shapes/LineSegment2.d.ts +70 -0
- package/dist/cjs/shapes/LineSegment2.js +183 -0
- package/dist/cjs/shapes/Path.d.ts +96 -0
- package/dist/cjs/shapes/Path.js +766 -0
- package/dist/cjs/shapes/PointShape2D.d.ts +18 -0
- package/dist/cjs/shapes/PointShape2D.js +31 -0
- package/dist/cjs/shapes/QuadraticBezier.d.ts +35 -0
- package/dist/cjs/shapes/QuadraticBezier.js +120 -0
- package/dist/cjs/shapes/Rect2.d.ts +58 -0
- package/dist/cjs/shapes/Rect2.js +259 -0
- package/dist/cjs/shapes/Triangle.d.ts +46 -0
- package/dist/cjs/shapes/Triangle.js +126 -0
- package/dist/mjs/Color4.d.ts +83 -0
- package/dist/mjs/Color4.mjs +271 -0
- package/dist/mjs/Mat33.d.ts +131 -0
- package/dist/mjs/Mat33.mjs +338 -0
- package/dist/mjs/Vec2.d.ts +42 -0
- package/dist/mjs/Vec2.mjs +42 -0
- package/dist/mjs/Vec3.d.ts +126 -0
- package/dist/mjs/Vec3.mjs +199 -0
- package/dist/mjs/lib.d.ts +27 -0
- package/dist/mjs/lib.mjs +29 -0
- package/dist/mjs/polynomial/solveQuadratic.d.ts +9 -0
- package/dist/mjs/polynomial/solveQuadratic.mjs +37 -0
- package/dist/mjs/rounding.d.ts +15 -0
- package/dist/mjs/rounding.mjs +139 -0
- package/dist/mjs/shapes/Abstract2DShape.d.ts +49 -0
- package/dist/mjs/shapes/Abstract2DShape.mjs +36 -0
- package/dist/mjs/shapes/BezierJSWrapper.d.ts +36 -0
- package/dist/mjs/shapes/BezierJSWrapper.mjs +89 -0
- package/dist/mjs/shapes/CubicBezier.d.ts +17 -0
- package/dist/mjs/shapes/CubicBezier.mjs +30 -0
- package/dist/mjs/shapes/LineSegment2.d.ts +70 -0
- package/dist/mjs/shapes/LineSegment2.mjs +176 -0
- package/dist/mjs/shapes/Path.d.ts +96 -0
- package/dist/mjs/shapes/Path.mjs +759 -0
- package/dist/mjs/shapes/PointShape2D.d.ts +18 -0
- package/dist/mjs/shapes/PointShape2D.mjs +26 -0
- package/dist/mjs/shapes/QuadraticBezier.d.ts +35 -0
- package/dist/mjs/shapes/QuadraticBezier.mjs +113 -0
- package/dist/mjs/shapes/Rect2.d.ts +58 -0
- package/dist/mjs/shapes/Rect2.mjs +252 -0
- package/dist/mjs/shapes/Triangle.d.ts +46 -0
- package/dist/mjs/shapes/Triangle.mjs +121 -0
- package/package.json +48 -0
- package/tsconfig.json +7 -0
- package/typedoc.json +5 -0
package/README.md
ADDED
@@ -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;
|