The context: A graphic application in which the user rotates an object around the origin and then can press a button to reset the rotation to its reset state. The reset should be appear smooth and not just jump.
I'm using a quaternion to represent the current rotation of the object at any time and when the user presses the button I want to slerp() between the current rotation and the reset one. This works fine if the reset rotation is a real rotation with Theta and an Axis but it breaks down if the reset state is has theta=0.
The slerp starts with a standard rotation quaternion
q1 = sin(theta/2) + (xi + yj + zk)cos(theta/2)
and supposed to end at the rotation quaternion with theta=0:
q0 = sin(0/2) + (xi + yj + zk)cos(0/2)
which turns out to be the the unit quaternion:
q0 = 1+0i+0j+0k
The problem I'm facing is that to do the rotation, slerp calcs the angle alpha between q0 and q1 by just taking their vector parts and doing arccos(), but the unity quaternion's vector is (0,0,0) so it can't do that.
Is there a standard way to solve this issue?
Yes, you can do it... First of all your definition of a quaternion is wrong. The correct expression is:
$$q_1 = \cos(\theta/2) + (xi + yj + zk)\sin(\theta/2)$$
and
$$q_0 = \cos(0/2) + (xi + yj + zk)\sin(0/2) = 1 $$
where $x^2 + y^2 +z^2 = 1$. Since $q_1$ represents the forward rotation, then the inverse is just the conjugate (i.e. negate the vector part).
$$q_1^{-1} = \cos(\theta/2) - (xi + yj + zk)\sin(\theta/2)$$
We can then divide the reverse rotation into N steps by dividing the angle by N yielding
$$q_{slerp} = \cos(\frac{\theta}{N}/2) - (xi + yj + zk)\sin(\frac{\theta}{N}/2)$$
This rotation is then applied to all of the points in your rotated shape object N times to bring it to the reset position.