Nathan Reed

Blog Stuff I’ve Made Talks About Me
Numerically Modeling The Expansion Of The UniverseGPU Profiling 101

Rotations And Infinitesimal Generators

September 18, 2011 · Math · 6 Comments

In this post I’d like to talk about rotations in three-dimensional space. As you can imagine, rotations are pretty important transformations! They commonly show up in physics as an example of a symmetry transformation, and they have practical applications in fields like computer graphics.

Like any linear transformation, rotations can be represented by matrices, and this provides the best representation for actually computing with vectors, transformations, and suchlike. Various formulas for rotation matrices are well-known and can be found in untold books, papers, and websites, but how do you actually derive these formulas?

If you know a little trigonometry, you can work out the 2D rotation matrix formula by drawing a diagram like this:

2D Rotation

The rotation takes the vector (1,0)(1, 0)(1,0) to (cos⁡θ,sin⁡θ)(\cos \theta, \sin \theta)(cosθ,sinθ) and the vector (0,1)(0, 1)(0,1) to (−sin⁡θ,cos⁡θ)(-\sin \theta, \cos \theta)(−sinθ,cosθ). This is just what we need, since in a matrix the first column is just the output when you put in a unit vector along the xxx-axis; the second column is the output for a unit vector along the yyy-axis, and so on. So the 2D rotation matrix is: R2D(θ)=[cos⁡θ−sin⁡θsin⁡θcos⁡θ]. R_{2D}(\theta) = \begin{bmatrix} \cos \theta & -\sin \theta \\ \sin \theta & \cos \theta \end{bmatrix}. R2D​(θ)=[cosθsinθ​−sinθcosθ​]. You can expand this 2×2 matrix into a 3×3 one and rearrange a few things to get rotations around the xxx, yyy, and zzz axes. That’s all well and good, but what if you want a rotation around some other axis, one that’s not lined up with xxx, yyy, or zzz? Trying to figure out that formula directly with trigonometry is probably hopeless!

One way to do it is to combine rotations together to achieve the desired result. We could do something like: work out the polar coordinates of the axis we want to rotate around, then apply some rotations around the yyy and zzz axes that take that axis onto the xxx-axis. Then do an xxx-rotation by your desired angle, and then revert our yyy and zzz rotations to get the axis back to where it was.

That will work, but it’s inelegant. Since this is a blog about theoretical stuff, I’m going to talk about a more elegant way to do it, using a thing called an infinitesimal generator!

The basic idea of this is to first work out the formula for an infinitesimal rotation - a rotation by a very small angle. What’s the advantage of this? Everything’s simpler in infinitesimals, because you’re allowed to simply ignore things that are “too small to matter”. Infinitesimal math lets you make fantastically crude approximations and not worry about it because eventually, you’re going to take the limit as the infinitesimal thing goes to zero, and in that limit your approximation becomes exact! In this case (and I’m giving away a bit of the story here), once we know the formula for an infinitesimal rotation, we’ll integrate it to get the formula for a finite rotation.

Let’s return to the diagram above, but now consider a rotation by an infinitesimal angle dθd\thetadθ. Imagine taking the Cartesian coordinate system and just barely starting to turn it counter-clockwise. What happens to the point (1,0)(1, 0)(1,0)? It goes straight up! Eventually, if you keep rotating, it’ll start to curve over to the left…but since this is just an infinitesimal rotation, it doesn’t have time to do that.

Surely, you say, it doesn’t go straight up? It must go a little to the left, mustn’t it? Yes, it does…but this is one of those “too small to matter” things that you can just ignore! The smaller dθd\thetadθ is, the closer to straight-up the point goes, and that justifies treating it as if it just goes straight up all the time.

An analogous thought process about the point (0,1)(0, 1)(0,1) reveals that it goes straight to the left, neither up nor down (within our approximation). Here’s the diagram again, modified with these observations:

2D Infinitesimal Rotation

