3

I have tried to make an algorithm in java to rotate a 2-d pixel array(Not restricted to 90 degrees), the only problem i have with this is: the end result leaves me with dots/holes within the image.


Here is the code :

    for (int x = 0; x < width; x++)
    {
        for (int y = 0; y < height; y++)
        {
            int xp = (int) (nx + Math.cos(rotation) * (x - width / 2) + Math
                    .cos(rotation + Math.PI / 2) * (y - height / 2));
            int yp = (int) (ny + Math.sin(rotation) * (x - width / 2) + Math
                    .sin(rotation + Math.PI / 2) * (y - height / 2));
            int pixel = pixels[x + y * width];
            Main.pixels[xp + yp * Main.WIDTH] = pixel;
        }
    }

'Main.pixels' is an array connected to a canvas display, this is what is displayed onto the monitor.

'pixels' and the function itself, is within a sprite class. The sprite class grabs the pixels from a '.png' image at initialization of the program.


I've tried looking at the 'Rotation Matrix' solutions. But they are too complicated for me. I have noticed that when the image gets closer to a point of 45 degrees, the image is some-what stretched ? What is going wrong? And what is the correct code; that adds the pixels to a larger scale array(E.g. Main.pixels[]).

Needs to be java! and relative to the code format above. I am not looking for complex examples, simply because i will not understand(As said above). Simple and straight to the point, is what i am looking for.


How id like the question to be answered.

  1. Your formula is wrong because ....
  2. Do this and the effect will be...
  3. Simplify this...
  4. Id recommend...

Im sorry if im asking to much, but i have looked for an answer relative to this question, that i can understand and use. But to always either be given a rotation of 90 degrees, or an example from another programming language.

3
  • Show some more code.... i can help... i work on imaging technology... Commented Apr 20, 2015 at 5:27
  • nx and ny are just positioning variables, named nx so it doesn't conflict with x. same goes for ny. Commented Apr 20, 2015 at 6:28
  • Math.cos(rotation + Math.PI / 2) = - Math.sin(rotation).So what do it means for "Rotation" ? Commented Apr 20, 2015 at 7:43

2 Answers 2

4

You are pushing the pixels forward, and not every pixel is hit by the discretized rotation map. You can get rid of the gaps by calculating the source of each pixel instead.

Instead of

for each pixel p in the source
    pixel q = rotate(p, theta)
    q.setColor(p.getColor())

try

for each pixel q in the image
    pixel p = rotate(q, -theta)
    q.setColor(p.getColor())

This will still have visual artifacts. You can improve on this by interpolating instead of rounding the coordinates of the source pixel p to integer values.


Edit: Your rotation formulas looked odd, but they appear ok after using trig identities like cos(r+pi/2) = -sin(r) and sin(r+pi/2)=cos(r). They should not be the cause of any stretching.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your response Douglas, i have edited my question though as i need an answer appropriate to my problem. However, i did change the cos and sin within my code, but that left me with a rotating line,after the removal of '+ Math.PI /2', i get the same result as the wrong rotation formula. I know i may be going at this wrong, but I need an answer that solves the rotation of a 2-d pixel array, with my style of code.
3

To avoid holes you can:

  1. compute the source coordinate from destination

    (just reverse the computation to your current state) it is the same as Douglas Zare answer

  2. use bilinear or better filtering

  3. use less then single pixel step

    usually 0.75 pixel is enough for covering the holes but you need to use floats instead of ints which sometimes is not possible (due to performance and or missing implementation or other reasons)

Distortion

if your image get distorted then you do not have aspect ratio correctly applied so x-pixel size is different then y-pixel size. You need to add scale to one axis so it matches the device/transforms applied. Here few hints:

  • Is the source image and destination image separate (not in place)? so Main.pixels and pixels are not the same thing... otherwise you are overwriting some pixels before their usage which could be another cause of distortion.

  • Just have realized you have cos,cos and sin,sin in rotation formula which is non standard and may be you got the angle delta wrongly signed somewhere so

Just to be sure here an example of the bullet #1. (reverse) with standard rotation formula (C++):

float c=Math.cos(-rotation);
float s=Math.sin(-rotation);
int x0=Main.width/2;
int y0=Main.height/2;
int x1=      width/2;
int y1=      height/2;
for (int a=0,y=0; y < Main.height; y++)
 for (int     x=0; x < Main.width; x++,a++)
  {
  // coordinate inside dst image rotation center biased
  int xp=x-x0;
  int yp=y-y0;
  // rotate inverse
  int xx=int(float(float(xp)*c-float(yp)*s));
  int yy=int(float(float(xp)*s+float(yp)*c));
  // coordinate inside src image
  xp=xx+x1;
  yp=yy+y1;
  if ((xp>=0)&&(xp<width)&&(yp>=0)&&(yp<height))
       Main.pixels[a]=pixels[xp + yp*width]; // copy pixel
  else Main.pixels[a]=0; // out of src range pixel is black
  }

6 Comments

Thank you Spektre for your response, I am interested in reversing the computation, but i am confused in how to do so! May you give an example?
@user3474725 for starters try code from my answer it is C++ I am no JAVA coder but it should be compatible with your code have not changed anything just added standard rotation formula, reverse the computation to avoid holes, added some temp variables and few improvements the only thing that could be different is overtype style between int/float
@user3474725 had an typo in code check it out again (xx,yy)
@user3474725 if you want further improvement then change pixels[xp + yp*width] with bilinear interpolation of pixel from 4 neighboring pixels ...
YEEEEESSSSSSS!!!!!!, thank you so much Spektre. I have been trying to figure this out for sooooo long. Thank you again for all the advice, ill be sure to use it. Thank you thank you XD.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.