Rotation problems

Super long winded question alert: here be dragons if you don’t enjoy long reads written in poor English :dragon_face: :dragon_face: :dragon_face: :dragon_face: :dragon_face: :dragon_face: :dragon_face:

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 :dancer::rocket:

I think you might find this useful:

Also, I really don’t understand all the orbital dynamics lingo. Some pictures and a glossary would help :slight_smile:

2 Likes

Thanks! Gonna dive into that. As a temporary solution I’m rotating the position of each vertice to achieve the expected result, but feels kind of hackish!

Nailed it :smiley:!

The solution was to wrap the ellipse in a parent Object3D and then apply the longitude of the ascending node transformation to it after having applied the rotations to the ellipse itself, that way I’m able to get my desired ZXZ rotation.

Saying I nailed it is a bit generous, though… Found the solution here: How to use matrix for transformation · Issue #1593 · mrdoob/three.js · GitHub

Funny how a question and answer from 7 years ago can still be relevant… Then again I’m guessing Newtonian dynamics have not changed much over the past 200 or so years :rofl:

Oh well, happy Wednesday

2 Likes

@TheHappyKoala , wow. This gui input methods are looking so good. Can you please give me the script of this. That will be used much in my application. Please send me the script. or please share the link of this application.

Thanks, you’re most kind!

They’re custom made React components, but you can use the css to reproduce the look if you’re not using react. The whole project is open source and can be found on GitHub. You will find the components themselves in src/js/components.

2 Likes

Oh. Okay @TheHappyKoala :blush::blush: . Thanks for your kind reply.

Of course, here you go :smiley:

WOW:star_struck::star_struck::star_struck:, It is awesome.

1 Like

I am fighting with similar issues see https://codesandbox.io/s/7ly5c and https://stackoverflow.com/questions/57311356/rotating-an-object-properly-around-a-pivot-point-given-axis-and-angle/57312831#57312831

I’d appreciate if we somehow bundle our efforts and come up with somekind of rotation FAQ. I am trying to add something like the Pivot class in https://codesandbox.io/s/7ly5c to hide the details of the rotational transformations.

1 Like