Files
dotfiles/.config/quickshell/nucleus-shell/modules/components/morphedPolygons/geometry/offset.js

178 lines
3.5 KiB
JavaScript

.pragma library
/**
* @param {number} x
* @param {number} y
* @returns {Offset}
*/
function createOffset(x, y) {
return new Offset(x, y);
}
class Offset {
/**
* @param {number} x
* @param {number} y
*/
constructor(x, y) {
this.x = x;
this.y = y;
}
/**
* @param {number} x
* @param {number} y
* @returns {Offset}
*/
copy(x = this.x, y = this.y) {
return new Offset(x, y);
}
/**
* @returns {number}
*/
getDistance() {
return Math.sqrt(this.x * this.x + this.y * this.y);
}
/**
* @returns {number}
*/
getDistanceSquared() {
return this.x * this.x + this.y * this.y;
}
/**
* @returns {boolean}
*/
isValid() {
return isFinite(this.x) && isFinite(this.y);
}
/**
* @returns {boolean}
*/
get isFinite() {
return isFinite(this.x) && isFinite(this.y);
}
/**
* @returns {boolean}
*/
get isSpecified() {
return !this.isUnspecified;
}
/**
* @returns {boolean}
*/
get isUnspecified() {
return Object.is(this.x, NaN) && Object.is(this.y, NaN);
}
/**
* @returns {Offset}
*/
negate() {
return new Offset(-this.x, -this.y);
}
/**
* @param {Offset} other
* @returns {Offset}
*/
minus(other) {
return new Offset(this.x - other.x, this.y - other.y);
}
/**
* @param {Offset} other
* @returns {Offset}
*/
plus(other) {
return new Offset(this.x + other.x, this.y + other.y);
}
/**
* @param {number} operand
* @returns {Offset}
*/
times(operand) {
return new Offset(this.x * operand, this.y * operand);
}
/**
* @param {number} operand
* @returns {Offset}
*/
div(operand) {
return new Offset(this.x / operand, this.y / operand);
}
/**
* @param {number} operand
* @returns {Offset}
*/
rem(operand) {
return new Offset(this.x % operand, this.y % operand);
}
/**
* @returns {string}
*/
toString() {
if (this.isSpecified) {
return `Offset(${this.x.toFixed(1)}, ${this.y.toFixed(1)})`;
} else {
return 'Offset.Unspecified';
}
}
/**
* @param {Offset} start
* @param {Offset} stop
* @param {number} fraction
* @returns {Offset}
*/
static lerp(start, stop, fraction) {
return new Offset(
start.x + (stop.x - start.x) * fraction,
start.y + (stop.y - start.y) * fraction
);
}
/**
* @param {function(): Offset} block
* @returns {Offset}
*/
takeOrElse(block) {
return this.isSpecified ? this : block();
}
/**
* @returns {number}
*/
angleDegrees() {
return Math.atan2(this.y, this.x) * 180 / Math.PI;
}
/**
* @param {number} angle
* @param {Offset} center
* @returns {Offset}
*/
rotateDegrees(angle, center = Offset.Zero) {
const a = angle * Math.PI / 180;
const off = this.minus(center);
const cosA = Math.cos(a);
const sinA = Math.sin(a);
const newX = off.x * cosA - off.y * sinA;
const newY = off.x * sinA + off.y * cosA;
return new Offset(newX, newY).plus(center);
}
}
Offset.Zero = new Offset(0, 0);
Offset.Infinite = new Offset(Infinity, Infinity);
Offset.Unspecified = new Offset(NaN, NaN);