UNPKG

@js-draw/math

Version:
250 lines (249 loc) 8 kB
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;