You are on page 1of 5

Derivation of 3d rotation matrix:

rotation of vector r theta degrees and around vector n and becoming vector s
rp = r-parallel = n * r = sp = s-parrallel = n*s (since rotation doesnt change length)
rPerp = r-Perpendicular and sPerp = s-Perpendicular

Find s:
Since I know r, the goal is to get everything in terms of r.
s = sp + sPerp =>
s = rp + sPerp
To find sPerp, lets create a plane that sPerp is on with two basis that I know.
I can get one (call it V) by doing a cross product () with n and rPerp, which will produce a vector that
is perpendicular to rPerp and n. So our two new basis can be rPerp and this new vector V.

with some good old trig I get:


sPerp = |sPerp|*cos()*unit_rPerp + |sPerp|*sin()*unit_v
Since sPerp and rPerp are on a circle, I know that their lengths are the same. Also I know the length of
V is the same as rPerp because of a property of the cross product. Namely, |n rPerp| = |n|*|rPerp|
*sin(alpha), ns length is one and the angle betIen them is 90 degrees and sin(90)=1, thus |V|=|rPerp|
This lets us write sSperp like this:
sPerp = |rPerp|*cos()*unit_rPerp + |v|*sin()*unit_v
sPerp = cos()*rPerp + sin()*V

Rewrite s:
s = rp + cos()*rPerp + sin()*V
before I write everything in terms of r, note that (n rPerp) is equal to
(n (r-rp)) => (nr - nrp) and since rp is in the same direction as n, nrp is the 0 vector, and Ire left
with nr. so V is also nr!
s = (n r)* n + cos()*(r - (n r)* n) + sin()*( nr)
Using the tensor product I can rewrite (n r)* n as M*r, where M is matrix that when multiplied with r
produces (n r)* n.
r = (rx,ry,rz) and n= (nx,ny,nz)
(n r)*n=((rx*nx+ry*ny+rz*nz)*nx, (rx*nx+ry*ny+rz*nz)*ny, (rx*nx+ry*ny+rz*nz)*nz)
(rx*nx*nx+ry*ny*nx+rz*nz*nx, rx*nx*ny+ry*ny*ny +rz*nz*ny,
rx*nx*nz+ry*ny*nz +rz*nz*nz)
=>

nx ^ 2
nx * ny

nx * nz

nx * ny
ny ^ 2
ny * nz

nx * nz
ny * nz
nz ^ 2

0
0
0

rx
ry

rz

1 0

= M*r

so now I have:
s = M*r + cos()*(r - M*r) + sin()*( nr)
s = M*r + cos()*r cos()*M*r + sin()*( nr)
s = (1-cos())*M*r + cos()*r + sin()*( nr)
Next Ill write nr also as a matrix (say P) multiplied by r.
ny * rz nz * ry

nr = nz * rx nx * rz
nx * ry ny * rx

0
nz
=>
ny

nz
0
nx
0

ny
nx
0
0

0
0
0

rx
ry

=P*r
rz

So now I have:
s = (1-cos())*M*r + cos()*r + sin()* P*r
since (1-cos), cos and sin are scalars, simply make them scalar matrices!
s= [(1-cos())*M + cos()*I + sin()* P]*r
Rotation Matrix = [(1-cos())*M + cos()*I + sin()* P]
Which is:

(1 cos( )) * nx ^ 2 cos( )
(1 cos( )) * nx * ny nz * sin( ) (1 cos( )) * nx * nz ny * sin( )
(1 cos( )) * nx * ny nz * sin( )
(1 cos( )) * ny ^ 2 cos( )
(1 cos( )) * ny * nz nx * sin( )

(1 cos( )) * nx * nz ny * sin( ) (1 cos( )) * ny * nz nx * sin( )


(1 cos( )) * nz ^ 2 cos( )

0
0
0

0
0
0
1

nx ^ 2 (1 nx ^ 2) * cos( )
(1 cos( )) * nx * ny nz * sin( ) (1 cos( )) * nx * nz ny * sin( )
(1 cos( )) * nx * ny nz * sin( )
ny ^ 2 (1 ny ^ 2) * cos( )
(1 cos( )) * ny * nz nx * sin( )

(1 cos( )) * nx * nz ny * sin( ) (1 cos( )) * ny * nz nx * sin( )


nz ^ 2 (1 nz ^ 2) * cos( )

0
0
0

0
0
0
1

=>

thus I have the Rotation matrix!

