Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

kld-affine

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

kld-affine - npm Package Compare versions

Comparing version 2.0.4 to 2.1.0

.babelrc

24

index.js

@@ -0,5 +1,23 @@

/**
* @module kld-affine
*/
// expose classes
exports.Point2D = require('./lib/Point2D');
exports.Vector2D = require('./lib/Vector2D');
exports.Matrix2D = require('./lib/Matrix2D');
/**
* @namespace Point2D
* @implements {module:Point2D~Point2D}
*/
export {default as Point2D} from "./lib/Point2D.js";
/**
* @namespace Vector2D
* @implements {module:Vector2D~Vector2D}
*/
export {default as Vector2D} from "./lib/Vector2D.js";
/**
* @namespace Matrix2D
* @implements {module:Matrix2D~Matrix2D}
*/
export {default as Matrix2D} from "./lib/Matrix2D.js";

1105

lib/Matrix2D.js
/**
* Matrix2D.js
*
* copyright 2001-2002, 2013, 2017 Kevin Lindsey
* Matrix2D.js
* @module Matrix2D
* @copyright 2001-2019 Kevin Lindsey
*/
function setReadonlyProperty(object, property, value) {
Object.defineProperty(object, property, {
value: value,
writable: false,
enumerable: true,
configurable: false
});
}
/**
* Identity matrix
* Matrix2D
*
* @returns {Matrix2D}
* @memberof module:kld-affine
*/
setReadonlyProperty(Matrix2D, "IDENTITY", new Matrix2D(1, 0, 0, 1, 0, 0));
setReadonlyProperty(Matrix2D.IDENTITY, "isIdentity", function () { return true; });
class Matrix2D {
/**
* Matrix2D
*
* [a c e]
* [b d f]
* [0 0 1]
*
* @param {number} a
* @param {number} b
* @param {number} c
* @param {number} d
* @param {number} e
* @param {number} f
* @returns {module:kld-affine.Matrix2D}
*/
constructor(a, b, c, d, e, f) {
this.a = (a !== undefined) ? a : 1;
this.b = (b !== undefined) ? b : 0;
this.c = (c !== undefined) ? c : 0;
this.d = (d !== undefined) ? d : 1;
this.e = (e !== undefined) ? e : 0;
this.f = (f !== undefined) ? f : 0;
}
/**
* translation
*
* @param {number} tx
* @param {number} ty
* @returns {module:kld-affine.Matrix2D}
*/
static translation(tx, ty) {
return new Matrix2D(1, 0, 0, 1, tx, ty);
}
/**
* Matrix2D
*
* [a c e]
* [b d f]
* [0 0 1]
*
* @param {Number} a
* @param {Number} b
* @param {Number} c
* @param {Number} d
* @param {Number} e
* @param {Number} f
* @returns {Matrix2D}
*/
function Matrix2D(a, b, c, d, e, f) {
setReadonlyProperty(this, "a", (a !== undefined) ? a : 1);
setReadonlyProperty(this, "b", (b !== undefined) ? b : 0);
setReadonlyProperty(this, "c", (c !== undefined) ? c : 0);
setReadonlyProperty(this, "d", (d !== undefined) ? d : 1);
setReadonlyProperty(this, "e", (e !== undefined) ? e : 0);
setReadonlyProperty(this, "f", (f !== undefined) ? f : 0);
}
/**
* scaling
*
* @param {number} scale
* @returns {module:kld-affine.Matrix2D}
*/
static scaling(scale) {
return new Matrix2D(scale, 0, 0, scale, 0, 0);
}
/**
* scalingAt
*
* @param {number} scale
* @param {module:kld-affine.Point2D} center
* @returns {module:kld-affine.Matrix2D}
*/
static scalingAt(scale, center) {
return new Matrix2D(
scale,
0,
0,
scale,
center.x - center.x * scale,
center.y - center.y * scale
);
}
// *** STATIC METHODS
/**
* translation
*
* @param {Number} tx
* @param {Number} ty
* @returns {Matrix2D}
*/
Matrix2D.translation = function(tx, ty) {
return new Matrix2D(1, 0, 0, 1, tx, ty);
};
/**
* nonUniformScaling
*
* @param {number} scaleX
* @param {number} scaleY
* @returns {module:kld-affine.Matrix2D}
*/
static nonUniformScaling(scaleX, scaleY) {
return new Matrix2D(scaleX, 0, 0, scaleY, 0, 0);
}
/**
* scaling
*
* @param {Number} scale
* @returns {Matrix2D}
*/
Matrix2D.scaling = function(scale) {
return new Matrix2D(scale, 0, 0, scale, 0, 0);
};
/**
* nonUniformScalingAt
*
* @param {number} scaleX
* @param {number} scaleY
* @param {module:kld-affine.Point2D} center
* @returns {module:kld-affine.Matrix2D}
*/
static nonUniformScalingAt(scaleX, scaleY, center) {
return new Matrix2D(
scaleX,
0,
0,
scaleY,
center.x - center.x * scaleX,
center.y - center.y * scaleY
);
}
/**
* scalingAt
*
* @param {Number} scale
* @param {Point2D} center
* @returns {Matrix2D}
*/
Matrix2D.scalingAt = function(scale, center) {
return new Matrix2D(
scale,
0,
0,
scale,
center.x - center.x * scale,
center.y - center.y * scale
);
}
/**
* rotation
*
* @param {number} radians
* @returns {module:kld-affine.Matrix2D}
*/
static rotation(radians) {
const c = Math.cos(radians);
const s = Math.sin(radians);
return new Matrix2D(c, s, -s, c, 0, 0);
}
/**
* nonUniformScaling
*
* @param {Number} scaleX
* @param {Number} scaleY
* @returns {Matrix2D}
*/
Matrix2D.nonUniformScaling = function(scaleX, scaleY) {
return new Matrix2D(scaleX, 0, 0, scaleY, 0, 0);
};
/**
* rotationAt
*
* @param {number} radians
* @param {module:kld-affine.Point2D} center
* @returns {module:kld-affine.Matrix2D}
*/
static rotationAt(radians, center) {
const c = Math.cos(radians);
const s = Math.sin(radians);
/**
* nonUniformScalingAt
*
* @param {Number} scaleX
* @param {Number} scaleY
* @param {Point2D} center
* @returns {Matrix2D}
*/
Matrix2D.nonUniformScalingAt = function(scaleX, scaleY, center) {
return new Matrix2D(
scaleX,
0,
0,
scaleY,
center.x - center.x * scaleX,
center.y - center.y * scaleY
);
};
return new Matrix2D(
c,
s,
-s,
c,
center.x - center.x * c + center.y * s,
center.y - center.y * c - center.x * s
);
}
/**
* rotation
*
* @param {Number} radians
* @returns {Matrix2D}
*/
Matrix2D.rotation = function(radians) {
let c = Math.cos(radians);
let s = Math.sin(radians);
/**
* rotationFromVector
*
* @param {module:kld-affine.Vector2D} vector
* @returns {module:kld-affine.Matrix2D}
*/
static rotationFromVector(vector) {
const unit = vector.unit();
const c = unit.x; // cos
const s = unit.y; // sin
return new Matrix2D(c, s, -s, c, 0, 0);
};
return new Matrix2D(c, s, -s, c, 0, 0);
}
/**
* rotationAt
*
* @param {Number} radians
* @param {Point2D} center
* @returns {Matrix2D}
*/
Matrix2D.rotationAt = function(radians, center) {
let c = Math.cos(radians);
let s = Math.sin(radians);
/**
* xFlip
*
* @returns {module:kld-affine.Matrix2D}
*/
static xFlip() {
return new Matrix2D(-1, 0, 0, 1, 0, 0);
}
return new Matrix2D(
c,
s,
-s,
c,
center.x - center.x * c + center.y * s,
center.y - center.y * c - center.x * s
);
};
/**
* yFlip
*
* @returns {module:kld-affine.Matrix2D}
*/
static yFlip() {
return new Matrix2D(1, 0, 0, -1, 0, 0);
}
/**
* rotationFromVector
*
* @param {Vector2D}
* @returns {Matrix2D}
*/
Matrix2D.rotationFromVector = function(vector) {
var unit = vector.unit();
var c = unit.x; // cos
var s = unit.y; // sin
/**
* xSkew
*
* @param {number} radians
* @returns {module:kld-affine.Matrix2D}
*/
static xSkew(radians) {
const t = Math.tan(radians);
return new Matrix2D(c, s, -s, c, 0, 0);
};
return new Matrix2D(1, 0, t, 1, 0, 0);
}
/**
* xFlip
*
* @returns {Matrix2D}
*/
Matrix2D.xFlip = function() {
return new Matrix2D(-1, 0, 0, 1, 0, 0);
};
/**
* ySkew
*
* @param {number} radians
* @returns {module:kld-affine.Matrix2D}
*/
static ySkew(radians) {
const t = Math.tan(radians);
/**
* yFlip
*
* @returns {Matrix2D}
*/
Matrix2D.yFlip = function() {
return new Matrix2D(1, 0, 0, -1, 0, 0);
};
return new Matrix2D(1, t, 0, 1, 0, 0);
}
/**
* xSkew
*
* @param {Number} radians
* @returns {Matrix2D}
*/
Matrix2D.xSkew = function(radians) {
var t = Math.tan(radians);
/**
* multiply
*
* @param {module:kld-affine.Matrix2D} that
* @returns {module:kld-affine.Matrix2D}
*/
multiply(that) {
if (this.isIdentity()) {
return that;
}
return new Matrix2D(1, 0, t, 1, 0, 0);
};
if (that.isIdentity()) {
return this;
}
/**
* ySkew
*
* @param {Number} radians
* @returns {Matrix2D}
*/
Matrix2D.ySkew = function(radians) {
var t = Math.tan(radians);
return new this.constructor(
this.a * that.a + this.c * that.b,
this.b * that.a + this.d * that.b,
this.a * that.c + this.c * that.d,
this.b * that.c + this.d * that.d,
this.a * that.e + this.c * that.f + this.e,
this.b * that.e + this.d * that.f + this.f
);
}
return new Matrix2D(1, t, 0, 1, 0, 0);
};
/**
* inverse
*
* @returns {module:kld-affine.Matrix2D}
*/
inverse() {
if (this.isIdentity()) {
return this;
}
const det1 = this.a * this.d - this.b * this.c;
// *** METHODS
if (det1 === 0.0) {
throw new Error("Matrix is not invertible");
}
/**
* multiply
*
* @pararm {Matrix2D} that
* @returns {Matrix2D}
*/
Matrix2D.prototype.multiply = function (that) {
if (this.isIdentity()) {
return that;
const idet = 1.0 / det1;
const det2 = this.f * this.c - this.e * this.d;
const det3 = this.e * this.b - this.f * this.a;
return new this.constructor(
this.d * idet,
-this.b * idet,
-this.c * idet,
this.a * idet,
det2 * idet,
det3 * idet
);
}
if (that.isIdentity()) {
return this;
/**
* translate
*
* @param {number} tx
* @param {number} ty
* @returns {module:kld-affine.Matrix2D}
*/
translate(tx, ty) {
return new this.constructor(
this.a,
this.b,
this.c,
this.d,
this.a * tx + this.c * ty + this.e,
this.b * tx + this.d * ty + this.f
);
}
return new this.constructor(
this.a * that.a + this.c * that.b,
this.b * that.a + this.d * that.b,
this.a * that.c + this.c * that.d,
this.b * that.c + this.d * that.d,
this.a * that.e + this.c * that.f + this.e,
this.b * that.e + this.d * that.f + this.f
);
};
/**
* inverse
*
* @returns {Matrix2D}
*/
Matrix2D.prototype.inverse = function () {
if (this.isIdentity()) {
return this;
/**
* scale
*
* @param {number} scale
* @returns {module:kld-affine.Matrix2D}
*/
scale(scale) {
return new this.constructor(
this.a * scale,
this.b * scale,
this.c * scale,
this.d * scale,
this.e,
this.f
);
}
var det1 = this.a * this.d - this.b * this.c;
/**
* scaleAt
*
* @param {number} scale
* @param {module:kld-affine.Point2D} center
* @returns {module:kld-affine.Matrix2D}
*/
scaleAt(scale, center) {
const dx = center.x - scale * center.x;
const dy = center.y - scale * center.y;
if ( det1 === 0.0 ) {
throw("Matrix is not invertible");
return new this.constructor(
this.a * scale,
this.b * scale,
this.c * scale,
this.d * scale,
this.a * dx + this.c * dy + this.e,
this.b * dx + this.d * dy + this.f
);
}
var idet = 1.0 / det1;
var det2 = this.f * this.c - this.e * this.d;
var det3 = this.e * this.b - this.f * this.a;
/**
* scaleNonUniform
*
* @param {number} scaleX
* @param {number} scaleY
* @returns {module:kld-affine.Matrix2D}
*/
scaleNonUniform(scaleX, scaleY) {
return new this.constructor(
this.a * scaleX,
this.b * scaleX,
this.c * scaleY,
this.d * scaleY,
this.e,
this.f
);
}
return new this.constructor(
this.d * idet,
-this.b * idet,
-this.c * idet,
this.a * idet,
det2 * idet,
det3 * idet
);
};
/**
* scaleNonUniformAt
*
* @param {number} scaleX
* @param {number} scaleY
* @param {module:kld-affine.Point2D} center
* @returns {module:kld-affine.Matrix2D}
*/
scaleNonUniformAt(scaleX, scaleY, center) {
const dx = center.x - scaleX * center.x;
const dy = center.y - scaleY * center.y;
/**
* translate
*
* @param {Number} tx
* @param {Number} ty
* @returns {Matrix2D}
*/
Matrix2D.prototype.translate = function(tx, ty) {
return new this.constructor(
this.a,
this.b,
this.c,
this.d,
this.a * tx + this.c * ty + this.e,
this.b * tx + this.d * ty + this.f
);
};
return new this.constructor(
this.a * scaleX,
this.b * scaleX,
this.c * scaleY,
this.d * scaleY,
this.a * dx + this.c * dy + this.e,
this.b * dx + this.d * dy + this.f
);
}
/**
* scale
*
* @param {Number} scale
* @returns {Matrix2D}
*/
Matrix2D.prototype.scale = function(scale) {
return new this.constructor(
this.a * scale,
this.b * scale,
this.c * scale,
this.d * scale,
this.e,
this.f
);
};
/**
* rotate
*
* @param {number} radians
* @returns {module:kld-affine.Matrix2D}
*/
rotate(radians) {
const c = Math.cos(radians);
const s = Math.sin(radians);
/**
* scaleAt
*
* @param {Number} scale
* @param {Point2D} center
* @returns {Matrix2D}
*/
Matrix2D.prototype.scaleAt = function(scale, center) {
var dx = center.x - scale * center.x;
var dy = center.y - scale * center.y;
return new this.constructor(
this.a * c + this.c * s,
this.b * c + this.d * s,
this.a * -s + this.c * c,
this.b * -s + this.d * c,
this.e,
this.f
);
}
return new this.constructor(
this.a * scale,
this.b * scale,
this.c * scale,
this.d * scale,
this.a * dx + this.c * dy + this.e,
this.b * dx + this.d * dy + this.f
);
};
/**
* rotateAt
*
* @param {number} radians
* @param {module:kld-affine.Point2D} center
* @returns {module:kld-affine.Matrix2D}
*/
rotateAt(radians, center) {
const cos = Math.cos(radians);
const sin = Math.sin(radians);
const cx = center.x;
const cy = center.y;
/**
* scaleNonUniform
*
* @param {Number} scaleX
* @param {Number} scaleY
* @returns {Matrix2D}
*/
Matrix2D.prototype.scaleNonUniform = function(scaleX, scaleY) {
return new this.constructor(
this.a * scaleX,
this.b * scaleX,
this.c * scaleY,
this.d * scaleY,
this.e,
this.f
);
};
const a = this.a * cos + this.c * sin;
const b = this.b * cos + this.d * sin;
const c = this.c * cos - this.a * sin;
const d = this.d * cos - this.b * sin;
/**
* scaleNonUniformAt
*
* @param {Number} scaleX
* @param {Number} scaleY
* @param {Point2D} center
* @returns {Matrix2D}
*/
Matrix2D.prototype.scaleNonUniformAt = function(scaleX, scaleY, center) {
var dx = center.x - scaleX * center.x;
var dy = center.y - scaleY * center.y;
return new this.constructor(
a,
b,
c,
d,
(this.a - a) * cx + (this.c - c) * cy + this.e,
(this.b - b) * cx + (this.d - d) * cy + this.f
);
}
return new this.constructor(
this.a * scaleX,
this.b * scaleX,
this.c * scaleY,
this.d * scaleY,
this.a * dx + this.c * dy + this.e,
this.b * dx + this.d * dy + this.f
);
};
/**
* rotateFromVector
*
* @param {module:kld-affine.Vector2D} vector
* @returns {module:kld-affine.Matrix2D}
*/
rotateFromVector(vector) {
const unit = vector.unit();
const c = unit.x; // cos
const s = unit.y; // sin
/**
* rotate
*
* @param {Number} radians
* @returns {Matrix2D}
*/
Matrix2D.prototype.rotate = function(radians) {
var c = Math.cos(radians);
var s = Math.sin(radians);
return new this.constructor(
this.a * c + this.c * s,
this.b * c + this.d * s,
this.a * -s + this.c * c,
this.b * -s + this.d * c,
this.e,
this.f
);
}
return new this.constructor(
this.a * c + this.c * s,
this.b * c + this.d * s,
this.a * -s + this.c * c,
this.b * -s + this.d * c,
this.e,
this.f
);
};
/**
* flipX
*
* @returns {module:kld-affine.Matrix2D}
*/
flipX() {
return new this.constructor(
-this.a,
-this.b,
this.c,
this.d,
this.e,
this.f
);
}
/**
* rotateAt
*
* @param {Number} radians
* @param {Point2D} center
* @result {Matrix2D}
*/
Matrix2D.prototype.rotateAt = function(radians, center) {
var cos = Math.cos(radians);
var sin = Math.sin(radians);
var cx = center.x;
var cy = center.y;
/**
* flipY
*
* @returns {module:kld-affine.Matrix2D}
*/
flipY() {
return new this.constructor(
this.a,
this.b,
-this.c,
-this.d,
this.e,
this.f
);
}
var a = this.a * cos + this.c * sin;
var b = this.b * cos + this.d * sin;
var c = this.c * cos - this.a * sin;
var d = this.d * cos - this.b * sin;
/**
* skewX
*
* @param {number} radians
* @returns {module:kld-affine.Matrix2D}
*/
skewX(radians) {
const t = Math.tan(radians);
return new this.constructor(
a,
b,
c,
d,
(this.a - a) * cx + (this.c - c) * cy + this.e,
(this.b - b) * cx + (this.d - d) * cy + this.f
);
};
return new this.constructor(
this.a,
this.b,
this.c + this.a * t,
this.d + this.b * t,
this.e,
this.f
);
}
/**
* rotateFromVector
*
* @param {Vector2D}
* @returns {Matrix2D}
*/
Matrix2D.prototype.rotateFromVector = function(vector) {
var unit = vector.unit();
var c = unit.x; // cos
var s = unit.y; // sin
// TODO: skewXAt
return new this.constructor(
this.a * c + this.c * s,
this.b * c + this.d * s,
this.a * -s + this.c * c,
this.b * -s + this.d * c,
this.e,
this.f
);
};
/**
* skewY
*
* @param {number} radians
* @returns {module:kld-affine.Matrix2D}
*/
skewY(radians) {
const t = Math.tan(radians);
/**
* flipX
*
* @returns {Matrix2D}
*/
Matrix2D.prototype.flipX = function() {
return new this.constructor(
-this.a,
-this.b,
this.c,
this.d,
this.e,
this.f
);
};
return new this.constructor(
this.a + this.c * t,
this.b + this.d * t,
this.c,
this.d,
this.e,
this.f
);
}
/**
* flipY
*
* @returns {Matrix2D}
*/
Matrix2D.prototype.flipY = function() {
return new this.constructor(
this.a,
this.b,
-this.c,
-this.d,
this.e,
this.f
);
};
// TODO: skewYAt
/**
* skewX
*
* @pararm {Number} radians
* @returns {Matrix2D}
*/
Matrix2D.prototype.skewX = function(radians) {
var t = Math.tan(radians);
/**
* isIdentity
*
* @returns {boolean}
*/
isIdentity() {
return (
this.a === 1.0 &&
this.b === 0.0 &&
this.c === 0.0 &&
this.d === 1.0 &&
this.e === 0.0 &&
this.f === 0.0
);
}
return new this.constructor(
this.a,
this.b,
this.c + this.a * t,
this.d + this.b * t,
this.e,
this.f
);
};
/**
* isInvertible
*
* @returns {boolean}
*/
isInvertible() {
return this.a * this.d - this.b * this.c !== 0.0;
}
// TODO: skewXAt
/**
* getScale
*
* @returns {{ scaleX: number, scaleY: number }}
*/
getScale() {
return {
scaleX: Math.sqrt(this.a * this.a + this.c * this.c),
scaleY: Math.sqrt(this.b * this.b + this.d * this.d)
};
}
/**
* skewY
*
* @pararm {Number} radians
* @returns {Matrix2D}
*/
Matrix2D.prototype.skewY = function(radians) {
var t = Math.tan(radians);
/**
* getDecomposition
*
* Calculates matrix Singular Value Decomposition
*
* The resulting matrices, translation, rotation, scale, and rotation0, return
* this matrix when they are muliplied together in the listed order
*
* @see Jim Blinn's article {@link http://dx.doi.org/10.1109/38.486688}
* @see {@link http://math.stackexchange.com/questions/861674/decompose-a-2d-arbitrary-transform-into-only-scaling-and-rotation}
*
* @returns {{ translation: module:kld-affine.Matrix2D, rotation: module:kld-affine.Matrix2D, scale: module:kld-affine.Matrix2D, rotation0: module:kld-affine.Matrix2D }}
*/
getDecomposition() {
const E = (this.a + this.d) * 0.5;
const F = (this.a - this.d) * 0.5;
const G = (this.b + this.c) * 0.5;
const H = (this.b - this.c) * 0.5;
return new this.constructor(
this.a + this.c * t,
this.b + this.d * t,
this.c,
this.d,
this.e,
this.f
);
};
const Q = Math.sqrt(E * E + H * H);
const R = Math.sqrt(F * F + G * G);
const scaleX = Q + R;
const scaleY = Q - R;
// TODO: skewYAt
const a1 = Math.atan2(G, F);
const a2 = Math.atan2(H, E);
const theta = (a2 - a1) * 0.5;
const phi = (a2 + a1) * 0.5;
/**
* isIdentity
*
* @returns {Boolean}
*/
Matrix2D.prototype.isIdentity = function() {
return (
this.a === 1.0 &&
this.b === 0.0 &&
this.c === 0.0 &&
this.d === 1.0 &&
this.e === 0.0 &&
this.f === 0.0
);
};
return {
translation: this.constructor.translation(this.e, this.f),
rotation: this.constructor.rotation(phi),
scale: this.constructor.nonUniformScaling(scaleX, scaleY),
rotation0: this.constructor.rotation(theta)
};
}
/**
* isInvertible
*
* @returns {Boolean}
*/
Matrix2D.prototype.isInvertible = function() {
return this.a * this.d - this.b * this.c !== 0.0;
};
/**
* equals
*
* @param {module:kld-affine.Matrix2D} that
* @returns {boolean}
*/
equals(that) {
return (
this.a === that.a &&
this.b === that.b &&
this.c === that.c &&
this.d === that.d &&
this.e === that.e &&
this.f === that.f
);
}
/**
* getScale
*
* @returns {{ scaleX: Number, scaleY: Number }}
*/
Matrix2D.prototype.getScale = function() {
return {
scaleX: Math.sqrt(this.a * this.a + this.c * this.c),
scaleY: Math.sqrt(this.b * this.b + this.d * this.d)
};
};
/**
* precisionEquals
*
* @param {module:kld-affine.Matrix2D} that
* @param {number} precision
* @returns {boolean}
*/
precisionEquals(that, precision) {
return (
Math.abs(this.a - that.a) < precision &&
Math.abs(this.b - that.b) < precision &&
Math.abs(this.c - that.c) < precision &&
Math.abs(this.d - that.d) < precision &&
Math.abs(this.e - that.e) < precision &&
Math.abs(this.f - that.f) < precision
);
}
/**
* getDecomposition
*
* Calculates matrix Singular Value Decomposition
*
* The resulting matrices, translation, rotation, scale, and rotation0, return
* this matrix when they are muliplied together in the listed order
*
* @see Jim Blinn's article {@link http://dx.doi.org/10.1109/38.486688}
* @see {@link http://math.stackexchange.com/questions/861674/decompose-a-2d-arbitrary-transform-into-only-scaling-and-rotation}
*
* @returns {{ translation: Matrix2D, rotation: Matrix2D, scale: Matrix2D, rotation0: Matrix2D }}
*/
Matrix2D.prototype.getDecomposition = function () {
var E = (this.a + this.d) * 0.5;
var F = (this.a - this.d) * 0.5;
var G = (this.b + this.c) * 0.5;
var H = (this.b - this.c) * 0.5;
/**
* toString
*
* @returns {string}
*/
toString() {
return "matrix(" + [this.a, this.b, this.c, this.d, this.e, this.f].join(",") + ")";
}
}
var Q = Math.sqrt(E * E + H * H);
var R = Math.sqrt(F * F + G * G);
var scaleX = Q + R;
var scaleY = Q - R;
var a1 = Math.atan2(G, F);
var a2 = Math.atan2(H, E);
var theta = (a2 - a1) * 0.5;
var phi = (a2 + a1) * 0.5;
// TODO: Add static methods to generate translation, rotation, etc.
// matrices directly
return {
translation: new this.constructor(1, 0, 0, 1, this.e, this.f),
rotation: this.constructor.IDENTITY.rotate(phi),
scale: new this.constructor(scaleX, 0, 0, scaleY, 0, 0),
rotation0: this.constructor.IDENTITY.rotate(theta)
};
};
/**
* equals
* Identity matrix
*
* @param {Matrix2D} that
* @returns {Boolean}
* @returns {module:kld-affine.Matrix2D}
*/
Matrix2D.prototype.equals = function(that) {
return (
this.a === that.a &&
this.b === that.b &&
this.c === that.c &&
this.d === that.d &&
this.e === that.e &&
this.f === that.f
);
};
Matrix2D.IDENTITY = new Matrix2D();
Matrix2D.IDENTITY.isIdentity = () => true;
/**
* precisionEquals
*
* @param {Matrix2D} that
* @param {Number} precision
* @returns {Boolean}
*/
Matrix2D.prototype.precisionEquals = function(that, precision) {
return (
Math.abs(this.a - that.a) < precision &&
Math.abs(this.b - that.b) < precision &&
Math.abs(this.c - that.c) < precision &&
Math.abs(this.d - that.d) < precision &&
Math.abs(this.e - that.e) < precision &&
Math.abs(this.f - that.f) < precision
);
};
/**
* toString
*
* @returns {String}
*/
Matrix2D.prototype.toString = function() {
return "matrix(" + [this.a, this.b, this.c, this.d, this.e, this.f].join(",") + ")";
};
if (typeof module !== "undefined") {
module.exports = Matrix2D;
}
export default Matrix2D;
/**
*
* Point2D.js
*
* copyright 2001-2002, 2013, 2017 Kevin Lindsey
*
* Point2D.js
* @module Point2D
* @copyright 2001-2019 Kevin Lindsey
*/

@@ -12,177 +10,170 @@

*
* @param {Number} x
* @param {Number} y
* @returns {Point2D}
* @memberof module:kld-affine
*/
function Point2D(x, y) {
Object.defineProperties(this, {
"x": {
value: x !== undefined ? x : 0.0,
writable: false,
enumerable: true,
configurable: false
},
"y": {
value: y !== undefined ? y : 0.0,
writable: false,
enumerable: true,
configurable: false
}
});
}
class Point2D {
/**
* Point2D
*
* @param {number} x
* @param {number} y
* @returns {module:kld-affine.Point2D}
*/
constructor(x, y) {
this.x = x !== undefined ? x : 0.0;
this.y = y !== undefined ? y : 0.0;
}
/**
* clone
*
* @returns {Point2D}
*/
Point2D.prototype.clone = function() {
return new this.constructor(this.x, this.y);
};
/**
* clone
*
* @returns {module:kld-affine.Point2D}
*/
clone() {
return new this.constructor(this.x, this.y);
}
/**
* add
*
* @param {Point2D|Vector2D} that
* @returns {Point2D}
*/
Point2D.prototype.add = function(that) {
return new this.constructor(this.x+that.x, this.y+that.y);
};
/**
* add
*
* @param {Point2D|Vector2D} that
* @returns {module:kld-affine.Point2D}
*/
add(that) {
return new this.constructor(this.x + that.x, this.y + that.y);
}
/**
* subtract
*
* @param { Vector2D | Point2D } that
* @returns {Point2D}
*/
Point2D.prototype.subtract = function(that) {
return new this.constructor(this.x-that.x, this.y-that.y);
};
/**
* subtract
*
* @param { Vector2D | Point2D } that
* @returns {module:kld-affine.Point2D}
*/
subtract(that) {
return new this.constructor(this.x - that.x, this.y - that.y);
}
/**
* multiply
*
* @param {Number} scalar
* @returns {Point2D}
*/
Point2D.prototype.multiply = function(scalar) {
return new this.constructor(this.x*scalar, this.y*scalar);
};
/**
* multiply
*
* @param {number} scalar
* @returns {module:kld-affine.Point2D}
*/
multiply(scalar) {
return new this.constructor(this.x * scalar, this.y * scalar);
}
/**
* divide
*
* @param {Number} scalar
* @returns {Point2D}
*/
Point2D.prototype.divide = function(scalar) {
return new this.constructor(this.x/scalar, this.y/scalar);
};
/**
* divide
*
* @param {number} scalar
* @returns {module:kld-affine.Point2D}
*/
divide(scalar) {
return new this.constructor(this.x / scalar, this.y / scalar);
}
/**
* equals
*
* @param {Point2D} that
* @returns {Boolean}
*/
Point2D.prototype.equals = function(that) {
return ( this.x === that.x && this.y === that.y );
};
/**
* equals
*
* @param {module:kld-affine.Point2D} that
* @returns {boolean}
*/
equals(that) {
return (this.x === that.x && this.y === that.y);
}
/**
* precisionEquals
*
* @param {Point2D} that
* @param {Number} precision
* @returns {Boolean}
*/
Point2D.prototype.precisionEquals = function(that, precision) {
return (
Math.abs(this.x - that.x) < precision &&
Math.abs(this.y - that.y) < precision
);
};
/**
* precisionEquals
*
* @param {module:kld-affine.Point2D} that
* @param {number} precision
* @returns {boolean}
*/
precisionEquals(that, precision) {
return (
Math.abs(this.x - that.x) < precision &&
Math.abs(this.y - that.y) < precision
);
}
// utility methods
// utility methods
/**
* lerp
*
* @param { Vector2D | Point2D } that
* @param {Number} t
@ @returns {Point2D}
*/
Point2D.prototype.lerp = function(that, t) {
var omt = 1.0 - t;
/**
* lerp
*
* @param {module:kld-affine.Point2D} that
* @param {number} t
* @returns {module:kld-affine.Point2D}
*/
lerp(that, t) {
const omt = 1.0 - t;
return new this.constructor(
this.x * omt + that.x * t,
this.y * omt + that.y * t
);
};
return new this.constructor(
this.x * omt + that.x * t,
this.y * omt + that.y * t
);
}
/**
* distanceFrom
*
* @param {Point2D} that
* @returns {Number}
*/
Point2D.prototype.distanceFrom = function(that) {
var dx = this.x - that.x;
var dy = this.y - that.y;
/**
* distanceFrom
*
* @param {module:kld-affine.Point2D} that
* @returns {number}
*/
distanceFrom(that) {
const dx = this.x - that.x;
const dy = this.y - that.y;
return Math.sqrt(dx*dx + dy*dy);
};
return Math.sqrt(dx * dx + dy * dy);
}
/**
* min
*
* @param {Point2D} that
* @returns {Number}
*/
Point2D.prototype.min = function(that) {
return new this.constructor(
Math.min( this.x, that.x ),
Math.min( this.y, that.y )
);
};
/**
* min
*
* @param {module:kld-affine.Point2D} that
* @returns {number}
*/
min(that) {
return new this.constructor(
Math.min(this.x, that.x),
Math.min(this.y, that.y)
);
}
/**
* max
*
* @param {Point2D} that
* @returns {Number}
*/
Point2D.prototype.max = function(that) {
return new this.constructor(
Math.max( this.x, that.x ),
Math.max( this.y, that.y )
);
};
/**
* max
*
* @param {module:kld-affine.Point2D} that
* @returns {number}
*/
max(that) {
return new this.constructor(
Math.max(this.x, that.x),
Math.max(this.y, that.y)
);
}
/**
* transform
*
* @param {Matrix2D}
* @result {Point2D}
*/
Point2D.prototype.transform = function(matrix) {
return new this.constructor(
matrix.a * this.x + matrix.c * this.y + matrix.e,
matrix.b * this.x + matrix.d * this.y + matrix.f
);
};
/**
* transform
*
* @param {module:kld-affine.Matrix2D} matrix
* @returns {module:kld-affine.Point2D}
*/
transform(matrix) {
return new this.constructor(
matrix.a * this.x + matrix.c * this.y + matrix.e,
matrix.b * this.x + matrix.d * this.y + matrix.f
);
}
/**
* toString
*
* @returns {String}
*/
Point2D.prototype.toString = function() {
return "point(" + this.x + "," + this.y + ")";
};
/**
* toString
*
* @returns {string}
*/
toString() {
return "point(" + this.x + "," + this.y + ")";
}
}
if (typeof module !== "undefined") {
module.exports = Point2D;
}
export default Point2D;
/**
*
* Vector2D.js
*
* copyright 2001-2002, 2013, 2017 Kevin Lindsey
*
* Vector2D.js
* @module Vector2D
* @copyright 2001-2019 Kevin Lindsey
*/

@@ -12,231 +10,224 @@

*
* @param {Number} x
* @param {Number} y
* @returns {Vector2D}
* @memberof module:kld-affine
*/
function Vector2D(x, y) {
Object.defineProperties(this, {
"x": {
value: x !== undefined ? x : 0.0,
writable: false,
enumerable: true,
configurable: false
},
"y": {
value: y !== undefined ? y : 0.0,
writable: false,
enumerable: true,
configurable: false
}
});
}
class Vector2D {
/**
* Vector2D
*
* @param {number} x
* @param {number} y
* @returns {module:kld-affine.Vector2D}
*/
constructor(x, y) {
this.x = x !== undefined ? x : 0.0;
this.y = y !== undefined ? y : 0.0;
}
/**
* fromPoints
*
* @param {Point2D} p1
* @param {Point2D} p2
* @returns {Vector2D}
*/
Vector2D.fromPoints = function(p1, p2) {
return new Vector2D(
p2.x - p1.x,
p2.y - p1.y
);
};
/**
* fromPoints
*
* @param {module:kld-affine.Point2D} p1
* @param {module:kld-affine.Point2D} p2
* @returns {module:kld-affine.Vector2D}
*/
static fromPoints(p1, p2) {
return new Vector2D(
p2.x - p1.x,
p2.y - p1.y
);
}
/**
* length
*
* @returns {Number}
*/
Vector2D.prototype.length = function() {
return Math.sqrt(this.x*this.x + this.y*this.y);
};
/**
* length
*
* @returns {number}
*/
length() {
return Math.sqrt(this.x * this.x + this.y * this.y);
}
/**
* magnitude
*
* @returns {Number}
*/
Vector2D.prototype.magnitude = function() {
return this.x*this.x + this.y*this.y;
};
/**
* magnitude
*
* @returns {number}
*/
magnitude() {
return this.x * this.x + this.y * this.y;
}
/**
* dot
*
* @param {Vector2D} that
* @returns {Number}
*/
Vector2D.prototype.dot = function(that) {
return this.x*that.x + this.y*that.y;
};
/**
* dot
*
* @param {module:kld-affine.Vector2D} that
* @returns {number}
*/
dot(that) {
return this.x * that.x + this.y * that.y;
}
/**
* cross
*
* @param {Vector2D} that
* @returns {Number}
*/
Vector2D.prototype.cross = function(that) {
return this.x*that.y - this.y*that.x;
};
/**
* cross
*
* @param {module:kld-affine.Vector2D} that
* @returns {number}
*/
cross(that) {
return this.x * that.y - this.y * that.x;
}
/**
* determinant
*
* @param {Vector2D} that
* @returns {Number}
*/
Vector2D.prototype.determinant = function(that) {
return this.x*that.y - this.y*that.x;
};
/**
* determinant
*
* @param {module:kld-affine.Vector2D} that
* @returns {number}
*/
determinant(that) {
return this.x * that.y - this.y * that.x;
}
/**
* unit
*
* @returns {Vector2D}
*/
Vector2D.prototype.unit = function() {
return this.divide( this.length() );
};
/**
* unit
*
* @returns {module:kld-affine.Vector2D}
*/
unit() {
return this.divide(this.length());
}
/**
* add
*
* @param {Vector2D} that
* @returns {Vector2D}
*/
Vector2D.prototype.add = function(that) {
return new this.constructor(this.x + that.x, this.y + that.y);
};
/**
* add
*
* @param {module:kld-affine.Vector2D} that
* @returns {module:kld-affine.Vector2D}
*/
add(that) {
return new this.constructor(this.x + that.x, this.y + that.y);
}
/**
* subtract
*
* @param {Vector2D} that
* @returns {Vector2D}
*/
Vector2D.prototype.subtract = function(that) {
return new this.constructor(this.x - that.x, this.y - that.y);
};
/**
* subtract
*
* @param {module:kld-affine.Vector2D} that
* @returns {module:kld-affine.Vector2D}
*/
subtract(that) {
return new this.constructor(this.x - that.x, this.y - that.y);
}
/**
* multiply
*
* @param {Number} scalar
* @returns {Vector2D}
*/
Vector2D.prototype.multiply = function(scalar) {
return new this.constructor(this.x * scalar, this.y * scalar);
};
/**
* multiply
*
* @param {number} scalar
* @returns {module:kld-affine.Vector2D}
*/
multiply(scalar) {
return new this.constructor(this.x * scalar, this.y * scalar);
}
/**
* divide
*
* @param {Number} scalar
* @returns {Vector2D}
*/
Vector2D.prototype.divide = function(scalar) {
return new this.constructor(this.x / scalar, this.y / scalar);
};
/**
* divide
*
* @param {number} scalar
* @returns {module:kld-affine.Vector2D}
*/
divide(scalar) {
return new this.constructor(this.x / scalar, this.y / scalar);
}
/**
* angleBetween
*
* @param {Vector2D} that
* @returns {Number}
*/
Vector2D.prototype.angleBetween = function(that) {
var cos = this.dot(that) / (this.length() * that.length());
cos = Math.max(-1, Math.min(cos, 1));
var radians = Math.acos(cos);
/**
* angleBetween
*
* @param {module:kld-affine.Vector2D} that
* @returns {number}
*/
angleBetween(that) {
let cos = this.dot(that) / (this.length() * that.length());
cos = Math.max(-1, Math.min(cos, 1));
const radians = Math.acos(cos);
return (this.cross(that) < 0.0) ? -radians : radians;
};
return (this.cross(that) < 0.0) ? -radians : radians;
}
/**
* Find a vector is that is perpendicular to this vector
*
* @returns {Vector2D}
*/
Vector2D.prototype.perp = function() {
return new this.constructor(-this.y, this.x);
};
/**
* Find a vector is that is perpendicular to this vector
*
* @returns {module:kld-affine.Vector2D}
*/
perp() {
return new this.constructor(-this.y, this.x);
}
/**
* Find the component of the specified vector that is perpendicular to
* this vector
*
* @param {Vector2D} that
* @returns {Vector2D}
*/
Vector2D.prototype.perpendicular = function(that) {
return this.subtract(this.project(that));
};
/**
* Find the component of the specified vector that is perpendicular to
* this vector
*
* @param {module:kld-affine.Vector2D} that
* @returns {module:kld-affine.Vector2D}
*/
perpendicular(that) {
return this.subtract(this.project(that));
}
/**
* project
*
* @param {Vector2D} that
* @returns {Vector2D}
*/
Vector2D.prototype.project = function(that) {
var percent = this.dot(that) / that.dot(that);
/**
* project
*
* @param {module:kld-affine.Vector2D} that
* @returns {module:kld-affine.Vector2D}
*/
project(that) {
const percent = this.dot(that) / that.dot(that);
return that.multiply(percent);
};
return that.multiply(percent);
}
/**
* transform
*
* @param {Matrix2D}
* @returns {Vector2D}
*/
Vector2D.prototype.transform = function(matrix) {
return new this.constructor(
matrix.a * this.x + matrix.c * this.y,
matrix.b * this.x + matrix.d * this.y
);
};
/**
* transform
*
* @param {module:kld-affine.Matrix2D} matrix
* @returns {module:kld-affine.Vector2D}
*/
transform(matrix) {
return new this.constructor(
matrix.a * this.x + matrix.c * this.y,
matrix.b * this.x + matrix.d * this.y
);
}
/**
* equals
*
* @param {Vector2D} that
* @returns {Boolean}
*/
Vector2D.prototype.equals = function(that) {
return (
this.x === that.x &&
this.y === that.y
);
};
/**
* equals
*
* @param {module:kld-affine.Vector2D} that
* @returns {boolean}
*/
equals(that) {
return (
this.x === that.x &&
this.y === that.y
);
}
/**
* precisionEquals
*
* @param {Vector2D} that
* @param {Number} precision
* @returns {Boolean}
*/
Vector2D.prototype.precisionEquals = function(that, precision) {
return (
Math.abs(this.x - that.x) < precision &&
Math.abs(this.y - that.y) < precision
);
};
/**
* precisionEquals
*
* @param {module:kld-affine.Vector2D} that
* @param {number} precision
* @returns {boolean}
*/
precisionEquals(that, precision) {
return (
Math.abs(this.x - that.x) < precision &&
Math.abs(this.y - that.y) < precision
);
}
/**
* toString
*
* @returns {String}
*/
Vector2D.prototype.toString = function() {
return "vector(" + this.x + "," + this.y + ")";
};
/**
* toString
*
* @returns {string}
*/
toString() {
return "vector(" + this.x + "," + this.y + ")";
}
}
if (typeof module !== "undefined") {
module.exports = Vector2D;
}
export default Vector2D;
{
"name": "kld-affine",
"version": "2.0.4",
"version": "2.1.0",
"description": "A collection of classes used in affine geometry",

@@ -9,3 +9,8 @@ "author": {

},
"contributors": [
"Brett Zamir"
],
"license": "BSD-3-Clause",
"bugs": "https://github.com/thelonious/kld-affine/issues",
"homepage": "https://github.com/thelonious/kld-affine",
"repository": {

@@ -15,5 +20,14 @@ "type": "git",

},
"main": "index.js",
"main": "dist/index-umd.js",
"module": "index.js",
"browserslist": [
"cover 100%"
],
"scripts": {
"test": "mocha"
"eslint": "eslint .",
"rollup": "rollup -c",
"test": "npm run eslint && npm run rollup && mocha --require @babel/register",
"start": "static -p 8055",
"build-docs": "rm -rf docs/jsdoc/*;jsdoc --pedantic -c docs/jsdoc-config.js .",
"open-docs": "opn http://localhost:8055/docs/jsdoc/ && npm start"
},

@@ -26,8 +40,33 @@ "keywords": [

],
"dependencies": {},
"devDependencies": {
"mocha": "^3.4.2"
"@babel/core": "^7.4.4",
"@babel/preset-env": "^7.4.4",
"@babel/register": "^7.4.4",
"@mysticatea/eslint-plugin": "^10.0.3",
"eslint": "^5.16.0",
"eslint-config-ash-nazg": "^4.0.0",
"eslint-config-standard": "^12.0.0",
"eslint-plugin-compat": "^3.1.1",
"eslint-plugin-eslint-comments": "^3.1.1",
"eslint-plugin-import": "^2.17.2",
"eslint-plugin-jsdoc": "^4.8.3",
"eslint-plugin-markdown": "^1.0.0",
"eslint-plugin-no-use-extend-native": "^0.4.0",
"eslint-plugin-node": "^9.0.1",
"eslint-plugin-promise": "^4.1.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-unicorn": "^8.0.2",
"jsdoc": "^3.6.1",
"mocha": "^6.1.4",
"node-static": "^0.7.11",
"opn-cli": "^4.1.0",
"rollup": "^1.11.3",
"rollup-plugin-babel": "^4.3.2",
"rollup-plugin-terser": "^4.0.4",
"typescript": "^3.4.5"
},
"engines": {
"node": ">= 6.4.0"
"node": ">= 10.15.3"
}
}

@@ -13,3 +13,5 @@ # kld-affine

npm install kld-affine
```
npm install kld-affine
```

@@ -16,0 +18,0 @@ ## Point2D

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc