Ok, am I misunderstanding how Unity quaternions work, or is there a bad (about 2 degrees difference!) floating point error?
The TLDR is I use a quaternion r to rotate vector v and put the result in w. I then compute the angle between v and w (I looked at Unity’s code for Vector3.Angle, and it looks correct to me, and the floating point error on the value of 180/pi is not enough to make more than a fraction of a degree difference) and I computed angle-axis of r itself (this time the code is internal and I can’t see it). I expect the results to be the same, but they differ by a couple degrees.
What am I missing? I’d think if this is a bug, it’d be noticed and fixed by now!
I’ve asked elsewhere, and received lots of views but no answers. I know not many work with quaternions much so maybe nobody knows…
From my readings, it does appear that in Unity, the way to rotate a vector using a quaternion is quaternion times vector (the multiplication operator being overloaded to do the right thing, in theory). But the quaternion’s rotation amount an how much the vector rotated seem to be two degrees different! That is not what we call “close enough for government work”!
Log output
v = (1.00, 1.41, -1.50)
r = (0.12768, 0.23930, 0.14488, 0.95155)
w = (-0.20, 1.91, -1.26)
angle = 33.43961
angle = 35.81708
axis = (0.42, 0.78, 0.47)
using UnityEngine;
namespace Deplorable_Mountaineer.Core.Utils {
public class VectorsAndRotations : MonoBehaviour {
private void Start() {
//make a vector
Vector3 v = new Vector3(1, Mathf.Sqrt(2), -1.5f);
Debug.Log($"v = {v}");
//Make a rotation, first 20 degrees about z axis (roll), then
//10 degrees about x axis (pitch), and then 30 degrees about
//y axis (yaw).
Quaternion r = Quaternion.Euler(10, 30, 20);
Debug.Log($"r = {r}");
//w is v rotated by the rotation r
Vector3 w = r*v;
Debug.Log($"w = {w}");
//If v and w are vectors, what is the angle between them?
//method 1
float angle = Vector3.Angle(v, w);
Debug.Log($"angle = {angle}");
//method 2, since we know that w = r*v, find the angle of rotation encoded in r.
//this way also gives the axis, perpendicular to the plane containing both vectors.
Vector3 axis;
r.ToAngleAxis(out angle, out axis);
Debug.Log($"angle = {angle}");
Debug.Log($"axis = {axis}");
//why are they different?
}
}
}