Spherical coordinates / orbits

Hello all!

I have right-handed Z-up server-side coordinates.
Client-side left-handed Y-up coords.
Previous question + solution :-): Coordinates - server XYZ to client XZY - #2 by carolhmj

Now I have a problem figuring out the following:

. System transform nodes have “inclinations” from the default, flat one, define as three angles. Call this the “orbital plane”.
. Then some satellites orbit the center of each system/transform node.

Given that I have:
. x, y and z server-side inclination angles
. (x, y, z) server-side system center coordinates
. a distance from the center to the orbit (circles only for now, not ellipses)

How do I position a satellite:
. at the right x, y, z clients-side
. and the right position along the orbit (expressed as a fraction of Math.PI * 2), to simulate orbital evolution.

I have tried:

satellite_mesh.position.set(
    orbit_radius * Math.cos(orbit_angle_y) * Math.sin(orbit_angle_x),
    orbit_radius * Math.sin(orbit_angle_x),
    orbit_radius * Math.sin(orbit_angle_y) * Math.cos(orbit_angle_x),
);

But all I manage to get is something similar to the following:

Where the red and green directions are quite obviously not the same :[ (planets are in an ugly buy easy-to-spot blue tint).

Any idea?

Thanks!

NB: I cannot make the spheres children or the orbits/lines meshes as their scaling changes dynamically based on proximity.

Hello!

About the inclination angles, I didn’t understand one thing: are they angles in respect to each coordinate = 0 plane? I.e, the x angle is the inclination on the plane YZ? Something like this?

Thank you Carol,

Yes each star has three angles associated with it, one for each x/y/z axis.
So I would imagine the “x angle” rotates around the x axis, and the server-side Y angle around the client-side Z angle; likewise for the Z/Y flip.

Hello! Sorry about not answering earlier, do you still need help with calculations? In any case, I was thinking I’d approach the problem like this: first, I would calculate the star’s position in the original server coordinates, then flip the Y and Z coordinates (as we discussed in the earlier post) to map that to client coordinates. To calculate the server coordinates, you’ll have to determine in which order to apply the angles. Usually it’s X,Y, then Z, but your server might use a different convention, so it’s good to check. Let’s assume it’s X, Y, Z. Then, you have to apply the rotation matrices ( Rotation matrix - Wikipedia) for each angle:

R_z * R_y * R_x * c

Where c is the coordinate you want to rotate.
Then you also have to do a translation by the system center.

Something I used that works well is to define the position of your satellite in the orbital plane with:

satellite_mesh_position.set(
    orbit_radius * Math.cos(orbit_angle_x),
    0,
    orbit_radius * Math.sin(orbit_angle_y)
);

Then you attach this mesh by parenting to an orbital transform node whose only purpose is to tilt the orbital plane.

From your 3 euler angles of inclination, you can deduce a normal vector to the orbital plane.

By taking the cross product between this target normal vector and a simple up vector, you get a rotation axis to use to rotate your orbital node, then you can use Vector3.GetAngleBetweenVectors to figure out the rotation angle.

Finally you call

orbitalNode.rotate(rotationAxis, rotationAngle, Space.World)

This should position the satellite in the exact position you want.

If you cannot use parenting, then instead of using an intermediate TransformNode, you can directly modify the local orbit position from the beginning using a rotation matrix:

 const rotationMatrix = Matrix.RotationAxis(rotationAxis, angle);
 return Vector3.TransformCoordinates(localPosition, rotationMatrix).addInPlace(centerOfOrbit);

Hello!

Thank guys, I haven’t had the chance to look at your kind suggestions. Kind of tangled in some C->rust migration at the moment, so will go back to the client-side later… :slight_smile:

Cheers!

1 Like