UNPKG

@thi.ng/matrices

Version:

Matrix & quaternion operations for 2D/3D geometry processing

107 lines (106 loc) 2.94 kB
import { dotC4, dotC6 } from "@thi.ng/vectors/dotc"; import { magSq4 } from "@thi.ng/vectors/magsq"; import { setC, setC4, setC6 } from "@thi.ng/vectors/setc"; import { vop } from "@thi.ng/vectors/vop"; import { det44FromCoeffs, detCoeffs44 } from "./determinant.js"; const invert = vop(1); const invert22 = invert.add(4, (out, m) => { const [m00, m01, m10, m11] = m; let det = dotC4(m00, m11, -m01, m10); if (det === 0) return; det = 1 / det; return setC4(out || m, m11 * det, -m01 * det, -m10 * det, m00 * det); }); const invert23 = invert.add(6, (out, m) => { const [m00, m01, m10, m11, m20, m21] = m; let det = dotC4(m00, m11, -m01, m10); if (det === 0) return; det = 1 / det; return setC6( out || m, m11 * det, -m01 * det, -m10 * det, m00 * det, dotC4(m10, m21, -m11, m20) * det, dotC4(m01, m20, -m00, m21) * det ); }); const invert33 = invert.add(9, (out, m) => { const [m00, m01, m02, m10, m11, m12, m20, m21, m22] = m; const d01 = dotC4(m22, m11, -m12, m21); const d11 = dotC4(m12, m20, -m22, m10); const d21 = dotC4(m21, m10, -m11, m20); let det = dotC6(m00, d01, m01, d11, m02, d21); if (det === 0) return; det = 1 / det; return setC( out || m, d01 * det, dotC4(-m22, m01, m02, m21) * det, dotC4(m12, m01, -m02, m11) * det, d11 * det, dotC4(m22, m00, -m02, m20) * det, dotC4(-m12, m00, m02, m10) * det, d21 * det, dotC4(-m21, m00, m01, m20) * det, dotC4(m11, m00, -m01, m10) * det ); }); const invert44 = invert.add(16, (out, m) => { const coeffs = detCoeffs44(m); let det = det44FromCoeffs(coeffs); if (det === 0) return; det = 1 / det; const [ m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33 ] = m; const [d00, d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11] = coeffs; return setC( out || m, dotC6(m11, d11, -m12, d10, m13, d09) * det, dotC6(-m01, d11, m02, d10, -m03, d09) * det, dotC6(m31, d05, -m32, d04, m33, d03) * det, dotC6(-m21, d05, m22, d04, -m23, d03) * det, dotC6(-m10, d11, m12, d08, -m13, d07) * det, dotC6(m00, d11, -m02, d08, m03, d07) * det, dotC6(-m30, d05, m32, d02, -m33, d01) * det, dotC6(m20, d05, -m22, d02, m23, d01) * det, dotC6(m10, d10, -m11, d08, m13, d06) * det, dotC6(-m00, d10, m01, d08, -m03, d06) * det, dotC6(m30, d04, -m31, d02, m33, d00) * det, dotC6(-m20, d04, m21, d02, -m23, d00) * det, dotC6(-m10, d09, m11, d07, -m12, d06) * det, dotC6(m00, d09, -m01, d07, m02, d06) * det, dotC6(-m30, d03, m31, d01, -m32, d00) * det, dotC6(m20, d03, -m21, d01, m22, d00) * det ); }); const invertQ = (out, a) => { let d = magSq4(a); d = d > 0 ? -1 / d : 0; return setC4(out || a, a[0] * d, a[1] * d, a[2] * d, -a[3] * d); }; export { invert, invert22, invert23, invert33, invert44, invertQ };