I want to apply "whirl" transformation to some images, the name might be a bad choice but that is the name of a similar distortion I found in GIMP.
Basically it is like rotations but the image gets twisted. In normal rotations the angle that is rotated is the same everywhere from the center of rotation, and the relative positions of the points don't change. This means the amount of displacement along the arc is different for points with different distances from the rotational center.
I want the amount of geodesic displacement to be the same for all radii, this means the angles that points on each radius rotated will be different, and the shape would get twisted.
A circle is a full rotation and has length $l = 2 \pi r$, and rotation traces an arc on the circle, and it is obvious that the angle of rotation $\theta$ is proportional to the geodesic displacement $\Delta l$: $\Delta l = \theta r$, so $\theta = \frac{\Delta l} {r}$, because in this transformation $\Delta l$ is constant, points further from the center would rotate less angle and appear to drag behind, and the corners would appear to point to the direction opposite of the transformation.
The parametric equation of rotation is (assuming rotational center coincides with the origin):
$$x_1 = x \cos \theta - y \sin \theta \\ y_1 = x \sin \theta + y \cos \theta $$
So the equation for the transformation I call "whirl" is:
$$x_1 = x \cos (\frac{\Delta l} {\sqrt{x^2 + y^2}}) - y \sin (\frac{\Delta l} {\sqrt{x^2 + y^2}}) \\ y_1 = x \sin (\frac{\Delta l} {\sqrt{x^2 + y^2}}) + y \cos (\frac{\Delta l} {\sqrt{x^2 + y^2}}) $$
$\Delta l$ is constant, the above equation works if the origin is at the center and x increases to the right and y increases to the top, and center of rotation is the origin. But in most programming languages the origin of images is the top left corner and x increases to the right but y increases to the bottom.
I am wondering if there is a way to apply the transformation efficiently, without having to loop through the points one by one and do coordinate translation and then the transformation and then translate the coordinate back. Can I use transformation matrices for this? But as you can see, the transformation isn't linear.
Is there a way I can apply the above transformation programmatically, using clever mathematics, faster than brute force?