As before, the effect of the rotation on these two points is all we need to get the matrix for an infinitesimal rotation: r2D(dθ)=[1−dθdθ1]. r_{2D}(d\theta) = \begin{bmatrix} 1 & -d\theta \\ d\theta & 1 \end{bmatrix}. r2D​(dθ)=[1dθ​−dθ1​]. (I’m using lowercase letters, e.g. r2D(dθ)r_{2D}(d\theta)r2D​(dθ) for infinitesimal transformations, and uppercase letters like R2D(θ)R_{2D}(\theta)R2D​(θ) for finite ones.) Anyway, this looks a lot simpler than the first matrix we found, and we didn’t need any trigonometry to work it out!

Conceptually, what we need to do next is accumulate the effect of many successive infinitesimal rotations, to get a finite rotation. Technically, this is going to be accomplished by integration. But before we can integrate anything, we need a differential equation, so we have to fiddle with the formula a bit to get it into that shape. Let’s start with a vector u⃗\vec uu and apply the infinitesimal rotation to it; that’ll cause u⃗\vec uu to change by some small vector du⃗d\vec udu: u⃗+du⃗=r2D(dθ)u⃗du⃗=[r2D(dθ)−I]u⃗du⃗dθ=[0−110]u⃗≡G2Du⃗. \begin{aligned} \vec u + d\vec u &= r_{2D}(d\theta) \vec u \\ d\vec u &= \bigl[ r_{2D}(d\theta) - I \bigr] \vec u \\ \dfrac{d\vec u}{d\theta} &= \begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix} \vec u \equiv G_{2D} \vec u. \end{aligned} u+dududθdu​​=r2D​(dθ)u=[r2D​(dθ)−I]u=[01​−10​]u≡G2D​u.​ (In the second line there, III is the identity matrix.) Now we have a differential equation that tells us how u⃗\vec uu changes with θ\thetaθ for very small values of θ\thetaθ. The matrix in the last line, which I’m naming G2DG_{2D}G2D​, is the “infinitesimal generator” of 2D rotation! It’s a matrix that converts a vector into its derivative with respect to infinitesimal rotations.

The Exponential Map

At this point, we need to take a short detour into the world of differential equations. We have a differential equation in which the derivative of a vector, u⃗\vec uu, is equal to a matrix multiplied by u⃗\vec uu itself. This looks very similar to a famous differential equation about real numbers: dydx=ky, \dfrac{dy}{dx} = ky, dxdy​=ky, whose solution is the exponential function, y(x)=y0ekxy(x) = y_0 e^{kx}y(x)=y0​ekx (where y0y_0y0​ is a constant of integration, which equals y(0)y(0)y(0)). Working purely by analogy, we might hypothesize that the solution to our original differential equation is: u⃗(θ)=R2D(θ)u⃗0=eG2Dθu⃗0. \vec u (\theta) = R_{2D}(\theta) \vec u_0 = e^{G_{2D} \theta} \vec u_0. u(θ)=R2D​(θ)u0​=eG2D​θu0​. Now, instead of the ordinary exponential function on real numbers, we have some kind of exponential of a matrix, where e “raised to the power of” a matrix gives us back another matrix. Does this even make sense? It turns out that it does! This “matrix exponential” is a mathematical entity called the exponential map, a generalization of the exponential function to a broad range of contexts. It obeys many of the same rules as the familiar exponential function, so we can prove that it really does solve our differential equation!

Now we just need to calculate it. One way of defining the ordinary exponential function is by its Taylor series: ex=1+x+x22!+x33!+⋯ e^x = 1 + x + \dfrac{x^2}{2!} + \dfrac{x^3}{3!} + \cdots ex=1+x+2!x2​+3!x3​+⋯ The same Taylor series can be straightforwardly translated to one for the exponential map on matrices! This implies that: R2D(θ)=I+G2Dθ+G2D2θ22!+G2D3θ33!+⋯ R_{2D} (\theta) = I + G_{2D} \theta + G_{2D}^2 \dfrac{\theta^2}{2!} + G_{2D}^3 \dfrac{ \theta^3}{3!} + \cdots R2D​(θ)=I+G2D​θ+G2D2​2!θ2​+G2D3​3!θ3​+⋯ We’ve made some progress. Instead of a differential equation, we now have an infinite series for explicitly calculating a rotation matrix for any angle! We can almost split this into the four individual matrix elements and sum up each series individually - but first we need to see what the integer powers of G2DG_{2D}G2D​ look like.

