ootk
Version:
Orbital Object Toolkit including Multiple Propagators, Initial Orbit Determination, and Maneuver Calculations.
184 lines (160 loc) • 5.4 kB
text/typescript
/**
* @author @thkruz Theodore Kruczek
* @license AGPL-3.0-or-later
* @copyright (c) 2025 Kruczek Labs LLC
*
* Orbital Object ToolKit is free software: you can redistribute it and/or modify it under the
* terms of the GNU Affero General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* Orbital Object ToolKit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with
* Orbital Object ToolKit. If not, see <http://www.gnu.org/licenses/>.
*/
import { DEG2RAD, Degrees, Matrix, RAD2DEG, Radians, Vector3D } from '../main.js';
// / Class containing Euler angles.
export class EulerAngles {
// / Roll component _(rad)_.
roll: number;
// / Pitch component _(rad)_.
pitch: number;
// / Yaw component _(rad)_.
yaw: number;
/**
* Create a new EulerAngles object from roll, pitch, and yaw angles in radians.
* @param roll Roll angle in radians.
* @param pitch Pitch angle in radians.
* @param yaw Yaw angle in radians.
*/
constructor(roll: Radians, pitch: Radians, yaw: Radians) {
this.roll = roll;
this.pitch = pitch;
this.yaw = yaw;
}
/**
* Create a new EulerAngles object from roll, pitch, and yaw angles.
* @param rollDeg Roll angle in degrees.
* @param pitchDeg Pitch angle in degrees.
* @param yawDeg Yaw angle in degrees.
* @returns EulerAngles object.
*/
static fromDegrees(rollDeg: Degrees, pitchDeg: Degrees, yawDeg: Degrees): EulerAngles {
const roll = rollDeg * DEG2RAD as Radians;
const pitch = pitchDeg * DEG2RAD as Radians;
const yaw = yawDeg * DEG2RAD as Radians;
return new EulerAngles(roll, pitch, yaw);
}
/**
* Create a new EulerAngles object from 3-2-1 ordered direction cosine matrix c.
* @param c 3-2-1 ordered direction cosine matrix.
* @returns EulerAngles object.
*/
static fromDcm321(c: Matrix): EulerAngles {
const roll = Math.atan(c.elements[1][2] / c.elements[2][2]) as Radians;
const pitch = -Math.asin(c.elements[0][2]) as Radians;
const yaw = Math.atan(c.elements[0][1] / c.elements[0][0]) as Radians;
return new EulerAngles(roll, pitch, yaw);
}
/**
* Gets the roll angle in degrees.
* @returns The roll angle in degrees.
*/
get rollDegrees(): Degrees {
return this.roll * RAD2DEG as Degrees;
}
/**
* Gets the pitch angle in degrees.
* @returns The pitch angle in degrees.
*/
get pitchDegrees(): Degrees {
return this.pitch * RAD2DEG as Degrees;
}
/**
* Gets the yaw angle in degrees.
* @returns The yaw angle in degrees.
*/
get yawDegrees(): Degrees {
return this.yaw * RAD2DEG as Degrees;
}
/**
* Gets the roll angle in radians.
* @returns The roll angle in radians.
*/
get phi(): Radians {
return this.roll as Radians;
}
/**
* Gets the pitch angle in radians.
* @returns The pitch angle in radians.
*/
get theta(): Radians {
return this.pitch as Radians;
}
/**
* Gets the yaw angle in radians.
* @returns The yaw angle in radians.
*/
get psi(): Radians {
return this.yaw as Radians;
}
/**
* Gets the roll component in degrees.
* @returns The roll component in degrees.
*/
get phiDegrees(): Degrees {
return this.phi * RAD2DEG as Degrees;
}
/**
* Gets the pitch component in degrees.
* @returns The pitch component in degrees.
*/
get thetaDegrees(): Degrees {
return this.theta * RAD2DEG as Degrees;
}
/**
* Gets the yaw component in degrees.
* @returns The yaw component in degrees.
*/
get psiDegrees(): Degrees {
return this.psi * RAD2DEG as Degrees;
}
/**
* Returns a string representation of the Euler angles.
* @param precision The number of decimal places to include in the string representation. Default is 6.
* @returns A string representation of the Euler angles.
*/
toString(precision = 6): string {
const rollStr = this.rollDegrees.toFixed(precision);
const pitchStr = this.pitchDegrees.toFixed(precision);
const yawStr = this.yawDegrees.toFixed(precision);
return `Euler(roll: ${rollStr}°, pitch: ${pitchStr}°, yaw: ${yawStr}°)`;
}
/**
* Calculates the Direction Cosine Matrix (DCM) using the 3-2-1 Euler angles convention.
* @returns The calculated DCM as a Matrix object.
*/
dcm321(): Matrix {
const sPhi = Math.sin(this.phi);
const cPhi = Math.cos(this.phi);
const sTheta = Math.sin(this.theta);
const cTheta = Math.cos(this.theta);
const sPsi = Math.sin(this.psi);
const cPsi = Math.cos(this.psi);
return new Matrix([
[cTheta * cPsi, cTheta * sPsi, -sTheta],
[sPhi * sTheta * cPsi - cPhi * sPsi, sPhi * sTheta * sPsi + cPhi * cPsi, sPhi * cTheta],
[cPhi * sTheta * cPsi + sPhi * sPsi, cPhi * sTheta * sPsi - sPhi * cPsi, cPhi * cTheta],
]);
}
/**
* Rotates a 3D vector using a 3-2-1 Euler angle sequence.
* @param v The vector to rotate.
* @returns The rotated vector.
*/
rotateVector321(v: Vector3D): Vector3D {
return this.dcm321().multiplyVector3D(v);
}
}