use a vector perpendicular to Z-axis rotate that vector by your quaternion and get rotation from un-rotated to rotate vector. that’s the Z-axis rotation.
public static quaternion WithOutZAxis(this quaternion rot, out quaternion zRot)
{
float3 xAxis = math.float3(1, 0, 0);
var rotatedX = math.mul(rot, xAxis);
zRot = FromToRotationAssumeNomalized(xAxis, rotatedX);
return math.mul(math.inverse(zRot), rot);
}
//This is from Unity.Physics
/// <summary>
/// fast approach to shortest arc rotaion from a to b
/// a and b MUST BE NORMALIZED direction
/// </summary>
public static quaternion FromToRotationAssumeNomalized(float3 from, float3 to)
{
float d = math.dot(from, to);
if (d == 1) { return quaternion.identity; }
float4 q = math.float4(math.cross(from, to), 1f + d);
math.normalize(q);
return math.quaternion(q);
}
Hi @Lieene-Guo , I really appreciate you helping me and writing code. I just don’t know how to work with this. I tried a couple of things with it. I get that it returns a quaternion with and without the z axis, and bij subtracting the two the result is a quaternion that only represents the z axis. But that’s in 4 floats. And I really only want one float, if it’s degrees or radians doesn’t matter. just a single float. can you help me with that?
I guess you have written a whole library that does these kinds of things, with the “MathX” reference
I don’t know how to use it still, it must be basic for you but this kind of “advanced” math, is not yet part of my education.
Unity.Mathematics.quaternion stores radians instead of degrees. And after testing different kins of sin,cosin etc. methods and translating the result to degrees, I don’t see anything that looks like a value I was testing for.
I think there must be a simple way of seeing what the current stored radians or degrees are from a quaternoin. So I probably missed something.
In 2D you can represent rotations using angles or using complex numbers. Complex numbers add an additional dimension to your mathematics, but avoid trigonometric operations. Complex numbers do not contain information about the number of times something rotates around (there’s no concept of a 720 degree rotation).
Similarly, quaternions also use an additional dimension of imaginary numbers to compute rotations without trigonometry. However, they also avoid other issues like gimbal locking and have slerp capabilities. There is no “angle” stored in a quaternion in the conventional sense.
Assuming that your quaternion was only ever rotated along the z-axis (roll), then if you do this:
var rolledRightVector = math.mul(rot, new float3(1, 0, 0));
The z value of rolledRightVector is now the sine of the z-rotation. If you were to rotate along z by 90 degrees, the z value of rolledRightVector would be 1. If you don’t rotate at all, it would be 0.
So now you can do this:
var zRotationInRadians = math.asin(rolledRightVector.z);