Monday, August 27, 2018

Rotation maths

My previous post was designed to give you some intuition when working with quaternions. If you already have a library that does multiplications and inverses for you, you should be fine. If you'd like to learn more details or don't have a quaternion library, this blog post is for you.


How do we rotate something by some axis $V=(v_x, v_y, v_z)$ and some angle $\theta_V$?

To answer that, lets start with something simpler first: we ball with a stick in it, the stick is pointing in direction $D=(d_x, d_y, d_z)$. We want to rotate the ball via $V$ to get a new stick direction $R=(r_x, r_y, r_z)$.

We can do this by using Rodrigues' rotation formula.

$R = cos(\theta) D + sin(\theta) (V \times D) + (1-cos(\theta))(V \cdot D) V$

where $\times$ is the cross product (returns a vector)

$(V \times D)_x = (v_y d_z - v_z d_y)$
$(V \times D)_y = (v_z d_x - v_x d_z)$
$(V \times D)_z = (v_x d_y - v_y d_x)$

and $\cdot$ is the dot product (returns a single value)

$(V \cdot D) = v_xd_x + v_yd_y + v_zd_z$

This formula comes from splitting D into two pieces: $D_{\Vert}$, the part that is parallel to V, and $D_{\perp}$, the part that is perpendicular to V. Assuming $V$ and $D$ are normalized,  $D_{\Vert}=(V \cdot D)V$ is the vector projection of $D$ onto $V$, and then $D_{\perp}=D-D_{\Vert}$ (also known as the vector rejection of $D$ onto $V$).

Then we can find $R_{\Vert}$ and $R_{\perp}$ and get $R=R_{\Vert}+R_{\perp}$. (this isn't quite right, there are weighting terms on $R_{\Vert}$ and $R_{\perp}$ based on $\theta_V$, but this is a good intuition)

$D_{\Vert}$ is unaffected by the rotation, so $R_{\Vert}=D_{\Vert}$. 

$D_{\perp}$ is rotated $\theta_V$ degrees around $V$. If $\theta_V=90$, $R_{perp}$ will be perpendicular to $D_{\perp}$ and $V$. The cross product of any two vectors is known to return a vector that is perpendicular to them both, so if $\theta_V=90$ degrees, $R_{\perp} = V \times D_{\perp}$. Likewise, if $\theta_V=-90$ degrees, $R_{\perp}= V \times D_{\perp}$, and if $\theta_V=180$ degrees then $R_{\perp}=-D_{\perp}$.

The math for getting $R_{\perp}$ is then identical to what happens when you rotate the 2D vector $(1,0)$ by $\theta_V$ degrees around the origin, just replace $(1,0)$ with $D_{\perp}$ and $(0,1)$ with $V \times D_{\perp}$. See the Rodrigues' Rotation Formula wiki page for the full details.


TODO:

If I have axis angle $V=(v_x, v_y, v_z), v_{\theta}$ and another axis angle $U=(u_x, u_y, u_z), u_{\theta}$, intuitively how we combine them is easy: we apply V to an object, then apply U to an object. But can we make a new axis angle $W=(w_x, w_y, w_z), w_{\theta}$ so that when we apply $W$, it is the same as applying $V$ and then applying $U$?

No comments:

Post a Comment