Imagine you have a point \(p\) which you want to rotate at an angle \(\theta\) around a point \(c\) as shown in the following figure.
The first step is to know how to rotate a point around the origin because when you know how to do that, you will be able to rotate a point \(p\) around another point \(c\) in the new coordinate system whose origin is \(c\).
In 2D, we can define the point \(p'\), the point p rotated around the origin by an angle \(\theta\) (\(\theta\) measured counter-clockwise) as follows :
To see why this is the case, we will reason about \(p\) and \(p'\) as complex numbers. There is a natural one to one correspondence between the 2D plane and the set of complex numbers. A point \(p = (x, y)\) corresponds to the complex number \(x + i y\).
We know that complex number can be expressed as \(x + i y = \rho e^{i \theta}\) where \(\rho\) is the distance to the origin and \(\theta\) is the angle between the x-axis and the segment connecting the origin to point \((x, y)\).
The reason why this expression is useful is that multiplications behaves as expected, that is,
This means that the result of multiplying two complex numbers is a complex number whose distance to the origin is the product of the distances of the two input numbers and the angle is the addition. This is show in the following figure.
Therefore, in particular, to rotate a point \((x, y)\) of an angle \(\theta\) around the origin we simply need to multiply the complex number \(x + i y\) by \(e^{i \theta}\). The reason why this works is that if we write \(x + i y = \rho e^{i \alpha}\) for some \(\rho\) and \(\alpha\) then
Which is exacly the same point except that we added \(\theta\) to the angle. The next figure illustrates this.
Finally, to deduce the above formulas for the roation we simply need to compute the expression of \(x' + iy' = (x + i y) \cdot e^{i\theta}\) by remembering that \(e^{i\theta} = \cos \theta + i \sin \theta\). and \(i^2 = -1\):
So that
To rotate a point p around another point c, we need to rotate the point p expressed in the coordinate system whose origin is c (it simply is \(p-c\)), and then we just need to express the result in the initial coordinate system (whose origin is (0,0)).
This gives us the following formula (if we define \(p' = p'_x + p'_yi\)):
or :
Note : similar computations (with a different result) could be done for an angle measured clockwise. In fact, we would just have to change \(\theta\) into \(-\theta\).
In Java, we can easily implement these functions as follows.
static Point rotate(Point p, double a) { return new Point(p.x * Math.cos(a) - p.y * Math.sin(a), p.x * Math.sin(a) + p.y * Math.cos(a)); } static Point rotate(Point p, Point c, double a) { return new Point(c.x + (p.x - c.x) * Math.cos(a) - (p.y - c.y) * Math.sin(a), c.y + (p.x - c.x) * Math.sin(a) + (p.y - c.y) * Math.cos(a)); }