@dominicstop/utils
Version:
Yet another event emitter written in typescript.
157 lines (156 loc) • 4.52 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Angle = void 0;
const Point_1 = require("./Point");
class Angle {
constructor(args) {
this.angleUnit = args.angleUnit;
this.angleRawValue = args.angleValue;
}
;
get asValue() {
return {
angleUnit: this.angleUnit,
angleValue: this.angleRawValue,
};
}
;
get radians() {
switch (this.angleUnit) {
case 'degrees':
return this.angleRawValue * (Math.PI / 180);
case 'radians':
return this.angleRawValue;
}
;
}
;
get degrees() {
switch (this.angleUnit) {
case 'degrees':
return this.angleRawValue;
case 'radians':
return this.angleRawValue * (180 / Math.PI);
}
;
}
;
get normalized() {
const normalizedDegrees = this.degrees % 360;
const adj = (() => {
if (normalizedDegrees < 0) {
return 360;
}
;
if (normalizedDegrees > 360) {
return -360;
}
;
return 0;
})();
const normalizedDegreesAdj = normalizedDegrees + adj;
return new Angle({
angleUnit: 'degrees',
angleValue: normalizedDegreesAdj,
});
}
;
get isZero() {
return this.angleRawValue == 0;
}
;
clone() {
return new Angle({
...this.asValue,
});
}
;
getPointAlongCircle(args) {
const angleRadians = this.radians;
const adjustedAngle = args.isClockwise ? -angleRadians : angleRadians;
/// cw: `x = r * cos(angle)`, `y = r * sin(angle)`
const x = args.centerPoint.x + args.radius * Math.cos(adjustedAngle);
const y = args.centerPoint.y + args.radius * Math.sin(adjustedAngle);
return new Point_1.Point({ x, y });
}
;
computeMidAngle(args) {
const isClockwise = args.isClockwise ?? true;
const angleLeading = this.normalized.degrees;
const angleTrailing = args.otherAngle.normalized.degrees;
const delta = angleLeading - angleTrailing;
const needsAdj = isClockwise
? delta > 0
: delta < 0;
// amount to shift ccw direction
const adj = (() => {
if (needsAdj) {
return 0;
}
;
return Math.abs(delta) / 2;
})();
const angleMidDeg = (() => {
if (adj == 0) {
return (angleLeading + angleTrailing) / 2;
}
;
// adjust by shifting counter clockwise
const angleLeadingShifted = new Angle({
angleUnit: 'degrees',
angleValue: angleLeading + adj,
});
const angleTrailingShifted = new Angle({
angleUnit: 'degrees',
angleValue: angleTrailing + adj,
});
// normalized to 0...360
let angleLeadingNormalized = angleLeadingShifted.normalized.degrees;
let angleTrailingNormalized = angleTrailingShifted.normalized.degrees;
let angleMidShifted = (angleLeadingNormalized + angleTrailingNormalized) / 2;
// undo shifting
return angleMidShifted - adj;
})();
return new Angle({
angleUnit: 'degrees',
angleValue: angleMidDeg,
});
}
;
addOtherAngle(otherAngle) {
return Angle.addTwoAngles(this, otherAngle);
}
;
// MARK: - Static Init
// -------------------
static initFromDegrees(degreeValue) {
return new Angle({
angleUnit: 'degrees',
angleValue: degreeValue,
});
}
;
static initFromRadians(radianValue) {
return new Angle({
angleUnit: 'radians',
angleValue: radianValue,
});
}
;
static addTwoAngles(angleA, angleB) {
if (angleA.angleUnit === angleB.angleUnit) {
return new Angle({
angleUnit: angleA.angleUnit,
angleValue: angleA.angleRawValue + angleB.angleRawValue,
});
}
;
return new Angle({
angleUnit: 'degrees',
angleValue: angleA.degrees + angleB.degrees,
});
}
;
}
exports.Angle = Angle;
;