I am implementing a function which gets a input pixel array containing a bitmap, rotate the bitmap by 50 degrees and writes the result into an output pixel array. The output pixel array is shown on screen. I am using a rotation matrix to transform every pixel of the input to the output.
The function which rotates the pixels is implemented the following way:
void rotatePixel(int x, int y, float *new_x, float *new_y)
{
float f_x, f_y;
UWORD i;
f_x = (float)x;
f_y = (float)y;
i = currentDegree / DEGREE_RESOLUTION - 1;
*new_x = (f_x * cosLookup[i] - f_y * sinLookup[i]);
*new_y = (f_x * sinLookup[i] + f_y * cosLookup[i]);
}
The function is invoked for every pixel of the input array. cosLookup
and sinLookup
are lookup tables to speed up calculation. The result for a red square looks like this:
So, the rotation in general is working but there are lots of free spots where no pixel was written to. To find out whats going wrong, I adjusted my program to mark pixels with green and blue colors, if a pixel is projected at coordinates where already a pixel resides. The result looks like this:
I assume this is because of:
round()
leads to the problem from above: Pixels are written on the same x/y coordinate two or more times, while other coordinates in my output array remain emptyMy question is: How can I resolve this issue? I think tools like gimp, Photoshop etc. rotate objects without this problem. I thought about an internal upscaling to be capable of writing the resulting pixels more precisely to their destination. Or maybe applying a filter which smooths the result after transformation?
What if you invert the rotation and calculate backwards
new_x, new_x -> old_x, old_y
That would resolve the rounding errors.
for new_pixel_coordinates:
old_pixel_coordinates = inverse_rotate(new_pixel_coordinates)
color = lookup_color(old_bitmap, old_pixel_coordinates)
color_new_picture(new_bitmap, new_pixel_coordinates, color)