import java.util.Arrays;

/**
 * @author Biao
 * 
 * 在写俄罗斯方块时，可以为每个图形的每种状态都定义一个数组来表示(效率高)。
 * 因为每个图形有四个方向的状态：上右下左，所以每个图形要定义四个数组来表示他的状态。
 * 如果把这些图形都放在一个方阵中，图形的重心为方阵的中心，旋转时绕方阵中心旋转，
 * 则图形的四个方向的状态可以通过旋转方阵来实现，这样为每种图形只需要定义一个状态数组。
 * 而方阵向左或向右旋转 90 度通过算法可以很方便的实现。
 * 
 * 一般的如图像旋转任意角度 delta，也是要放在一个方阵中进行处理，以方阵的中心为坐标轴原心，
 * 然后使用sin, cos计算出旋转后的坐标点，取整。
 * 如图像上某一点离原心的距离为 r, 它的角度为 alpha, 逆时针旋转 delta:
 * x = r * cos(delta + alpha)
 * y = r * sin(delta + alpha)
 * 可以把2D坐标 (x, y) 归一化，变成(x, y, 1)，然后使用上面的公式计算出旋转矩阵来计算更为方便。
 */
public class RotateUtil {
    public static enum Direction { LEFT, RIGHT };
    
    /**
     * 方阵向右或向左旋转90度。
     */
    public static int[][] rotateSquareMatrix(int[][] data, Direction dir) {
        int len = data.length;
        int last = len - 1;
        temp = createTempSquareMatrix(len);
        
        // 代码量换取计算效率
        if (dir == Direction.LEFT) {
            // 向左旋转，第一行变第一列，第二行变第二列
            for (int i = 0; i < len; ++i) {
                for (int j = 0; j < len; ++j) {
                    temp[last - j][i] = data[i][j];
                }
            }
        } else if (dir == Direction.RIGHT) {
            // 向右旋转，第一行变第四列，第二行变第n - 2列
            for (int i = 0; i < len; ++i) {
                for (int j = 0; j < len; ++j) {
                    temp[j][last - i] = data[i][j];
                }
            }
        }
        
        // 复制旋转后的数据
        for (int i = 0; i < len; ++i) {
            for (int j = 0; j < len; ++j) {
                data[i][j] = temp[i][j];
            }
        }
        
        return data;
    }
    
    public static void printMatrix(int[][] data) {
        for (int i = 0; i < data.length; ++i) {
            System.out.println(Arrays.toString(data[i]));
        }
    }
    private static int[][] createTempSquareMatrix(int size) {
        if (temp == null || temp.length != size) {
            temp = new int[size][size];
        }

        return temp;
    }
    
    private static int[][] temp = null;
    
    public static void main(String[] args) {
        // 一般的俄罗斯方式 5 * 5 的方阵正好
        int[][] data = {
                {0, 0, 1, 0, 0},
                {0, 0, 1, 0, 0},
                {0, 0, 1, 1, 0},
                {0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0}
        };
        
        Direction dir = Direction.LEFT;
        String info = "Rotate " + ((dir == Direction.LEFT) ? "left" : "right");
        
        System.out.println("Original Data:");
        printMatrix(data);
        
        System.out.println(info);
        rotateSquareMatrix(data, dir);
        printMatrix(data);
        
        System.out.println(info);
        rotateSquareMatrix(data, dir);
        printMatrix(data);
        
        System.out.println(info);
        rotateSquareMatrix(data, dir);
        printMatrix(data);
        
        System.out.println(info);
        rotateSquareMatrix(data, dir);
        printMatrix(data);
        
        System.out.println("-------------------------------------------");
        dir = Direction.RIGHT;
        info = "Rotate " + ((dir == Direction.LEFT) ? "left" : "right");
        
        System.out.println("Original Data:");
        printMatrix(data);
        
        System.out.println(info);
        rotateSquareMatrix(data, dir);
        printMatrix(data);
        
        System.out.println(info);
        rotateSquareMatrix(data, dir);
        printMatrix(data);
        
        System.out.println(info);
        rotateSquareMatrix(data, dir);
        printMatrix(data);
        
        System.out.println(info);
        rotateSquareMatrix(data, dir);
        printMatrix(data);
    }
}
