- Home /
How to find axis and angle between two rotations.
I know Quaternion.Angle() finds the angle between two rotations, but how do I find the axis about which that angle can be applied?
While I'm getting believeable looking results with this test script (that pretty much uses the logic described by @Glurth aslo)...
(Empty scene, attach to camera)
using UnityEngine;
using System.Collections;
public class AngleTest : $$anonymous$$onoBehaviour {
public Transform a;
public Transform b;
public LineRenderer l;
// Use this for initialization
void Start ()
{
l = gameObject.AddComponent<LineRenderer>();
a = GameObject.CreatePrimitive(PrimitiveType.Cube).transform;
b = GameObject.CreatePrimitive(PrimitiveType.Cylinder).transform;
// a.rotation = Quaternion.AngleAxis(90, Vector3.up);
// b.rotation = Quaternion.AngleAxis(90, Vector3.forward);
Vector3 va = a.TransformDirection(Vector3.right);
Vector3 vb = b.TransformDirection(Vector3.right);
Debug.Log(Vector3.Cross(va, vb));
Debug.Log(Quaternion.Angle(a.rotation, b.rotation));
}
void Update ()
{
l.SetVertexCount(2);
Vector3 va = a.TransformDirection(Vector3.right);
Vector3 vb = b.TransformDirection(Vector3.right);
l.SetPosition(1, Vector3.Cross(va, vb) * 10f);
Debug.Log(Quaternion.Angle(a.rotation, b.rotation));
}
}
what bothers me is that if you un-comment the commented lines, Quaternion.Angle(a.rotation, b.rotation)
returns 120, when the angle see$$anonymous$$gly is 90 degrees (alternate selecting both objects in hierarchy and look at the red rotation arrows in scene view).
So since Quaternions and 3D rotations are a bit more complex than meets the eye, you'll probably have lots more trouble using/applying that axis value even if it was correct :P.
Quaternion.Angle(a.rotation, b.rotation) returns 120, when the angle see$$anonymous$$gly is 90 degrees
I'd think Quaternion angle somehow CO$$anonymous$$BINES both the angle between the axis, and the angles AROUND those axis. Notice that if you change the "90" in those remarked out lines, you will get different angle in your debug output, not 120. I ran your script, the axis it drew is indeed perpendicular to both axis of the rotations. That being said, your tests may very well show that this is NOT what the OP is actually looking for.
Yeah I'm definitely not saying Quaternion.Angle();
is bugged or anything. Just that I don't know the math behind Quaternions well enough :).
Depending on what the OP needs and how he plans to use the result, this might be another way to get the axis.
Quaternion differenceFromAtoB = a.rotation * Quaternion.Inverse(b.rotation);
Vector3 axis;
float angle;
differenceFromAtoB.ToAngleAxis(out angle, out axis);
Getting the "difference" quaternion and getting the angle and axis from it (based on this)
Quaternions are 4D (i.e. points on a hypersphere) which means that often your intuition for how to visualize them is wrong, or at least misleading, until you've worked with them a lot and/or really dug into the math.
Thanks everyone for your replies. I've had to spend some time reading up on how quats work in order to wrap my head around this. I think Glurth's idea is probably the simplest (for some reason I'm not seeing any option to upvote... guess I don't have any $$anonymous$$arma yet:)
Answer by Glurth · Jan 01, 2015 at 07:09 PM
If I understand what your looking for, this axis will be perpendicular to both Quaternions' "LookAt" Vector3 (I think you'd use ToAngleAxis()
axis output for that). If you get both those vectors, you can use the cross-product ( Vector3.Cross(V3,V3)
) of them to get a Vector3 perpendicular to both. I doubt this is the most efficient way though.