# Extract 'relative' yaw from a world rotation on a sphere

Hi

I’ve been searching, and trying to solve this for quite some time now, but can’t seem to find an answer (and hardly have any hair left to pull out).

I need to find the yaw (angle) of an objects rotation (on a sphere). I was thinking of converting the rotation to have it’s up vector at 0,0,1, so I then can use atan2 to calculate the angle. However, I’m stuck there, and not sure if that’s even the proper solution. It also needs to work around the poles.

I lack the proper knowledge of matrices and quaternions to solve this. Was hoping anybody here could help solve this.

I did find this on stackoverflow, but not sure if that’s of any use (and not sure if/how applicable to ue4 matrices)

Thanks!

cheers
-Frank

1 Like

Hey, It’s always a tricky topic because Rotations are not really simple, as far I know can you convert a Rotation to a matrix, but it’s just another powerful way to represent the Rotation.

You always can multiply the Yaw only Matrix with the World Rotation Matrix, which would look like this:

``````const FQuat YawDelta = FQuat::MakeFromEuler(FVector::UpVector * CameraYaw);

const FQuat WantedRotation = (YawDelta.ToMatrix() * WorldRotation.ToMatrix()).ToQuat();
``````

Or more Simple just using FQuats like:

``````const FQuat YawDelta = FQuat::MakeFromEuler(FVector::UpVector * CameraYaw);

const FQuat WantedRotation = WorldRotation * YawDelta;
``````

I’m pretty new to Unreal Engine, so I don’t know any tricks the engine has to offer, however one downside of just adding Rotations to it is the fact that it keeps spinning because it’s taking the World Rotation and Constantly adding value to it.

So what’s the solution to this?

I solved it by creating a Rotation which is always pointing relative forward to the Unit which needs to be rotated locally, so when the Unit is facing up the rotation pointing Forward and when the Unit is facing Down it’s pointing Backwards with a Negative Roll.

My Code looks like following:

``````// ROTATION
// STORE THE NORMAL VECTOR, HERE WE SIMPLY CAN USE ANY Up, TO USE IT IN THE CROSS PRODUCT AND IN THE MATRIX ROTATION
// NOTE: Collision->GetUpVector() IS ALWAYS WITH THE LAST POSITION ONE FRAME BEHIND, THE MOST OPTIMAL CASE WOULD USING
// THE GROUND NORMAL FROM THE STACK TRACE OR THE GRAVITY VECTOR OF THE PLANET WHICH GET PREDICTED BEFORE THIS CALCULATION HAPPENS
const FVector NormalRotationVector = Collision->GetUpVector();

// GETTING THE CROSS PRODUCT OF THE FORWARD TO THE NORMAL
// TO HAVE THE OPPOSITE RIGHT HAND VECTOR SEE -> https://mathworld.wolfram.com/CrossProduct.html
const FVector CrossRotationRight = FVector::CrossProduct(  OrbitalOriginRotation.GetForwardVector(), NormalRotationVector);
// HERE WE TAKE THE RIGHT HAND VECTOR AND GETTING THE NEW DELTA BETWEEN OrbitalOriginRotation.GetForwardVector() AND NormalRotationVector BY USING THE CROSS PRODUCT
const FVector CrossRotationForward = FVector::CrossProduct(NormalRotationVector, CrossRotationRight);

// CONVERT THE VECTOR TO AN ROTATION MATRIX WITH X AND Z TO MAKE IT WORK ON FAUX GRAVITY
// HERE WE SET OrbitalOriginRotation WHICH IS THE KEY IN THIS EQUATION WHICH STORES THE ORIGIN ROTATION,
// THIS MEAN WE CAN WORK WITH AN Unify ALWAYS FACING RELATIVE FORWARD ROTATION TO THE WORLD
OrbitalOriginRotation = FRotationMatrix::MakeFromXZ(CrossRotationForward.GetSafeNormal(), NormalRotationVector).ToQuat();

// LET'S GET THE CameraYaw ONLY AND CALCULATE AN Yaw ONLY ROTATION ... NOTE: CameraYaw IS THE ABSOLUTE ROTATION, -180 ... 180 NOT ANY DELTA
// IT WILL WORK WITH ANY Yaw, DON'T NEED TO BE THE CAMERA
const FQuat CameraYawRotation = FQuat::MakeFromEuler(FVector::UpVector * CameraYaw);

// APPLY THE Awesome Final FAUX GRAVITY ROTATION WITH THE OrbitalOriginRotation * CameraYawRotation
const FQuat FinalFauxRotation = OrbitalOriginRotation * CameraYawRotation;

// SET THE FINAL ROTATION TO THE ACTOR OR COMPONENT
//CollisionRotationRuntime = FinalFauxRotation;
Collision->SetWorldRotation(FinalFauxRotation);
``````

And this is the Key Part, the Rotation requires having an Origin which is a Runtime Quaternion which is Rotating with the Unit but on a unify way.

So it needs to be in the Header to store the value:

``````// FOR ROTATING ON FAUX GRAVITY
// THIS QUATERNION IS REALLY IMPORTANT TO STAY IN THE CURRENT STATE OF MOTION, DON'T SET IT SOMEWHERE ELSE BECAUSE THE NEXT FRAME IS DEPENDING ON THE VALUES
FQuat OrbitalOriginRotation;
``````

Here is a video of the Code in Action:
https://www.dropbox.com/s/d9hy2m0krv4h97j/Unreal%20Engine%205%202022.08.28%20-%2014.22.14.02.mp4?dl=0

Thanks for this Post, once I’ve been on the way to figure it out I was really wondering why there was no answer^^ so here it is.