$
\newcommand{\vo}{\mathbf{o}}
\newcommand{\vv}{\mathbf{v}}
\newcommand{\vs}{\mathbf{s}}
\newcommand{\vp}{\mathbf{p}}
\newcommand{\vx}{\mathbf{x}}
\newcommand{\vy}{\mathbf{y}}
\newcommand{\vz}{\mathbf{z}}
\newcommand{\vu}{\mathbf{u}}
\newcommand{\vw}{\mathbf{w}}
\newcommand{\vk}{\mathbf{k}}
\newcommand{\vP}{\mathbf{P}}
\newcommand{\vR}{\mathbf{R}}
\newcommand{\vI}{\mathbf{I}}
\newcommand{\vrot}{\vv_\mathrm{rot}}
\newcommand{\mP}{\mathcal{P}}
\newcommand{\mR}{\mathcal{R}}
\newcommand{\mI}{\mathcal{I}}
\newcommand{\flecha}[1]{\vec{#1}}
\newcommand{\vfx}{\flecha{x}}
\newcommand{\vfy}{\flecha{y}}
\newcommand{\vfz}{\flecha{z}}
\newcommand{\vfu}{\flecha{u}}
\newcommand{\vfv}{\flecha{v}}
\newcommand{\vfw}{\flecha{w}}
\newcommand{\vfk}{\flecha{k}}
\newcommand{\vfvrot}{\vfv_\mathrm{rot}}
\newcommand{\opar}{\parallel} %% parallel
\newcommand{\oper}{\vdash}
\newcommand{\operV}{\perp}
\newcommand{\boper}{\!\oper\!}
\newcommand{\boperV}{\!\operV\!}
\newcommand{\bopar}{\!\opar\!}
$
Rotation matrix
Derivation of rotation matrix for 2D and 3D, from scratch.
The vector space
Operations and coordinates.
We consider a vector space, either a 2D or 3D one. This vector space
has a scalar product, which defines lengths of vectors
and angles between them, as usual. We assume this vector space includes an
orthonormal basis $\{\vfx,\vfy\}$ in 2D, or $\{\vfx,\vfy,\vfz\}$ in 3D.
Thus (in 2D), when we say that $\vv=(a_0,a_1)^T$ are the coordinates of $\vfv$,
what we mean is that $\vfv$ is $a_0\vfx\,+\,b_1\vfy$ (equally in 3D, with 3
components coordinate tuples).
Parallel and perpendicular components of a vector
Let $\vfu$ and $\vfv$ be any two vectors in
the vector space. We assume $\vfu$ has unit length. We define two non-conmutative lineal
operators ($\opar$ and $\oper$) in that vector space. The first one allows to get the component of $\vfv$ parallel to
$\vfu$, and is defined as:
$$
\vfv\bopar\vfu ~~\equiv~~ (\vfv\cdot\vfu)\vfu
$$
The other lineal operator allows to obtain the component of $\vfv$ perpendicular to $\vfu$, and
is defined as $\vfv$ minus the parallel component:
$$
\vfv\boper\vfu ~~\equiv~~ \vfv\,-\,(\vfv\bopar\vfu)
$$
So any vector can be decomposed in two components, one parallel and another perpendicular to
any vector, that is:
$$
\vfv ~~=~~ (\vfv\bopar\vfu)\,+\,(\vfv\boper\vfu)
$$
Of course, these two operators can be extended to their corresponding operators acting on coordinates.
Rotations in 2D
Perpendicular vector operator and matrix in 2D
In 2D we can define the operator $\mP$, this operator, when applied to any
vector $\vfv$ yields a vector $\mP\vfv$ perpendicular to $\vfv$, that is, it
holds $\vfv\cdot(\mP\vfv)=0$, and with the same length, that is
$(\mP\vfv)\cdot(\mP\vfv)=\vfv\cdot\vfv$. There are two possible vectors with
these two properties (if a vector $\vfw$ holds both, also does $-\vfw$). To
determine operator $\mP$, we assume it holds $\vfy\,=\,\mP\vfx$.
It is easy to check that if $\vv=(a_0,b_0)^T$ are the coordinates of $\vfv$,
then those of $\mP\vfv$ are $(-a_1,a_0)$.
Thus operator $\mP$ has an associated 2x2 matrix $\vP$, such that if
$\vv=(a_0,a_1)^T$ are the coordinates of $\vfv$, then the coordinates of
$\mP\vfv$ are $\vP\vv$, where:
$$
\vP ~\equiv~ \left(\begin{array}{cc}
0 & -1 \\
1 & 0
\end{array}\right)
$$
The rotation operator and matrix in 2D
In a 2D vector space we want to define the rotation operator $\mR_\theta$.
This rotation is a rotation around the origin (the null vector) of the vector space, with angle $\theta$ (in radians).
If we want to rotate vector $\vfv$, we begin by using the previous definition of $\mP$.
We define the rotated vector $\mR_\theta\vfv$ as a weighted sum of $\vfv$ and the vector perpendicular to
$\vfv$, such that the rotated vector has the same length as the original, as follows:
$$
\begin{equation}
\mR_\theta\vfv ~=~ (\cos\theta)\,\vfv \,+\, (\sin\theta)\,\mP\vfv
\end{equation}
$$
note that when $\theta=0$, we have $\mR_0\vfv=\vfv$. By using $\vfv=\mI\vfv$ (where
$\mI$ is the identity operator), we get a definition for the rotation operator:
$$
\begin{align*}
\mR_\theta\vfv ~~&=~~ (\cos\theta)\vfv \,+\, (\sin\theta)\mP\vfv \\
~~&=~~ (\cos\theta)\mI\vfv \,+\, (\sin\theta)\mP\vfv \\
~~&=~~ \left[(\cos\theta)\mI \,+\, (\sin\theta)\mP\right]\,\vfv
\end{align*}
$$
thus:
$$
\mR_\theta ~~=~~ (\cos\theta)\mI \,+\, (\sin\theta)\mP
$$
This implies we can write the rotation matrix $\vR_\theta$ as a combination of the identity matrix
$\vI$ and matrix $\vP$:
$$
\vR_\theta
~~=~~
(\cos\theta)\vI \,+\, (\sin\theta)\vP
~~=~~
(\cos\theta)
\left(\begin{array}{cc}
1 & 0 \\
0 & 1
\end{array}\right)
\,+\,
(\sin\theta)
\left(\begin{array}{cc}
0 & -1 \\
1 & 0
\end{array}\right)
$$
And we get the matrix form for 2D rotations:
$$
\boxed{\mbox{$~$}\\~~~~~~
\vR_\theta
~~=~~
\left(\begin{array}{cc}
\cos\theta & -\sin\theta \\
\sin\theta & \cos\theta
\end{array}\right)
~~~~~~}
$$
thus we arrive to the matrix form for 2D rotations.
Rotations in 3D
Cross product operator
In a 3D vector space, for any given vector $\vfw$, there are infinitelly many vectors perpendicular
to $\vfw$ and with the same length as $\vfw$ (all those form a circunference in the plane perpendicular to $\vfw$).
To select one of those perpendicular vectors, we must use a third vector $\vfk$ (non colinear with $\vfw$), and compute
the cross product of $\vfk$ and $\vfw$. Then, vector $\vfk\times\vfw$ is perpendicular to $\vfw$ (but not neccesarly
with the same length as $\vfw$).
We define the lineal operator $\mP_\vfk$ (the cross product operator) by his action on $\vfv$ as:
$$
\mP_\vfk\,\vfv ~~\equiv~~ \vfk\times\vfv
$$
Cross product matrix
If $\vk=(a_0,a_1,a_2)^T$ are the coordinates of $\vfk$, and $\vw=(b_0,b_1,b_2)$ are the coordinates
of $\vfw$, then the coordinates of $\vfk\times\vfw$ can be defined as:
$$
\vk\times\vw
~~=~~
\left(\begin{array}{c}
a_0 \\ a_1 \\ a_2
\end{array}\right)
\times
\left(\begin{array}{c}
b_0 \\ b_1 \\ b_2
\end{array}\right)
~~=~~
\left(\begin{array}{c}
a_1b_2-a_2b_1 \\
a_2b_0-a_0b_2 \\
a_0b_1- a_1b_0
\end{array}\right)
$$
Thus cross-product operation (pre-multiplying by $\vk$), can also be written as a linear matrix operation by using matrix $\vP_\vk$
defined as follows:
$$
\vP_\vk ~~=~~
\left(\begin{array}{c}
0 & -a_2 & a_1 \\
a_2 & 0 & -a_0 \\
-a_1 & a_0 & 0
\end{array}\right)
$$
It is easy to check that pre-multiplying $\vk$ by $\vw$ is the same as to apply $\vP_\vk$ to $\vw$
$$
\vP_\vk\vw
~~=~~
\left(\begin{array}{c}
0 & -a_2 & a_1 \\
a_2 & 0 & -a_0 \\
-a_1 & a_0 & 0
\end{array}\right)
\left(\begin{array}{c}
b_0 \\ b_1 \\ b_2
\end{array}\right)
~~=~~
\left(\begin{array}{c}
a_1b_2-a_2b_1 \\
a_2b_0-a_0b_2 \\
a_0b_1- a_1b_0
\end{array}\right)
~~=~~
\vk\times\vw
$$
An additional perpendicular binary operation
In 3D we introduce here an additional perpendicular non-conmutative binary lineal operation $\operV$. If we assume
that $\vfu$ is a unit-length vector in 3D, then for any arbitrary vector $\vfv$
we can define vector $\vfv\boperV\vfu$ as:
$$
\begin{equation}
\vfv\boperV\vfu ~~\equiv~~ \vfu\times(\vfv\boper\vfu)
\end{equation}
$$
Vector $\vfv\boperV\vfu$ is perpendicular to both $\vfu$ and $\vfv$, and has the same
length as $\vfv\boper\vfu$. It can be rewritten as a cross product:
$$
\vfv\boperV\vfu ~~\equiv~~ \vfu\times(\vfv\boper\vfu)
~~=~~ \vfu\times(\vfv\,-\,\vfv\bopar\vfu) ~~=~~ \vfu\times\vfv ~~=~~ \mP_\vfu\,\vfv
$$
this holds because $\vfu$ is colinear with $\vfv\bopar\vfu$, thus their cross-product is the null vector.
Rotations in 3D and Rodrigues formula
In 3D the vector lineal rotation operator $\mR_{\theta,\vfu}$ uses an arbitrary rotation axis which
is determined by the unit length vector $\vfu$. The rotation operation
does not modifies the $\vfv$ component parallel to $\vfu$, and transform its perpendicular
component in a similar way as 2D rotation (but now in the plane perpendicular to $\vfu$).
Thus, we define:
$$
\begin{equation}
\mR_{\theta,\vfu}\vfv ~~\equiv~~
(\vfv\bopar\vfu) \,+\, (\cos\theta)(\vfv\boper\vfu) \,+\, (\sin\theta)(\vfv\boperV\vfu)
\end{equation}
$$
By expanding the definitions of operators $\oper$ and $\operV$) we get:
$$
\begin{align*}
\mR_{\theta,\vfu}\vfv
~~&=~~ \vfv\bopar\vfu \,+\, (\cos\theta)\vfv\boper\vfu \,+\, (\sin\theta)\vfv\boperV\vfu \\
&=~~ \vfv\bopar\vfu \,+\, (\cos\theta)\left[\vfv-(\vfv\bopar\vfu)\right] \,+\, (\sin\theta)\vfu\times\vfv \\
&=~~ (\cos\theta)\vfv \,+\, (1-\cos\theta)\vfv\bopar\vfu \,+\, (\sin\theta)\vfu\times\vfv
\end{align*}
$$
Finally, by expanding $\vfv\bopar\vfu$ we get Rodrigues' rotation formula:
$$
\boxed{\mbox{}\\~~~~~~
\mR_{\theta,\vfu}\vfv
~~=~~ (\cos\theta)\vfv \,+\, (1-\cos\theta)(\vfu\cdot\vfv)\vfu \,+\, (\sin\theta)\vfu\times\vfv
~~~~~~}
$$
Rotation using cross-products. Operator form.
We can express Rodrigues formula in terms of cross-products. We begin by using $\operV$ definition
to rewrite $\vfv\boper\vfu$ as follows:
$$
\vfv\boper\vfu ~~=~~ (\vfv\boperV\vfu)\times\vfu
~~=~~ -\vfu\times(\vfv\boperV\vfu)
~~=~~ -\vfu\times(\vfu\times\vfv)
$$
This allows to write $\vfv\bopar\vfu$ by using cross-products:
$$
\vfv\bopar\vfu ~~=~~ \vfv \,-\, \vfv\boper\vfu
~~=~~ \vfv \,+\, \vfu \times(\vfu\times\vfv)
$$
Now we expand these two equalities. Vector $\vfv\bopar\vfu+(\cos\theta)\vfv\boper\vfu$ is expressed as follows:
$$
\begin{align*}
\vfv\bopar\vfu+(\cos\theta)\vfv\boper\vfu
~~&=~~ \vfv\bopar\vfu \,+\, (\cos\theta)(\vfv-\vfv\bopar\vfu) \\
&=~~ (\cos\theta)\vfv \,+\, (1-\cos\theta)\vfv\bopar\vfu \\
&=~~ (\cos\theta)\vfv \,+\, (1-\cos\theta)[\vfv \,+\, \vfu \times (\vfu\times\vfv)] \\
&=~~ \vfv \,+\,(1-\cos\theta)\vfu \times (\vfu\times\vfv)
\end{align*}
$$
Now Rodrigues formula can be written by using just cross-products:
$$
\begin{equation}
\mR_{\theta,\vfu}\vfv
~~=~~ \vfv \,+\,(1-\cos\theta)\vfu \times (\vfu\times\vfv) \,+\, (\sin\theta)\vfu\times\vfv
\end{equation}
$$
Finally, by using the definition of operator $\mP_\vfu$, we get an operator-only definition of the rotation
$$
\mR_{\theta,\vfu} ~~=~~ \mI \,+\,
(\sin\theta)\mP_\vfu \,+\,
(1-\cos\theta)\mP^2_\vfu
$$
Matrix form
The operator expression for the rotation operator can be directly translated to a matrix expression:
$$
\boxed{\mbox{}\\~~~~~~
\vR_{\theta,\vu} ~~=~~ \vI \,+\, (\sin\theta)\vP_\vu \,+\,(1-\cos\theta)\vP^2_\vu
~~~~~~}
$$
where
$$
\vP_\vu ~~=~~
\left(\begin{array}{c}
0 & -u_2 & u_1 \\
u_2 & 0 & -u_0 \\
-u_1 & u_0 & 0
\end{array}\right)
~~~~~~~~~\mbox{when}~~~
\vu\,=\,\left(\begin{array}{c}
u_0 \\ u_1 \\ u_2
\end{array}\right)
$$.
If we expand $\vP^2_\vu$ we get:
$$
\vP^2_\vu ~~=~~
\left(\begin{array}{c}
0 & -u_2 & u_1 \\
u_2 & 0 & -u_0 \\
-u_1 & u_0 & 0
\end{array}\right)
\left(\begin{array}{c}
0 & -u_2 & u_1 \\
u_2 & 0 & -u_0 \\
-u_1 & u_0 & 0
\end{array}\right)
~~=~~
\left(\begin{array}{c}
u_0^2-1 & u_0u_1 & u_0u_2 \\
u_0u_1 & u_1^2-1 & u_1u_2 \\
u_0u_2 & u_1u_2 & u_2^2-1
\end{array}\right)
$$
where we have used $u_0^2+u_1^2+u_2^2=1$.
By expanding the matrices we get:
$$
\vR_{\theta,\vu} ~~=~~
\left(\begin{array}{c}
1 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 1
\end{array}\right)
\,+\,(\sin\theta)
\left(\begin{array}{c}
0 & -u_2 & u_1 \\
u_2 & 0 & -u_0 \\
-u_1 & u_0 & 0
\end{array}\right)
\,+\,
(1-\cos\theta)
\left(\begin{array}{c}
u_0^2-1 & u_0u_1 & u_0u_2 \\
u_0u_1 & u_1^2-1 & u_1u_2 \\
u_0u_2 & u_1u_2 & u_2^2-1
\end{array}\right)
$$
And finally:
$$
\vR_{\theta,\vu}
~~=~~
\left(\begin{array}{c}
(1-c)u_0^2+c & (1-c)u_0u_1-su_2 & (1-c)u_0u_2+su1 \\
(1-c)u_0u_1+su_2 & (1-c)u_1^2+c & (1-c)u_1u_2-su_0 \\
(1-c)u_0u_2-su_1 & (1-c)u_1u_2+su_0 & (1-c)u_2^2+c
\end{array}\right)
~~~~~~~\mbox{where:}~~~
\left\{\begin{array}{l}
s \,=\, \sin\theta \\
c \,=\, \cos\theta
\end{array}\right.
$$
More compactly:
$$
\boxed{~\\~~~~~~
\vR_{\theta,\vu}
~~=~~
\left(\begin{array}{c}
a_{00}+c & a_{01}-su_2 & a_{02}+su1 \\
a_{10}+su_2 & a_{11}+c & a_{12}-su_0 \\
a_{20}-su_1 & a_{21}+su_0 & a_{22}+c
\end{array}\right)
~~~~~~~~~~\mbox{where:}~~~
\left\{\begin{array}{l}
s \, = \, \sin\theta \\
c \, = \, \cos\theta \\
a_{ij} \, = \, (1-c)u_iu_j
\end{array}\right.
~~~~~~\\\mbox{}}
$$
(this page uses MathJax)