Quaternion rotations & transforms from global to local space

I am trying to solve this problem and getting no where, could really use some assistance. Rotation is defined as X (rotate left/right), Y(rotate up/down), Z(roll) Coordinates are X: Forward/backward, Y: Left/right, Z: up/down

I have two objects in simulated space, both have galactic coordinates (XYZ) and a quaternion representing their rotation.

ObjectA Coordinates: 0.593 0 0 (directly ahead of ObjB) RotationQuat: w: 0, x: 1, y: 0, z:0 (Rotated 180 yaw, facing backwards)

ObjectB Coordinates: 0 0 0 RotationQuat: w: 1, x: 0, y: 0, z: 0 (No rotation, facing towards ObjA)

Given the above information, how do I translate ObjA's location into ObjB's local space?

If ObjA fires at ObjB (or vise versa), I need to calculate which side will be hit. Forward, Aft, Port, Starboard, Ventral or Dorsal.

My project is written entirely in C. Actually this is an old project, created by someone else that I am converting to using quaternions due to gimbal lock.

how do I translate ObjA's location into ObjB's local space?

Get A's coordinates as a vector from the centre of B:

Acb= (0.593,0,0) - (0,0,0) = (0.593,0,0)


Make a (non-unit) quaternion from Object A's coordinates wrt B:

Acq = w: 0, x: 0.593, y: 0, z: 0


Rotate it according to the inverse of B's orientation (Bq):

Bq^-1 * Acq * Bq
= (w: 1, x: 0, y: 0, z: 0) * (w: 0, x: 0.593, y: 0, z: 0) * (w: 1, x: 0, y: 0, z: 0)
= (w: 0, x: 0.593, y: 0, z: 0)


Extract the imaginary part: (0.593,0,0)

Voila.

Note: since B is aligned with the global frame here, AND is located at the world origin, the vector to A from B coordinate frame is the same as the vector to A from the world (galaxy) frame.

More information on how to rotate a vector or point with a quaternion here: https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation#Using_quaternion_rotations

• This is essentially what I was doing. Create coordinates using ShipBCoord - ShipA coord, then rotate that by ShipA's Quaternion. This givens coordinates representing ShipB's position in ShipA's local space. I use the function once from ShipA to ShipB to make sure shipB is in shipA's firing arc, and then again to see where onShipB a weapon fired from ShipA would hit. What would be the best way to determine e.g., aft/fore/port/star/dorsal/ventral? Currently I'm just using if statements based on what the output of the rotation is, e.g. if X == 1, return forward, if that makes sense. – Mike Taylor Aug 17 '15 at 0:06
• However, this seems to not produce appropriate output when ShipB is not exactly in front of ShipA, or above/below/etc. If ShipB is slightly ahead and to the port of ShipA, the numbers bork. Hmm. – Mike Taylor Aug 17 '15 at 0:10
• Suggest you print out the numbers at each step of the calculation that is going wrong, review them, and if it still doesn't look good, post here. – D.J.Duff Aug 17 '15 at 15:57