@js-draw/math
Version:
A math library for js-draw.
250 lines (249 loc) • 8 kB
TypeScript
import { Point2, Vec2 } from './Vec2';
import Vec3 from './Vec3';
/**
* See {@link Mat33.toArray}.
*/
export type Mat33Array = [number, number, number, number, number, number, number, number, number];
/**
* Represents a three dimensional linear transformation or
* a two-dimensional affine transformation. (An affine transformation scales/rotates/shears
* **and** translates while a linear transformation just scales/rotates/shears).
*
* In addition to other matrices, {@link Mat33}s can be used to transform {@link Vec3}s and {@link Vec2}s.
*
* For example, to move the point $(1, 1)$ by 5 units to the left and 6 units up,
* ```ts,runnable,console
* import {Mat33, Vec2} from '@js-draw/math';
*
* const moveLeftAndUp = Mat33.translation(Vec2.of(5, 6));
* console.log(moveLeftAndUp);
* ```
*
* This `moveLeftAndUp` matrix could then translate (move) a {@link Vec2} using
* {@link Mat33.transformVec2}:
*
* ```ts,runnable,console
* ---use-previous---
* ---visible---
* console.log(moveLeftAndUp.transformVec2(Vec2.of(1, 1)));
* console.log(moveLeftAndUp.transformVec2(Vec2.of(-1, 2)));
* ```
*
* It's also possible to create transformation matrices that scale and rotate.
* A single transform matrix can be created from multiple using matrix multiplication
* (see {@link Mat33.rightMul}):
*
* ```ts,runnable,console
* ---use-previous---
* ---visible---
* // Create a matrix by right multiplying.
* const scaleThenRotate =
* // The resultant matrix first scales by a factor of two
* Mat33.scaling2D(2).rightMul(
* // ...then rotates by pi/2 radians = 90 degrees.
* Mat33.zRotation(Math.PI / 2)
* );
* console.log(scaleThenRotate);
*
* // Use scaleThenRotate to scale then rotate a vector.
* console.log(scaleThenRotate.transformVec2(Vec2.unitX));
* ```
*/
export declare class Mat33 {
readonly a1: number;
readonly a2: number;
readonly a3: number;
readonly b1: number;
readonly b2: number;
readonly b3: number;
readonly c1: number;
readonly c2: number;
readonly c3: number;
private readonly rows;
/**
* Creates a matrix from inputs in the form,
* $$
* \begin{bmatrix}
* a1 & a2 & a3 \\
* b1 & b2 & b3 \\
* c1 & c2 & c3
* \end{bmatrix}
* $$
*
* Static constructor methods are also available.
* See {@link Mat33.scaling2D}, {@link Mat33.zRotation}, {@link Mat33.translation}, and {@link Mat33.fromCSSMatrix}.
*/
constructor(a1: number, a2: number, a3: number, b1: number, b2: number, b3: number, c1: number, c2: number, c3: number);
/**
* Creates a matrix from the given rows:
* $$
* \begin{bmatrix}
* \texttt{r1.x} & \texttt{r1.y} & \texttt{r1.z}\\
* \texttt{r2.x} & \texttt{r2.y} & \texttt{r2.z}\\
* \texttt{r3.x} & \texttt{r3.y} & \texttt{r3.z}\\
* \end{bmatrix}
* $$
*/
static ofRows(r1: Vec3, r2: Vec3, r3: Vec3): Mat33;
/** The 3x3 [identity matrix](https://en.wikipedia.org/wiki/Identity_matrix). */
static identity: Mat33;
/**
* Either returns the inverse of this, or, if this matrix is singular/uninvertable,
* returns Mat33.identity.
*
* This may cache the computed inverse and return the cached version instead of recomputing
* it.
*/
inverse(): Mat33;
invertable(): boolean;
private cachedInverse;
private computeInverse;
transposed(): Mat33;
/**
* [Right-multiplies](https://en.wikipedia.org/wiki/Matrix_multiplication) this by `other`.
*
* See also {@link transformVec3} and {@link transformVec2}.
*
* Example:
* ```ts,runnable,console
* import {Mat33, Vec2} from '@js-draw/math';
* console.log(Mat33.identity.rightMul(Mat33.identity));
*
* // Create a matrix by right multiplying.
* const scaleThenRotate =
* // The resultant matrix first scales by a factor of two
* Mat33.scaling2D(2).rightMul(
* // ...then rotates by pi/4 radians = 45 degrees.
* Mat33.zRotation(Math.PI / 4)
* );
* console.log(scaleThenRotate);
*
* // Use scaleThenRotate to scale then rotate a vector.
* console.log(scaleThenRotate.transformVec2(Vec2.unitX));
* ```
*/
rightMul(other: Mat33): Mat33;
/**
* Applies this as an **affine** transformation to the given vector.
* Returns a transformed version of `other`.
*
* Unlike {@link transformVec3}, this **does** translate the given vector.
*/
transformVec2(other: Vec2): Vec2;
/**
* Applies this as a linear transformation to the given vector (doesn't translate).
* This is the standard way of transforming vectors in ℝ³.
*/
transformVec3(other: Vec3): Vec3;
/** @returns true iff this is the identity matrix. */
isIdentity(): boolean;
/** Returns true iff this = other ± fuzz */
eq(other: Mat33, fuzz?: number): boolean;
/**
* Creates a human-readable representation of the matrix.
*
* Example:
* ```ts,runnable,console
* import { Mat33 } from '@js-draw/math';
* console.log(Mat33.identity.toString());
* ```
*/
toString(): string;
/**
* ```
* result[0] = top left element
* result[1] = element at row zero, column 1
* ...
* ```
*
* Example:
* ```ts,runnable,console
* import { Mat33 } from '@js-draw/math';
* console.log(
* new Mat33(
* 1, 2, 3,
* 4, 5, 6,
* 7, 8, 9,
* )
* );
* ```
*/
toArray(): Mat33Array;
/**
* Returns a new `Mat33` where each entry is the output of the function
* `mapping`.
*
* @example
* ```
* new Mat33(
* 1, 2, 3,
* 4, 5, 6,
* 7, 8, 9,
* ).mapEntries(component => component - 1);
* // → ⎡ 0, 1, 2 ⎤
* // ⎢ 3, 4, 5 ⎥
* // ⎣ 6, 7, 8 ⎦
* ```
*/
mapEntries(mapping: (component: number, rowcol: [number, number]) => number): Mat33;
/** Estimate the scale factor of this matrix (based on the first row). */
getScaleFactor(): number;
/** Returns the `idx`-th column (`idx` is 0-indexed). */
getColumn(idx: number): Vec3;
/** Returns the magnitude of the entry with the largest entry */
maximumEntryMagnitude(): number;
/**
* Constructs a 3x3 translation matrix (for translating `Vec2`s) using
* **transformVec2**.
*
* Creates a matrix in the form
* $$
* \begin{pmatrix}
* 1 & 0 & {\tt amount.x}\\
* 0 & 1 & {\tt amount.y}\\
* 0 & 0 & 1
* \end{pmatrix}
* $$
*/
static translation(amount: Vec2): Mat33;
/**
* Creates a matrix for rotating `Vec2`s about `center` by some number of `radians`.
*
* For this function, {@link Vec2}s are considered to be points in 2D space.
*
* For example,
* ```ts,runnable,console
* import { Mat33, Vec2 } from '@js-draw/math';
*
* const halfCircle = Math.PI; // PI radians = 180 degrees = 1/2 circle
* const center = Vec2.of(1, 1); // The point (1,1)
* const rotationMatrix = Mat33.zRotation(halfCircle, center);
*
* console.log(
* 'Rotating (0,0) 180deg about', center, 'results in',
* // Rotates (0,0)
* rotationMatrix.transformVec2(Vec2.zero),
* );
* ```
*/
static zRotation(radians: number, center?: Point2): Mat33;
static scaling2D(amount: number | Vec2, center?: Point2): Mat33;
/**
* **Note**: Assumes `this.c1 = this.c2 = 0` and `this.c3 = 1`.
*
* @see {@link fromCSSMatrix}
*/
toCSSMatrix(): string;
/**
* Converts a CSS-form `matrix(a, b, c, d, e, f)` to a Mat33.
*
* Note that such a matrix has the form,
* ```
* ⎡ a c e ⎤
* ⎢ b d f ⎥
* ⎣ 0 0 1 ⎦
* ```
*/
static fromCSSMatrix(cssString: string): Mat33;
}
export default Mat33;