Suppose:
2D array: abcdef
ghijkl
mnopqr
Stored in simple string of length width * height, thus, let’s call it arr.
arr = abcdefghijklmnopqr
width = 6
height = strlen ( arr ) / width
The goal is to rotate this array by 45 degrees ( PI/4 ) and get the following result:
arr = abgchmdinejofkplqr
width = 3
height = 8
converted to 2D array: a..
bg.
chm
din
ejo
fkp
.lq
..r
I have spent a few hours trying to figure out how to make this conversion and came up with a few semi-functional solutions, but I can’t get it fully working. Can you describe / write an algorithm that would solve this? Preferably in C.
Thanks for any help
Edit: This is what I’ve tried already
Edit2: The purpose of 45 degree rotation is to turn diagonals into lines so that they can be searched using strstr.
// this is 90 degree rotation. pretty simple
for ( i = 0; i < width * height; i++ ) {
if ( i != 0 && !(i % height) ) row++;
fieldVertical[i] = field[( ( i % height ) * width ) + row];
}
// but I just can't get my head over rotating it 45 degrees.
// this is what I've tried. It works untile 'border' is near the first edge.
row = 0;
int border = 1, rowMax = 0, col = 0; // Note that the array may be longer
// than wider and vice versa. In that case rowMax should be called colMax.
for ( i = 0; i < width * height; ) {
for ( j = 0; j < border; j++, i++ ) {
fieldCClockwise[row * width + col] = field[i];
col--;
row++;
}
col = border;
row = 0;
border++;
}
The ‘border’ in my code is an imaginary borderline. In the source, it is a diagonal
line that separates diagonals. In the result, it would be a horizontal line between
each row.
1 2 3 / 4 5
6 7 / 8 9 10
11 /12 13 14 15
Those slashes are our borderline.
The algorithm shoul be pretty simple and just read riagonals:
first number 1, then 2, then 6, then 3, then 7, then 11, then 4 and so on.
I’d call this diagonal scanning, not rotation by 45 degrees.
In your example, the diagonals are running down-left; we can enumerate them 1, 2, …:
This will be the counter for the iterations of the outer loop. The inner loop will run 1, 2 or 3 iterations. In order to jump from one numbered symbol to the other, do
col--; row++;like you did, or addwidth-1to a linear index:Code (untested):
If you want to “rotate” in another direction, you may want to change
++to--around the code, and maybe change bound checking in the loops to opposite.In addition, you can replace
(x,y)coordinates by just one index (replacing++ybyindex+=width); i used(x,y)for clarity.