UNPKG

react-native-gesture-handler

Version:

Declarative API exposing native platform touch and gesture system to React Native

204 lines (147 loc) 5.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } // Implementation taken from Flutter's LeastSquareSolver // https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/gestures/lsq_solver.dart class Vector { constructor(length) { _defineProperty(this, "offset", void 0); _defineProperty(this, "length", void 0); _defineProperty(this, "elements", void 0); this.offset = 0; this.length = length; this.elements = new Array(length); } static fromVOL(values, offset, length) { const result = new Vector(0); result.offset = offset; result.length = length; result.elements = values; return result; } get(index) { return this.elements[this.offset + index]; } set(index, value) { this.elements[this.offset + index] = value; } dot(other) { let result = 0; for (let i = 0; i < this.length; i++) { result += this.get(i) * other.get(i); } return result; } norm() { return Math.sqrt(this.dot(this)); } } class Matrix { constructor(rows, columns) { _defineProperty(this, "columns", void 0); _defineProperty(this, "elements", void 0); this.columns = columns; this.elements = new Array(rows * columns); } get(row, column) { return this.elements[row * this.columns + column]; } set(row, column, value) { this.elements[row * this.columns + column] = value; } getRow(row) { return Vector.fromVOL(this.elements, row * this.columns, this.columns); } } // An nth degree polynomial fit to a dataset. class PolynomialFit { // The polynomial coefficients of the fit. // // For each `i`, the element `coefficients[i]` is the coefficient of // the `i`-th power of the variable. // Creates a polynomial fit of the given degree. // // There are n + 1 coefficients in a fit of degree n. constructor(degree) { _defineProperty(this, "coefficients", void 0); this.coefficients = new Array(degree + 1); } } const precisionErrorTolerance = 1e-10; // Uses the least-squares algorithm to fit a polynomial to a set of data. class LeastSquareSolver { // The x-coordinates of each data point. // The y-coordinates of each data point. // The weight to use for each data point. // Creates a least-squares solver. // // The [x], [y], and [w] arguments must not be null. constructor(x, y, w) { _defineProperty(this, "x", void 0); _defineProperty(this, "y", void 0); _defineProperty(this, "w", void 0); this.x = x; this.y = y; this.w = w; } // Fits a polynomial of the given degree to the data points. // // When there is not enough data to fit a curve null is returned. solve(degree) { if (degree > this.x.length) { // Not enough data to fit a curve. return null; } const result = new PolynomialFit(degree); // Shorthands for the purpose of notation equivalence to original C++ code. const m = this.x.length; const n = degree + 1; // Expand the X vector to a matrix A, pre-multiplied by the weights. const a = new Matrix(n, m); for (let h = 0; h < m; h++) { a.set(0, h, this.w[h]); for (let i = 1; i < n; i++) { a.set(i, h, a.get(i - 1, h) * this.x[h]); } } // Apply the Gram-Schmidt process to A to obtain its QR decomposition. // Orthonormal basis, column-major ordVectorer. const q = new Matrix(n, m); // Upper triangular matrix, row-major order. const r = new Matrix(n, m); for (let j = 0; j < n; j += 1) { for (let h = 0; h < m; h += 1) { q.set(j, h, a.get(j, h)); } for (let i = 0; i < j; i += 1) { const dot = q.getRow(j).dot(q.getRow(i)); for (let h = 0; h < m; h += 1) { q.set(j, h, q.get(j, h) - dot * q.get(i, h)); } } const norm = q.getRow(j).norm(); if (norm < precisionErrorTolerance) { // Vectors are linearly dependent or zero so no solution. return null; } const inverseNorm = 1.0 / norm; for (let h = 0; h < m; h += 1) { q.set(j, h, q.get(j, h) * inverseNorm); } for (let i = 0; i < n; i += 1) { r.set(j, i, i < j ? 0.0 : q.getRow(j).dot(a.getRow(i))); } } // Solve R B = Qt W Y to find B. This is easy because R is upper triangular. // We just work from bottom-right to top-left calculating B's coefficients. const wy = new Vector(m); for (let h = 0; h < m; h += 1) { wy.set(h, this.y[h] * this.w[h]); } for (let i = n - 1; i >= 0; i -= 1) { result.coefficients[i] = q.getRow(i).dot(wy); for (let j = n - 1; j > i; j -= 1) { result.coefficients[i] -= r.get(i, j) * result.coefficients[j]; } result.coefficients[i] /= r.get(i, i); } return result; } } exports.default = LeastSquareSolver; //# sourceMappingURL=LeastSquareSolver.js.map