UNPKG

@nuintun/qrcode

Version:

A pure JavaScript QRCode encode and decode library.

140 lines (137 loc) 3.86 kB
/** * @module QRCode * @package @nuintun/qrcode * @license MIT * @version 5.0.2 * @author nuintun <nuintun@qq.com> * @description A pure JavaScript QRCode encode and decode library. * @see https://github.com/nuintun/qrcode#readme */ /** * @module PerspectiveTransform */ class PerspectiveTransform { #a11; #a12; #a13; #a21; #a22; #a23; #a31; #a32; #a33; constructor(a11, a21, a31, a12, a22, a32, a13, a23, a33) { this.#a11 = a11; this.#a12 = a12; this.#a13 = a13; this.#a21 = a21; this.#a22 = a22; this.#a23 = a23; this.#a31 = a31; this.#a32 = a32; this.#a33 = a33; } inverse() { // Adjoint is the transpose of the cofactor matrix. const a11 = this.#a11; const a12 = this.#a12; const a13 = this.#a13; const a21 = this.#a21; const a22 = this.#a22; const a23 = this.#a23; const a31 = this.#a31; const a32 = this.#a32; const a33 = this.#a33; return new PerspectiveTransform( a22 * a33 - a23 * a32, a23 * a31 - a21 * a33, a21 * a32 - a22 * a31, a13 * a32 - a12 * a33, a11 * a33 - a13 * a31, a12 * a31 - a11 * a32, a12 * a23 - a13 * a22, a13 * a21 - a11 * a23, a11 * a22 - a12 * a21 ); } times(other) { const a11 = this.#a11; const a12 = this.#a12; const a13 = this.#a13; const a21 = this.#a21; const a22 = this.#a22; const a23 = this.#a23; const a31 = this.#a31; const a32 = this.#a32; const a33 = this.#a33; const b11 = other.#a11; const b12 = other.#a12; const b13 = other.#a13; const b21 = other.#a21; const b22 = other.#a22; const b23 = other.#a23; const b31 = other.#a31; const b32 = other.#a32; const b33 = other.#a33; return new PerspectiveTransform( a11 * b11 + a21 * b12 + a31 * b13, a11 * b21 + a21 * b22 + a31 * b23, a11 * b31 + a21 * b32 + a31 * b33, a12 * b11 + a22 * b12 + a32 * b13, a12 * b21 + a22 * b22 + a32 * b23, a12 * b31 + a22 * b32 + a32 * b33, a13 * b11 + a23 * b12 + a33 * b13, a13 * b21 + a23 * b22 + a33 * b23, a13 * b31 + a23 * b32 + a33 * b33 ); } mapping(x, y) { const a11 = this.#a11; const a12 = this.#a12; const a13 = this.#a13; const a21 = this.#a21; const a22 = this.#a22; const a23 = this.#a23; const a31 = this.#a31; const a32 = this.#a32; const a33 = this.#a33; const denominator = a13 * x + a23 * y + a33; return [(a11 * x + a21 * y + a31) / denominator, (a12 * x + a22 * y + a32) / denominator]; } } function squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3) { const dx3 = x0 - x1 + x2 - x3; const dy3 = y0 - y1 + y2 - y3; if (dx3 === 0 && dy3 === 0) { return new PerspectiveTransform(x1 - x0, x2 - x1, x0, y1 - y0, y2 - y1, y0, 0, 0, 1); } else { const dx1 = x1 - x2; const dx2 = x3 - x2; const dy1 = y1 - y2; const dy2 = y3 - y2; const denominator = dx1 * dy2 - dx2 * dy1; const a13 = (dx3 * dy2 - dx2 * dy3) / denominator; const a23 = (dx1 * dy3 - dx3 * dy1) / denominator; return new PerspectiveTransform( x1 - x0 + a13 * x1, x3 - x0 + a23 * x3, x0, y1 - y0 + a13 * y1, y3 - y0 + a23 * y3, y0, a13, a23, 1 ); } } function quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3) { // Here, the adjoint serves as the inverse. return squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3).inverse(); } function quadrilateralToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3, x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p) { const qToS = quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3); const sToQ = squareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p); return sToQ.times(qToS); } export { PerspectiveTransform, quadrilateralToQuadrilateral };