Let’s just calculate the first few powers and see what happens: G2D=[0−110]G2D2=[−100−1]G2D3=[01−10]G2D4=[1001]G2D5=[0−110] \begin{aligned} G_{2D} &= \begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix} & G_{2D}^2 &= \begin{bmatrix} -1 & 0 \\ 0 & -1 \end{bmatrix} \\ G_{2D}^3 &= \begin{bmatrix} 0 & 1 \\ -1 & 0 \end{bmatrix} & G_{2D}^4 &= \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} \\ G_{2D}^5 &= \begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix} \end{aligned} G2D​G2D3​G2D5​​=[01​−10​]=[0−1​10​]=[01​−10​]​G2D2​G2D4​​=[−10​0−1​]=[10​01​]​ Woah! That’s interesting - the fifth power of G2DG_{2D}G2D​ is the same as G2DG_{2D}G2D​ itself. This means that if we kept going, we’d just generate the same four matrices over and over again. Note also that G2D3=−G2DG_{2D}^3 = -G_{2D}G2D3​=−G2D​, and G2D4=−G2D2G_{2D}^4 = -G_{2D}^2G2D4​=−G2D2​. Not only do the matrices repeat every four powers, they repeat with a sign change every two powers.

This is very similar to the behavior of a couple of other famous Taylor series! sin⁡x=x−x33!+x55!−⋯cos⁡x=1−x22!+x44!−⋯ \begin{aligned} \sin x &= x - \dfrac{x^3}{3!} + \dfrac{x^5}{5!} - \cdots \\ \cos x &= 1 - \dfrac{x^2}{2!} + \dfrac{x^4}{4!} - \cdots \end{aligned} sinxcosx​=x−3!x3​+5!x5​−⋯=1−2!x2​+4!x4​−⋯​ The Taylor series of the sine and cosine functions are the same as that of the exponential function…except that they only include every two powers, and alternate with a sign change each term, with sine taking the odd powers and cosine taking the even powers. (This is the basis of Euler’s formula.)

If we regroup the terms in our series for R2D(θ)R_{2D}(\theta)R2D​(θ) into odd and even, and use the fact that the powers of G2DG_{2D}G2D​ repeat with sign changes, we get: R2D(θ)=(I+G2D2θ22!+G2D4θ44!+⋯ )+(G2Dθ+G2D3θ33!+G2D5θ55!+⋯ )=−G2D2(1−θ22!+θ44!−⋯ )+G2D(θ−θ33!+θ55!−⋯ )=−G2D2cos⁡θ+G2Dsin⁡θ=[cos⁡θ−sin⁡θsin⁡θcos⁡θ]. \begin{aligned} R_{2D}(\theta) &= \left(I + G_{2D}^2 \dfrac{\theta^2}{2!} + G_{2D}^4 \dfrac{\theta^4}{4!} + \cdots \right) \\ &\qquad + \left(G_{2D} \theta + G_{2D}^3 \dfrac{\theta^3}{3!} + G_{2D}^5 \dfrac{\theta^5}{5!} + \cdots \right) \\ &= -G_{2D}^2 \left(1 - \dfrac{\theta^2}{2!} + \dfrac{\theta^4}{4!} - \cdots \right) \\ &\qquad + G_{2D} \left(\theta - \dfrac{\theta^3}{3!} + \dfrac{\theta^5}{5!} - \cdots \right) \\ &= -G_{2D}^2 \cos \theta + G_{2D} \sin \theta \\ &= \begin{bmatrix} \cos \theta & -\sin \theta \\ \sin \theta & \cos \theta \end{bmatrix}. \end{aligned} R2D​(θ)​=(I+G2D2​2!θ2​+G2D4​4!θ4​+⋯)+(G2D​θ+G2D3​3!θ3​+G2D5​5!θ5​+⋯)=−G2D2​(1−2!θ2​+4!θ4​−⋯)+G2D​(θ−3!θ3​+5!θ5​−⋯)=−G2D2​cosθ+G2D​sinθ=[cosθsinθ​−sinθcosθ​].​ This final matrix is the same as in the very first equation in this article, but now we’ve gotten there through a completely different route - we first worked out the generator matrix for an infinitesimal rotation, then we calculated the exponential of that matrix (multiplied by θ\thetaθ) to get the matrix for a finite rotation!

