Mabadai
Mabadai

Reputation: 355

Rotate 2D array by alpha degrees

I wrote a function which takes two parameters:

  1. JPG image as 3D array

  2. rotation degrees given by alpha My approach was:

    public static int[][] rotate(int[][] img, double alpha) { double rad = Math.toRadians(alpha); double sin = Math.sin(rad); double cos = Math.cos(rad);

     int height = img.length;
     int width = img[0].length;
    
     int[][] rotate = new int[height][width];
    
     for(int i = 0; i < height; i++) {
         for(int j = height - i - 1; j < width; j++) {
    
             if(j < height && i < width) {
    
                 double i_new = Math.floor(cos * (img[i].length - i) - sin * (img[j].length - j)) + i;
                 double j_new = Math.floor(sin * (img[i].length - i) + cos * (img[j].length - j)) + j;
    
                 rotate[i][j] = img[(int)j_new][(int)i_new];
             }
         }
     }
     return rotate;
    

    }

While fixing the index range, the output is a black image. What am I missing?

Upvotes: 2

Views: 136

Answers (1)

Mabadai
Mabadai

Reputation: 355

After a while I got to a solution.

Caution: Its not using any special pre-defined libraries.

The global function which run`s over the matrice:

public static int[][] rotate(int[][] img, double alpha) {

    double rad = Math.toRadians(alpha);                             //construct of the relevant angles
    double sin = Math.sin(rad);
    double cos = Math.cos(rad);

    int height = img.length;
    int width = img[0].length;

    int[][] rotate = new int[height][width];

    int a = height / 2;                                             //we will use the area of a and b to compare coordinates by the formula given
    int b = width / 2;

    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {

            double i_new = Math.floor(cos * (i - a) - sin * (j - b)) + a;       // following the conversion function
            double j_new = Math.floor(sin * (i - a) + cos * (j - b)) + b;

            if (i_new >= rotate.length || i_new < 0 || j_new >= rotate[0].length || j_new < rotate[0][0]) { // if out of scope of the conversion --> print none
                System.out.print("");                                           //mainly cause 'continue' statements are not necessary in java and JS
            } else {
                rotate[(int) i_new][(int) j_new] = img[i][j];                   //convert
            }
        }
    }

    return rotate;
}

The global function which rotates each 2D matrice:

public static int[][][] rotate_alpha(int[][][] img, double alpha) {

    int height = img[0].length;
    int width = img[0][0].length;

    int[][][] rotated = new int[3][height][width];

    for (int k = 0; k < 3; k++) {
        rotated[k] = rotate(img[k], alpha);
    }

    return rotated;
}

Hope this topic is solved by now, and stands by all the standards of the clean code.

Upvotes: 1

Related Questions