Note: If I plug in the basis vectors from the 3D Cartesian coordinate system Ill get the three rotation
matrices that rotate about an axis.
Put n = {0,0,1} in and we get:

0^ 2 (1 0^ 2) * cos( )
(1 cos( )) * 0 * 0 1 * sin( )

(1 cos( )) * 0 *1 0 * sin( )

=>

cos( )
sin( )

sin( )
cos( )
0
0

0
0
1
0

Put n = {0,1,0} in and we get:

=>

cos( )

sin( )

0
1
0
0

sin( )
0
cos( )
0

(1 cos( )) * 0 *1 0 * sin( )
(1 cos( )) * 0 *1 0 * sin( )
1^ 2 (1 1^ 2) * cos( )
0

0
0
0

0
0
=> which is the Rotation matrix about the z axis!
0

0^ 2 (1 0^ 2) * cos( )
(1 cos( )) * 0 *1 0 * sin( )

(1 cos( )) * 0 * 0 1 * sin( )

(1 cos( )) * 0 * 0 1 * sin( )
0^ 2 (1 0^ 2) * cos( )
(1 cos( )) * 0 *1 0 * sin( )
0

(1 cos( )) * 0 *1 0 * sin( )
1^ 2 (1 1^ 2) * cos( )
(1 cos( )) *1 * 0 0 * sin( )
0

(1 cos( )) * 0 * 0 1 * sin( )
(1 cos( )) *1 * 0 0 * sin( )
0^ 2 (1 0^ 2) * cos( )
0

0
0
=> which is the Rotation matrix about the y axis!
0

0
0
0

Put n = {1,0,0} in and we get:

1^ 2 (1 1^ 2) * cos( )
(1 cos( )) *1 * 0 0 * sin( )

(1 cos( )) *1 * 0 0 * sin( )

(1 cos( )) *1 * 0 0 * sin( )
0^ 2 (1 0^ 2) * cos( )
(1 cos( )) * 0 * 0 1 * sin( )
0

(1 cos( )) *1 * 0 0 * sin( )
(1 cos( )) * 0 * 0 1 * sin( )
0^ 2 (1 0^ 2) * cos( )
0

=>

1
0

0
cos( )
sin( )
0

0
sin( )
cos( )
0

0
0
=> which is the Rotation matrix about the x axis!
0

Note: That if you rotate - degrees about n you will have the same rotation as rotating degrees about n.

Put your eye at Q and rotate + degrees is counterclockwise and - degrees is clockwise, and you will be
doing the same rotation.
Proposition to Get Rid of Trig and Square Root calls
If I know vector s (the final vector from the rotation) then I can easily get rid of the trig and square roots.
Let vector V = rs and remember that vector n=rs/(|rs|)
Cos()=rs/(|r|*|s|), |r|=1, |s|=1 => Cos()=rs
Sin()=|rs|/(r||*|s|), |r|=1, |s|=1 => Sin()=|rs|
|V|=|rs|= V .x ^ 2 V . y ^ 2 V .z ^ 2 =Sin()
VV= V .x ^ 2 V . y ^ 2 V .z ^ 2
n.x =

V .x
V .y
V .z
, n.y =
, n.z =
|V |
|V |
|V |

V .x * V .x
V .x * V .x
=>
,
|V |*|V |
V V
V .x * V . y
V .x * V . y
n.x*n.y =
=>
,
|V | *|V |
V V
n.x*n.x =

n.z*Sin() =

V .z
V .z
*|rs| =>
*|V| => V.z
|V |
|V |

V . y *V . y
V .z * V .z
, n.z*n.z =
,
V V
V V
V .x * V .z
V . y * V .z
n.x*n.z =
, n.y*n.z =
V V
V V
n.y*n.y =

0
0
0

n.y*Sin() => V.y


n.x*Sin() => V.x
Now I can rewrite the rotation matrix in terms of vector V, which will be without trig and square roots.

V .x * V .x
V .x * V .x
V V (r s ) * (1 V V )

(1 (r s )) * V .x *V . y V .z

V V

V
.
x
*
V
.
z

(1 (r s )) *
V .y
V V

V .x * V . y

V .z
V V

V . y *V . y
V . y *V . y
(r s ) * (1
)

V V
V V
V . y * V .z

V .x
(1 (r s)) *
V V

0
(1 (r s)) *

V .x * V .z
V V

V . y * V .z

(1 (r s )) *
V V

V
V .z * V .z
(r s ) * (1

V V
0
(1 (r s )) *

You might also like