@bokeh/bokehjs
Version:
Interactive, novel data visualization
149 lines • 3.88 kB
JavaScript
import { equals } from "./eq";
const { sin, cos } = Math;
export class AffineTransform {
a;
b;
c;
d;
e;
f;
static __name__ = "AffineTransform";
constructor(a = 1, b = 0, c = 0, d = 1, e = 0, f = 0) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.e = e;
this.f = f;
}
toString() {
const { a, b, c, d, e, f } = this;
return `matrix(${a}, ${b}, ${c}, ${d}, ${e}, ${f})`;
}
static from_DOMMatrix(matrix) {
const { a, b, c, d, e, f } = matrix;
return new AffineTransform(a, b, c, d, e, f);
}
to_DOMMatrix() {
const { a, b, c, d, e, f } = this;
return new DOMMatrix([a, b, c, d, e, f]);
}
clone() {
const { a, b, c, d, e, f } = this;
return new AffineTransform(a, b, c, d, e, f);
}
[equals](that, cmp) {
return (cmp.eq(this.a, that.a) &&
cmp.eq(this.b, that.b) &&
cmp.eq(this.c, that.c) &&
cmp.eq(this.d, that.d) &&
cmp.eq(this.e, that.e) &&
cmp.eq(this.f, that.f));
}
reset() {
this.a = 1;
this.b = 0;
this.c = 0;
this.d = 1;
this.e = 0;
this.f = 0;
}
get is_identity() {
const { a, b, c, d, e, f } = this;
return a == 1 && b == 0 && c == 0 && d == 1 && e == 0 && f == 0;
}
apply_point(p) {
const [x, y] = this.apply(p.x, p.y);
return { x, y };
}
apply_rect(rect) {
const p0 = this.apply_point(rect.p0);
const p1 = this.apply_point(rect.p1);
const p2 = this.apply_point(rect.p2);
const p3 = this.apply_point(rect.p3);
return { p0, p1, p2, p3 };
}
apply(x, y) {
const { a, b, c, d, e, f } = this;
return [
a * x + c * y + e,
b * x + d * y + f,
];
}
iv_apply(xs, ys) {
const { a, b, c, d, e, f } = this;
const n = xs.length;
for (let i = 0; i < n; i++) {
const x = xs[i];
const y = ys[i];
xs[i] = a * x + c * y + e;
ys[i] = b * x + d * y + f;
}
}
transform(A, B, C, D, E, F) {
const { a, b, c, d, e, f } = this;
this.a = a * A + c * B;
this.c = a * C + c * D;
this.e = a * E + c * F + e;
this.b = b * A + d * B;
this.d = b * C + d * D;
this.f = b * E + d * F + f;
return this;
}
translate(tx, ty) {
return this.transform(1, 0, 0, 1, tx, ty);
}
scale(cx, cy) {
return this.transform(cx, 0, 0, cy, 0, 0);
}
skew(sx, sy) {
return this.transform(1, sy, sx, 1, 0, 0);
}
rotate(angle) {
if (angle == 0) {
return this;
}
const s = sin(angle);
const c = cos(angle);
return this.transform(c, s, -s, c, 0, 0);
}
rotate_ccw(angle) {
return this.rotate(-angle);
}
rotate_around(x, y, angle) {
this.translate(x, y);
this.rotate(angle);
this.translate(-x, -y);
return this;
}
translate_x(tx) {
return this.translate(tx, 0);
}
translate_y(ty) {
return this.translate(0, ty);
}
flip() {
return this.scale(-1, -1);
}
flip_x() {
return this.scale(1, -1);
}
flip_y() {
return this.scale(-1, 1);
}
inverse() {
return AffineTransform.from_DOMMatrix(this.to_DOMMatrix().inverse());
}
}
export function rotate_around(point, center, angle) {
if (angle == 0) {
return point;
}
else {
const tr = new AffineTransform();
tr.rotate_around(center.x, center.y, angle);
const [x, y] = tr.apply(point.x, point.y);
return { x, y };
}
}
//# sourceMappingURL=affine.js.map