Super long winded question alert: here be dragons if you don’t enjoy long reads written in poor English
I have a question about rotations. I’ve managed to figure out how to generate state vectors from orbital elements, where the important one for this particular case are the semi-major axis of the ellipse, its eccentricity and then the three angles that define the orientation of the orbit in 3D space, namely the argument of periapsis, the inclination of the orbit and finally the longitude of the ascending node. I can take the orbital elements of any body and reproduce its unique orbit around its primary.
When adding bodies, the user will see the orbit of the body they are about to add given the values they have provided for its orbital elements, like in the picture below:
This functionality works fine if you only provide values for the inclination and argument of periapsis; - the body you add will follow the the green ellipse - and let the longitude of the ascending node be 0. However, things break down when you set a value of the ascending node, and the orientation of the green ellipse does not match the orientation of the body you have added.
I suspect the problem lies in the fact that when you convert the orbital elements to state vectors, you need to first rotate the position and velocity vectors around the z axis with the argument of periapsis value, and then you have to rotate them around the x axis with the inclination value. Last, but not least, and here’s the problem, I think, you have to rotate those vectors around the z axis again with the longitude of the ascending node value, to get your position and velocity vectors that describe the unique trajectory of a body around its primary: I have not found a way of first applying a rotation to the z axis, then one to the x axis and then the z axis again.
Does anyone know how I could do this?
Here is the code I use for generating the state vectors from the orbital elements:
export function getOrbit(primary, secondary, g) {
const x = primary.x !== undefined ? primary.x : 0;
const y = primary.y !== undefined ? primary.y : 0;
const z = primary.z !== undefined ? primary.z : 0;
const { vx, vy, vz } = primary;
const apoapsis = getApoapsis(secondary.a, secondary.e);
const dParams = getDistanceParams(primary, {
x: x + apoapsis,
y: y,
z: z
});
const d = Math.sqrt(dParams.dSquared);
const vMag = getVMag(g, primary, d, secondary.a);
const secondaryP = new H3()
.set({ x: apoapsis, y: 0, z: 0 })
.rotate({ x: 0, y: 0, z: 1 }, secondary.w - 180)
.rotate({ x: 1, y: 0, z: 0 }, secondary.i)
.rotate({ x: 0, y: 0, z: 1 }, secondary.o);
const secondaryV = new H3()
.set({
x: -dParams.dy * vMag / d,
y: dParams.dx * vMag / d,
z: dParams.dz * vMag / d
})
.rotate({ x: 0, y: 0, z: 1 }, secondary.w - 180)
.rotate({ x: 1, y: 0, z: 0 }, secondary.i)
.rotate({ x: 0, y: 0, z: 1 }, secondary.o);
return {
...secondary,
x: x + secondaryP.x,
y: y + secondaryP.y,
z: z + secondaryP.z,
vx: vx + secondaryV.x,
vy: vy + secondaryV.y,
vz: vz + secondaryV.z
};
}
Then when I rotate my ellipse, I have this code:
rotateAroundFocus(axisRotations: VectorType): void {
const w = degreesToRadians(axisRotations.z); //argument of periapsis
const i = degreesToRadians(axisRotations.x); //inclination
const o = degreesToRadians(axisRotations.y); //Longitude of the ascending node
this.rotation.x = i;
this.rotation.y = o; //This does not work, but if I only provide values for i and w, it works
this.rotation.z = w;
}
Thanks for anyone that made it this far, and here’s a good overview of what I’m doing rotation wise, if the code was not specific enough: http://astronomy.swin.edu.au/cosmos/A/Ascending+Node
Naturally, if anyone has any questions, I’m here