private void rotateImage(int[,] board, int k)
{
int m = board.GetLength(0), n = board.GetLength(1);
int cycleM = m, cycleN = n;
while(cycleM > 1)
{
int oX = (m - cycleM) / 2, oY = (n - cycleN) / 2;
int[] xy = new int[2] { oX, oY };
int tmp = board[xy[0], xy[1]];
int[] nextXY = getNextXY(xy, m, n, cycleM, cycleN, k);
while(nextXY[0] != oX || nextXY[1] != oY)
{
tmp = tmp ^ board[nextXY[0], nextXY[1]] ^ (board[nextXY[0],
nextXY[1]] = tmp);
nextXY = getNextXY(nextXY, m, n, cycleM, cycleN, k);
}
board[oX, oY] = tmp;
cycleM -= 2;
cycleN -= 2;
}
}
private int[] getNextXY(int[] xy, int boardM, int boardN, int cycleM, int
cycleN, int k)
{
int minX = (boardM - cycleM) / 2, minY = (boardN - cycleN) / 2;
int maxX = minX + cycleM - 1, maxY = minY + cycleN - 1;
int[] newXY = new int[2] { xy[0], xy[1] };
k %= 2 * (cycleM + cycleN - 2); // If K is greater than 1 full cycle,
limit it in 1 cycle
if (k >= cycleM + cycleN - 2) // If K is greater than half a full
cycle, rotate half a cycle
{
newXY = new int[2] { boardM - xy[0] - 1, boardN - xy[1] - 1 };
k -= cycleM + cycleN - 2;
}
//Craw the edge step by step in half a cycle
while(k-- > 0)
if (newXY[0] == minX && newXY[1] != maxY) newXY[1]++;
else if (newXY[1] == maxY && newXY[0] != maxX) newXY[0]++;
else if (newXY[0] == maxX && newXY[1] != minY) newXY[1]--;
else if (newXY[1] == minY && newXY[0] != minX) newXY[0]--;
return newXY;
}