Axis-Angle Rotations in 3D

We can apply the same approach to solve the problem I posed near the top of this article: to find the matrix of a rotation about an arbitrary axis. Let’s identify this axis by a⃗\vec aa, a unit vector pointing along the axis. Our goal is to find an expression for Ra(θ)R_a(\theta)Ra​(θ), the 3×3 matrix that rotates around a⃗\vec aa by an angle θ\thetaθ. As before, we’ll begin by considering an infinitesimal rotation, and working out the generator GaG_aGa​.

Let’s consider the action of a rotation around a⃗\vec aa by an infinitesimal angle dθd\thetadθ on an arbitrary 3D vector u⃗\vec uu. What will happen to u⃗\vec uu? In the infinitesimal approximation, it moves in a direction straight out of the plane containing a⃗\vec aa and u⃗\vec uu, as shown here:

3D infinitesimal rotation around an arbitrary axis

We can express this using the vector cross product: du⃗dθ=a⃗×u⃗. \dfrac{d\vec u}{d\theta} = \vec a \times \vec u. dθdu​=a×u. (Note that the length of the cross product vector is related to the lengths of the two vectors being crossed. I leave it as an exercise for the reader to show that the length of du⃗d\vec udu is correct in the above equation!)

The cross product can also be expressed as a matrix. In this case, we need a matrix that, when multiplied by u⃗\vec uu, gives us a⃗×u⃗\vec a \times \vec ua×u. This will be GaG_aGa​, the infinitesimal generator for rotations around a⃗\vec aa. a⃗×u⃗=[0−azayaz0−ax−ayax0]u⃗=Gau⃗ \vec a \times \vec u = \begin{bmatrix} 0 & -a_z & a_y \\ a_z & 0 & -a_x \\ -a_y & a_x & 0 \end{bmatrix} \vec u = G_a \vec u a×u=⎣⎡​0az​−ay​​−az​0ax​​ay​−ax​0​⎦⎤​u=Ga​u It follows that Ra(θ)=eGaθR_a(\theta) = e^{G_a \theta}Ra​(θ)=eGa​θ, i.e. the rotation matrix we’re trying to find is the exponential of θ\thetaθ times the matrix GaG_aGa​ above! If you work out the first few powers of GaG_aGa​ and use the fact that a⃗\vec aa is a unit vector (so ax2+ay2+az2=1a_x^2 + a_y^2 + a_z^2 = 1ax2​+ay2​+az2​=1), you’ll see that it follows the same pattern that the powers of G2DG_{2D}G2D​ did: they repeat every four powers, and repeat with sign alternation every two, so that Ga3=−GaG_a^3 = -G_aGa3​=−Ga​ and Ga4=−Ga2G_a^4 = -G_a^2Ga4​=−Ga2​. We can almost use the same odd/even term grouping as before to split the series into a part proportional to cos⁡θ\cos \thetacosθ, and a part proportional to sin⁡θ\sin \thetasinθ. However, there is one little bug to deal with. In the 2D version of this derivation, we implicitly used the fact that G2D4=IG_{2D}^4 = IG2D4​=I, the identity matrix, when factoring −G2D2-G_{2D}^2−G2D2​ out of the even terms. Here, Ga4≠IG_a^4 \neq IGa4​=I, so we have to do a little bit of a fixup. Ra(θ)=(I+Ga2θ22!+Ga4θ44!+⋯ )+(Gaθ+Ga3θ33!+Ga5θ55!+⋯ )=I−Ga2(−θ22!+θ44!−⋯ )+Ga(θ−θ33!+θ55!−⋯ )=I−Ga2(cos⁡θ−1)+Gasin⁡θ=I+Ga2(1−cos⁡θ)+Gasin⁡θ \begin{aligned} R_a(\theta) &= \left(I + G_a^2 \dfrac{\theta^2}{2!} + G_a^4 \dfrac{\theta^4}{4!} + \cdots \right) \\ &\qquad + \left(G_a \theta + G_a^3 \dfrac{\theta^3}{3!} + G_a^5 \dfrac{\theta^5}{5!} + \cdots \right) \\ &= I - G_a^2 \left(- \dfrac{\theta^2}{2!} + \dfrac{\theta^4}{4!} - \cdots \right) \\ &\qquad + G_a \left(\theta - \dfrac{\theta^3}{3!} + \dfrac{\theta^5}{5!} - \cdots \right) \\ &= I - G_a^2 (\cos \theta - 1) + G_a \sin \theta \\ &= I + G_a^2 (1 - \cos \theta) + G_a \sin \theta \\ \end{aligned} Ra​(θ)​=(I+Ga2​2!θ2​+Ga4​4!θ4​+⋯)+(Ga​θ+Ga3​3!θ3​+Ga5​5!θ5​+⋯)=I−Ga2​(−2!θ2​+4!θ4​−⋯)+Ga​(θ−3!θ3​+5!θ5​−⋯)=I−Ga2​(cosθ−1)+Ga​sinθ=I+Ga2​(1−cosθ)+Ga​sinθ​ Finally, we can put everything together to get our final rotation matrix: Ra(θ)=[1+(ax2−1)(1−cos⁡θ)axay(1−cos⁡θ)−azsin⁡θaxaz(1−cos⁡θ)+aysin⁡θaxay(1−cos⁡θ)+azsin⁡θ1+(ay2−1)(1−cos⁡θ)ayaz(1−cos⁡θ)−axsin⁡θaxaz(1−cos⁡θ)−aysin⁡θayaz(1−cos⁡θ)+axsin⁡θ1+(az2−1)(1−cos⁡θ)] R_a(\theta) = \begin{bmatrix} 1+(a_x^2-1)(1-\cos\theta) & a_x a_y (1-\cos\theta) - a_z\sin\theta & a_x a_z (1-\cos\theta) + a_y\sin\theta \\ a_x a_y (1-\cos\theta) + a_z\sin\theta & 1+(a_y^2-1)(1-\cos\theta) & a_y a_z (1-\cos\theta) - a_x\sin\theta \\ a_x a_z (1-\cos\theta) - a_y\sin\theta & a_y a_z (1-\cos\theta) + a_x\sin\theta & 1+(a_z^2-1)(1-\cos\theta) \end{bmatrix} Ra​(θ)=⎣⎡​1+(ax2​−1)(1−cosθ)ax​ay​(1−cosθ)+az​sinθax​az​(1−cosθ)−ay​sinθ​ax​ay​(1−cosθ)−az​sinθ1+(ay2​−1)(1−cosθ)ay​az​(1−cosθ)+ax​sinθ​ax​az​(1−cosθ)+ay​sinθay​az​(1−cosθ)−ax​sinθ1+(az2​−1)(1−cosθ)​⎦⎤​ And there it is! Whew! That was a lot of work, but now we have an explicit matrix for arbitrary rotations around any axis in 3D space, and along the way we met a bunch of interesting concepts, such as infinitesimal math, the exponential map, and Taylor series.

Rotations are truly a fascinating set of transformations, and in this post I’ve only just scratched the surface of the interesting structure that they have. Rotations in any number of dimensions form a mathematical entity called a Lie group, and the fact that they can be produced by infinitesimal generators is intimately linked with the special properties of Lie groups! But that’s a topic for a future post.

Numerically Modeling The Expansion Of The UniverseGPU Profiling 101

6 Comments on “Rotations And Infinitesimal Generators”

Subscribe

  • RSS RSS

Recent Posts

  • Reading Veach’s Thesis, Part 2
  • Reading Veach’s Thesis
  • Texture Gathers and Coordinate Precision
  • git-partial-submodule
  • Slope Space in BRDF Theory
  • Hash Functions for GPU Rendering
  • All Posts

Categories

  • Graphics(32)
  • Coding(23)
  • Math(21)
  • GPU(15)
  • Physics(6)
  • Eye Candy(4)
© 2007–2024 by Nathan Reed. Licensed CC-BY-4.0.