How to convert a quaternion from one coordinate system to another I am trying to find a way of converting a quaternion from an arbitrary coordinate system to a fixed coordinate system that is used in my application.
I have two different coordinate systems, one is for my app and is fixed, but would be defined like below:
fixed_coordinate_system=dict(
    forward=(0,0,1), # (forward direction is positive Z axis)
    up=     (0,1,0), # (up direction is positive Y axis)
    right=  (1,0,0), # (right direction is positive X axis)
)

I have a config object describing another arbitrary coordinate system for a 3rd party as a set of three mutually-orthogonal unit vectors (Note: They are not required to be axis aligned but generally are). A simple example might be like below:
custom_coordinate_system=dict(
    forward=(0,0,-1), # (forward direction is positive Z axis)
    up=     (0,1,0),  # (up direction is positive Y axis)
    right=  (1,0,0),  # (right direction is positive X axis)
)

Using a config like this to define what the arbitrary coordinate system looks like makes it clear at the API level how to map 3rd party coordinates into my application without users having to think about my coordinate system but instead just define what theirs looks like. So far I have only needed convert 3D positions from the arbitrary 3rd party coordinate system into mine. There is probably a better approach, but for now using a dot-product seems to work well as it gives the "amplitude" of the point contributing to the specified vector. Like:
def ConvertPoint(custom_coordinate_system_point):
    return dict(
        x=DotProduct(custom_coordinate_system['right'],   custom_coordinate_system_point),
        y=DotProduct(custom_coordinate_system['up'],      custom_coordinate_system_point),
        z=DotProduct(custom_coordinate_system['forward'], custom_coordinate_system_point),
    )

However now I have need of converting a quaternion representing an orientation in the arbitrary 3rd party coordinate system into my apps coordinate system using the custom_coordinate_system config.
Ultimately I plan to implement something like:
def ConvertQuaternion(custom_coordinate_system_quaternion):
    return dict(
        w=...,
        x=...,
        y=...,
        z=...,
    )

I believe this is possible as in theory it should only ever be a rotation and maybe a handedness conversion. But so far I have failed to find any relevant information showing me the approach for this sort of conversion.
Thinking it through conceptually, the coordinate system definition I have is very similar to that of a 3x3 rotation matrix and maybe there is some way I can define this as such and just convert that to a quaternion and then I assume I just multiply the two quaternions to get the result...
The closest information like this that I have read is:

*

*Find the rotation angles in $x, y$ and $z$ to convert between axis systems

*https://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/
I was not sure doing the:
a) axis config to rotation matrix then
b) rotation to quaternion and then
c) multiply quaternions would work.
Partly as that doesn't seem to handle the handedness change and this is just a bit out of my current knowledge.
So my question is really what is an approach to doing a generic transform of a quaternion from one arbitrary coordinate system into another using a config like this that defines the axis of the arbitrary source coordinate system?
Thanks.
 A: When dealing with quaternions, there are two variations in conventions which should be stated when describing the quaternions. The first one is if the scalar element is first or last, the second is if the coordinate system is right handed or left handed.
To convert between  scalar last and scalar first quaternions simply move the scalar
<qx,qy,qz,qw> -> <qw,qx,qy,qz>
To convert between right and left handed coordinate systems negate the x component and swap y and z.
(scalar first)
<qw,qx,qy,qz> -> <qw,-qx,-qz,-qy>
(scalar last)
<qw,qx,qy,qz> -> <qw,-qx,-qz,-qy>
Once all quaternions are under the same convention they need to be rotated to which ever reference frame they are needed in.
Given:
q_ar = quaternion from the reference frame r to a
q_ia = quaternion from a to i
q_ir = quaternion from r to i
q_ir = q_ia X q_ar
where X is the quaternion Hamilton product
This link has everything you need as far as quaternion multiplication and rotation matrices.
https://www.biorxiv.org/content/10.1101/733881v5.full
