I wasn’t able to find anything on the following topic, since most questions asked to rotate the array around 90°, 180°, 270°, which would be to easy actually.
I need to turn a matrix for all possible kinds of degrees, like as if I rotate an image in photoshop (programmatically, I don’t need a GUI or something similar for this). This will lead to small errors in the result, which won’t bother much.
Picture rotating should be a quite similar approach, so I think there should be tons of solutions to this problem. Is there an easy way in java to do this or do I have to calculate the position for every entry by myself?
Note: The array I’m using is a “binary” array, filled with Integers that are of the value “0” and “1”.
PS: This will change the size of the “bounding box” around the matrix. This is no problem at this point.
Edit: I try to give an example how this could look like:
Initial:
{ 0, 0, 1, 0 }
{ 0, 0, 1, 0 }
{ 0, 0, 1, 0 }
{ 0, 0, 1, 0 }
{ 0, 0, 1, 0 }
{ 0, 0, 1, 0 }
Rotate 20.12° at the rotation point [3][2].
Result:
{ 0, 0, 0, 1 }
{ 0, 0, 1, 0 }
{ 0, 0, 1, 0 }
{ 0, 0, 1, 0 }
{ 0, 0, 1, 0 }
{ 0, 1, 0, 0 }
This looks extremely useless, but the more the size of this matrix is, the more accurate those results will be. I work with matrices much bigger than this example. 🙂
2
Answers
I would write two methods: one to convert your array to a BufferedImage and one the other way around. Both things should be easy to implement. The BufferedImage can be rotated with AffineTransform etc.
Not very elegant but to do with standard java code without third party stuff.
And you got images to show the result graphically.
This implementation does the things mentioned above:
As already pointed out and discussed in the comments, there are some degrees of freedom when implementing this.
Particularly, in some cases, it’s simply not clear what should happen. First of all, the “bounds” of the array will change when it is rotated. Then, you’ll encounter aliasing artifacts, when one entry of the input array lies exactly between two cells of the output array after the rotation.
However, disregarding these minor questions, there are basically only two solutions for this:
“Forward-mapping”:
For each cell of the input array, one can compute the rotated position of the cell, and write the value from the input cell into this rotated position of the output array.
“Backward-mapping”:
For each cell of the output array, one can compute the position that this cell had in the input array, and fetch the value from there.
In both cases, the rotation could simply be done using an
AffineTransform
that rotates about a certain point.From a practical point of view, this does not make much difference – as long as the resolution (that is, the size in this case) of both arrays is the same! There will, however, be differences regarding the aliasing artifacts: While the “forward” method may occasionally “swallow” points (and place a 0 where you’d expect a 1), the backward method may occasionally place a 1 where you’d expect a 0.
The implementation of both methods might then simply look like this: