1

I use the standard formula to rotate a solid (filled) rectangle/object with pivot point. The image is a on/off byte array.

const uint8_t *srcBuf;
color_t *dstBuf[];
double angle = 25.0;
double roCos = cos(angle);
double roSin = sin(angle);

int16_t src_val;

for(int y = 0; y < src_h; y++) {

    for(int x = 0; x < src_w ; x++) {

        src_val = srcBuf[y * src_w + x];
        if (src_val == 0) { continue; }

        deltaX = (double)(x - src_piv_x);
        deltaY = (double)(y - src_piv_y);

        xp = (int16_t)(deltaX * roCos - deltaY * roSin);
        yp = (int16_t)(deltaX * roSin + deltaY * roCos);

        xp += pivot_x;
        yp += pivot_y;
        if (xp >= 0 && xp < dst_w && yp >= 0 && yp <= dst_h) {
            dstBuf[yp * dst_w + xp] = color ;
        }
    }
}

The image is rotated correctly. However, I get blank dots (regular pattern) inside the rotated rectangle/object. I presume these unfilled dots are because the equation does not produce map 1:1 on the destination due to rounding/precision.

Is there a recommendation to overcome this limitation?

Thanks

alsaleem
  • 347
  • 3
  • 16
  • 1
    The problem is caused by the fact that the rotated pixel coordinates are no longer aligned to the pixel grid. You can fix this by iterating x and y over the _destination_ coordinates instead of the _source_ coordinates. At each point, pick the source pixel closest to the transformed destination coordinate (if any exists). Obviously you'll need to scan over a wide range (multiply the height and width by √2). Alternatively, try using the 3-shear method proposed by Alan Paeth, which should work much faster anyway. – r3mainer Feb 20 '21 at 15:16
  • is there clear instructions/equations for this? – alsaleem Feb 20 '21 at 15:56
  • 1
    Try searching for `Paeth rotation c source`, or [read Paeth's paper on the subject](https://graphicsinterface.org/wp-content/uploads/gi1986-15.pdf). – r3mainer Feb 20 '21 at 19:41
  • Thanks @Spektre. This is an easier answer as my geometry is simple image. but the resulting image will be different dimensions and the linked answer assumes that result image is same as input. Should I calculate the result image and loop through it? – alsaleem Feb 21 '21 at 19:26
  • Thanks @r3mainer. I found FreeImage library that has the 3-shear method, already started customizing it for 'C' until (Spektre) posted his. – alsaleem Feb 21 '21 at 19:28
  • @Spektre my image is basically a filled rectangle of 9x50 pixels. but i am displaying on LED P2.5 that is making it very clear to eye when there is something wrong. No, I am using your suggested principle for drawing. it is going to take time to test. Could you phrase your suggestion in answer to accept it. – alsaleem Feb 22 '21 at 17:09

1 Answers1

1

To avoid holes in image after rotation you have to loop through destination pixels (instead of source pixels). This (using nearest neighbor) works well for images that have:

source resolution <= destination resolution

In case of shrinking:

source resolution > destination resolution

Aliasing may occur (which will be emphasized by rotation if animated). There are ways how to deal with them:

Using Bilinear filtering is ok up to 1/2 zoom

Using Bicubic filtering is ok up to 1/4 zoom

For higher shrinking the common way is to use Mip-maps (shrink the image by factor 2 using average of each 4 pixels, until resolution is near the destination one).

All 3 methods will provide antialiasing (blending the edges that do not fit pixels exactly) so If you are viewing on big LEDs and are capable of modulating their intensity (not just BW but grayscale or color) then they will provide better image quality (better perceived by humans)

Related QAs:

Spektre
  • 49,595
  • 11
  • 110
  • 380