From 065ed23c798f0f26c351081520ca977e13648950 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sat, 1 Feb 2020 01:16:47 +0100 Subject: [PATCH] :tada: Add javascript variants of geom.point and geom.matrix. Only for have them in backup, they are not in use right now and we dont expect to use them in a near future. --- frontend/src/uxbox/util/geom/_matrix.js | 229 ++++++++++++++++++++++ frontend/src/uxbox/util/geom/_point.js | 242 ++++++++++++++++++++++++ 2 files changed, 471 insertions(+) create mode 100644 frontend/src/uxbox/util/geom/_matrix.js create mode 100644 frontend/src/uxbox/util/geom/_point.js diff --git a/frontend/src/uxbox/util/geom/_matrix.js b/frontend/src/uxbox/util/geom/_matrix.js new file mode 100644 index 000000000..48b0282e1 --- /dev/null +++ b/frontend/src/uxbox/util/geom/_matrix.js @@ -0,0 +1,229 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This Source Code Form is "Incompatible With Secondary Licenses", as + * defined by the Mozilla Public License, v. 2.0. + * + * Copyright (c) 2020 Andrey Antukh +*/ + +// NOTE: this code is unused, but is preserved for the case when we +// note that the cljs impl has not not enough performance. + +goog.provide("uxbox.util.geom.matrix_impl"); +goog.provide("uxbox.util.geom.matrix_impl.Matrix"); +goog.require("goog.math"); +goog.require("uxbox.util.geom.point_impl"); + +goog.scope(function() { + const self = uxbox.util.geom.matrix_impl; + const gpt = uxbox.util.geom.point_impl; + const math = goog.math; + + /** + * @param {number} a + * @param {number} b + * @param {number} c + * @param {number} d + * @param {number} e + * @param {number} f + * @struct + */ + class Matrix { + constructor(a, b, c, d, e, f) { + this.a = a; + this.b = b; + this.c = c; + this.d = d; + this.e = e; + this.f = f; + } + + [Symbol.iterator]() { + return [["a", this.a] + ["b", this.b]]; + } + + toString() { + return `matrix(${this.a},${this.b},${this.c},${this.d},${this.e},${this.f})`; + } + + copy() { + return new Matrix( + this.a, + this.b, + this.c, + this.d, + this.e, + this.f + ); + } + } + + self.Matrix = Matrix; + + /** + * @param {number?} a + * @param {number?} b + * @param {number?} c + * @param {number?} d + * @param {number?} e + * @param {number?} f + * @return {Matrix} + */ + self.matrix = function(a, b, c, d, e, f) { + if (a === undefined) { + return new Matrix(1,0,0,1,0,0); + } else { + return new Matrix(a,b,c,d,e,f); + } + }; + + /** + * @param {?} m + * @return {boolean} + */ + function isMatrix(m) { + return m instanceof Matrix; + } + + self.isMatrix = isMatrix + + + /** + * @param {Matrix} m1 + * @param {Matrix} m2 + * @return {Matrix} + */ + self.multiplyUnsafe = function(m1, m2) { + const a = m1.a * m2.a + m1.c * m2.b; + const b = m1.b * m2.a + m1.d * m2.b; + const c = m1.a * m2.c + m1.c * m2.d; + const d = m1.b * m2.c + m1.d * m2.d; + const e = m1.a * m2.e + m1.c * m2.f + m1.e; + const f = m1.b * m2.e + m1.d * m2.f + m1.f; + m1.a = a; + m1.b = b; + m1.c = c; + m1.d = d; + m1.e = e; + m1.f = f; + return m1; + } + + /** + * @param {Matrix} m1 + * @param {Matrix} m2 + * @return {Matrix} + */ + self.multiply = function(m1, m2) { + m1 = m1.copy(); + return self.multiplyUnsafe(m1, m2); + } + + /** + * @param {...Matrix} matrices + * @return {Matrix} + */ + self.compose = function(...matrices) { + switch (matrices.length) { + case 0: + throw new Error('no matrices provided') + + case 1: + return matrices[0] + + case 2: + return self.multiply(matrices[0], matrices[1]) + + default: { + let result = matrices[0].copy(); + for (let i=1; i +*/ + +// NOTE: this code is unused, but is preserved for the case when we +// note that the cljs impl has not not enough performance. + +goog.provide("uxbox.util.geom.point_impl"); +goog.provide("uxbox.util.geom.point_impl.Point"); +goog.require("goog.math"); + +goog.scope(function() { + const self = uxbox.util.geom.point_impl; + const math = goog.math; + + /** + * @param {number} x + * @param {number} y + * @struct + */ + class Point { + constructor(x, y) { + this.x = x; + this.y = y; + } + + toString() { + return "point(" + this.x + ", " + this.y + ")"; + } + } + + self.Point = Point; + + self.point = function(x, y) { + let xv = null; + let yv = null; + + if (x === undefined) { + return new Point(0, 0); + } else { + xv = x; + } + + if (y === undefined) { + yv = x; + } else { + yv = y; + } + + return new Point(xv, yv); + }; + + function isPoint(p) { + return p instanceof Point; + } + + self.isPoint = isPoint; + + /** + * @param {Point} p + * @param {number} angle + * @return {Point} + */ + self.rotate = function(p, angle) { + const r = math.toRadians(angle); + const sin = Math.sin(r); + const cos = Math.cos(r); + + const x = p.x; + const y = p.y; + + const point = new Point( + x * cos - y * sin, + x * sin + y * cos + ); + + return self.roundTo(point, 6) + }; + + /** + * @param {Point} p + * @param {Point} other + * @return {Point} + */ + self.add = function(p, other) { + return new Point( + p.x + other.x, + p.y + other.y + ); + }; + + /** + * @param {Point} p + * @param {Point} other + * @return {Point} + */ + self.subtract = function(p, other) { + return new Point( + p.x - other.x, + p.y - other.y + ); + }; + + /** + * @param {Point} p + * @param {Point} other + * @return {Point} + */ + self.multiply = function(p, other) { + return new Point( + p.x * other.x, + p.y * other.y + ); + }; + + /** + * @param {Point} p + * @param {Point} other + * @return {Point} + */ + self.divide = function(p, other) { + return new Point( + p.x / other.x, + p.y / other.y + ); + }; + + /** + * @param {Point} p + * @return {Point} + */ + self.negate = function(p) { + const x = p.x, y = p.y; + return new Point( + x === 0 ? x : x * -1, + y === 0 ? y : y * -1 + ); + }; + + /** + * @param {Point} p + * @param {Point} other + * @return {number} + */ + self.distance = function(p, other) { + const dx = p.x - other.x; + const dy = p.y - other.y; + return Math.sqrt(Math.pow(dx, 2), + Math.pow(dy, 2)); + }; + + /** + * @param {Point} p + * @param {Point} center + * @return {number} + */ + self.angle = function(p, center) { + if (center !== undefined) { + p = self.subtract(p, center); + } + + return math.toDegrees(Math.atan2(p.y, p.x)); + }; + + /** + * @param {Point} p + * @param {Point} other + * @return {number} + */ + self.length = function(p) { + return Math.sqrt(Math.pow(p.x, 2) + Math.pow(p.y, 2)); + }; + + /** + * @param {Point} p + * @return {number} + */ + self.angle2other = function(p, other) { + let angle = ((p.x * other.x) + (p.y * other.y)) / (self.length(p) * self.length(other)); + + if (angle < -1) { + angle = -1; + } else if (angle > 1) { + angle = 1; + } + + angle = Math.acos(angle); + angle = math.toDegrees(angle); + return parseFloat(angle.toFixed(6)); + }; + + /** + * @param {Point} p + * @param {number} angle + * @return {Point} + */ + self.updateAngle = function(p, angle) { + const len = self.length(p); + const r = math.toRadiants(angle); + + return new Point( + Math.cos(r) * len, + Math.sin(r) * len + ); + }; + + /** + * @param {Point} p + * @param {number} decimals + * @return {Point} + */ + self.roundTo = function(p, decimals) { + return new Point( + parseFloat(p.x.toFixed(decimals)), + parseFloat(p.y.toFixed(decimals)) + ); + }; + + // class Matrix { + // constructor() { + // this.a = 1; + // this.b = 0; + // this.c = 0; + // this.d = 1; + // this.e = 0; + // this.f = 0; + // } + // } + + // self = uxbox.util.geom.matrix_impl; + // self.Matrix = Matrix; + // self.sayHello = function() { + // console.log("hello"); + // } +});