First written in 2006.
Last updated 2014-06-29.

Rotate a point, $$(x_1, y_1)$$, around the origin, by the angle $$\phi$$, resulting in a new point, $$(x_2, y_2)$$:

$$\begin{eqnarray*} x_2 & = & x_1 \cos \phi - y_1 \sin \phi\\ y_2 & = & y_1 \cos \phi + x_1 \sin \phi \end{eqnarray*}$$

## How to derive the rotation formulas

Start with a point: $$p_1 = (x_1, y_1)$$

In polar coordinates, this is: $$\begin{eqnarray*} x_1 = r \cos \theta_1\\ y_1 = r \sin \theta_1 \end{eqnarray*}$$

The rotated point will be: $$\begin{eqnarray*} x_2 & = & r \cos \left(\theta_1 + \phi\right) \\ y_2 & = & r \sin \left(\theta_1 + \phi\right) \end{eqnarray*}$$

Remember the trigonometric identities for addition of angles: (we'll get to these later) $$\begin{eqnarray*} \sin \left(a + b\right) & = & \sin a \cos b + \cos a \sin b \\ \cos \left(a + b\right) & = & \cos a \cos b - \sin a \sin b \end{eqnarray*}$$

Substituting these in, we get: $$\begin{eqnarray*} x_2 & = & r \cos \left(\theta_1 + \phi\right) \\ x_2 & = & r \left( \cos \theta_1 \cos \phi - \sin \theta_1 \sin \phi \right) \end{eqnarray*}$$

Using the equations for $$x_1$$ and $$y_1$$, we can simplify this: $$\begin{eqnarray*} x_2 & = & \left( r \cos \theta_1 \right) \cos \phi - \left( r \sin \theta_1 \right) \sin \phi\\ x_2 & = & x_1 \cos \phi - y_1 \sin \phi \end{eqnarray*}$$

Likewise, for $$y_2$$: $$\begin{eqnarray*} y_2 & = & r \sin \left(\theta_1 + \phi\right) \\ y_2 & = & r \left( \sin \theta_1 \cos \phi + \cos \theta_1 \sin \phi \right) \\ y_2 & = & y_1 \cos \phi + x_1 \sin \phi \end{eqnarray*}$$

## How to derive the addition-of-angles formulas

A complex number on the unit circle, in exponential form: $$e^{\theta i} = \cos \theta + i \sin \theta$$

Multiplying two such complex numbers: $$e^{ai} \times e^{bi} = e^{\left(a+b\right)i}$$

So: $$\begin{eqnarray*} e^{\left(a+b\right)i} & = & \cos\left(a+b\right) + i \sin\left(a+b\right) \\ e^{ai} \times e^{bi} & = & \left(\cos a + i \sin a\right) \times\\ & & \left(\cos b + i \sin b\right)\\ & = & \cos a \cos b + i \cos a \sin b +\\ & & i \sin a \cos b - \sin a \sin b\\ \end{eqnarray*}$$

Separating the real and complex components: $$\begin{eqnarray*} \cos\left(a+b\right) & = & \cos a \cos b - \sin a \sin b\\ \sin\left(a+b\right) & = & \cos a \sin b + \sin a \cos b \end{eqnarray*}$$

## Implementation and optimization

Here's a straightforward implementation of rotation in C++:

void rot1(const double x1, const double y1, const double theta,
double* x2, double* y2) {
const double s = sin(theta);
const double c = cos(theta);
*x2 = x1 * c - y1 * s;
*y2 = y1 * c + x1 * s;
}

The above costs 4 multiplies, 1 add, 1 subtract.

We can trade one of the multiplies for 2 adds and 1 subtract:

void rot2(const double x1, const double y1, const double theta,
double* x2, double* y2) {
const double s = sin(theta);
const double c = cos(theta);
const double z = x1 * (s + c);
*x2 = z - (x1 + y1) * s;
*y2 = z + (y1 - x1) * c;
}

The above costs 3 multiplies, 3 adds, 2 subtracts.

If the angle is fixed, there's a further optimization possible:

void rot3(const double x1, const double y1,
double* x2, double* y2) {
const double s = sin(1. * M_PI / 16.);
const double c = cos(1. * M_PI / 16.);
const double z = c * (x1 + y1);
*x2 = (-s-c) * y1 + z;
*y2 = ( s-c) * x1 + z;
}

The above costs 3 multiplies and 3 adds, because -s-c and s-c are turned into constants.

All the code is here: rot.cc

I'm not counting operations by looking at the C++ code, but by looking at the generated assembler. There are instructions and results in the file.