Aiming
From CGAFaq
What’s needed is a method for creating a rotation that turns one unit vector to line up with another. To aim at an object, you can subtract the position of the camera from the position of the object to get a vector which you then normalize. The vector you want to turn is the camera forward vector, commonly a unit vector along the camera −z axis. Be warned that more than one rotation can achieve aim alone. (The issue is rather complicated, as laid out in Ken Shoemake’s article on twist reduction in Graphics Gems IV.) For example, even if the camera is already properly aimed you could rotate it around its z axis. The most direct rotation is given by the non-unit quaternion
- q = [(b, −a, 0), 1−c], to aim the −z axis along unit vector (a, b, c).
Normalization is advised, but it will fail for aim vector (0, 0, 1). In that case just rotate 180° around the y axis, using
- q = [(0, 1, 0), 0]
If the camera is level after rotation by quaternion [(x, y, z), w], the y component of its rotated x axis will be zero, so
- x y + w z = 0
If it is upright, the y component of its rotated y axis will not be negative, so
- w2 − x2 + y2 − z2 ≥ 0
To ensure these two desirable properties, aim with a more sophisticated non-unit quaternion
- [(b s, −a t, a b), s t], where s = r−c, t = r+1, and r = √(a2+c2).
This can also fail to normalize, in which case normalize instead
- [(0, 1+c, −b), 0]
Unless the aim vector is null, this will succeed. If the aim vector has not been normalized and its magnitude is m = √(a2+b2+c2), substitute 1 ↦ m. That is, use t = r+m and use m+c.
More generally, to rotate unit vector u1 directly to unit vector u2, the non-unit quaternion will be
- q = [u1×u2, 1+u1·u2]
Why? If u is a unit vector, then it is normal to a plane through the origin with equation u·p = 0. Reflection in that plane is given by reversing the u component of p.
- reflect(p,u) = p − 2(u·p) u
The quaternion product of u1 and u2 is [u1×u2, −u1·u2], so
- −2 (u·p) = p u + u p
Noting u u = −1, this gives a quaternion reflection formula.
reflect(p,u) = p + (p u + u p)u = p − p + u p u = u p u
Reflecting with u1 then u2, by u2(u1 p u1)u2, rotates by twice the angle between the planes, with axis perpendicular to both normals. Noting u1 u2 is the conjugate of u2 u1, and −q rotates like q, the rotation quaternion is
q = −u2 u1 = −[u2×u1, −u2·u1] = [u1×u2, u1·u2]
This q fails to aim u1 at u2 by rotating twice as much as needed, but its square root succeeds. One square root of unit q is 1+q normalized, geometrically the bisection of the great arc from the identity to q. There is an inevitable singularity when u2 is the opposite of u1, because any perpendicular axis gives an equally direct 180° rotation.
[These quaternion methods were provided by Ken Shoemake.]

