How to rotate the contents of a 16x16 bitmap array using only math (no scaling, just unscrew the corners)

another question from me about bitmaps! Quick introduction to this: I am working on a university project where I have no external libraries, only basic windows / C ++, this bitmap rotation has to be done entirely by changing the pixels in the array.

I have a 16x16 bitmap (it's just a COLORREF array, 16x16 elements long) and I want to rotate it about a center point (or whatever point really is).

I have a code that almost works, it rotates it in the top left corner, so I know I'm close, I just don't know what to edit to compensate for this by 8px, as is all I can think of for the results when overflow from the 16x16 area.

Here's the code I have (which I grabbed from DrDobbs and tweaked it a bit had a scaling option (part (1.0)) that I didn't need)

void Sprite::DrawAt(Render* render, int x, int y, double angle)
{
    COLORREF* tmp = new COLORREF[width * height];
    int u, v;

    for (int i = 0; i<height; i++)
    {
        for (int j = 0; j<width; j++)
        {
            u = cos(-angle) * j * (1.0) + sin(-angle) * i * (1.0);
            v = -sin(-angle) * j * (1.0) + cos(-angle) * i * (1.0);
            tmp[(i * width) + j] = bitmap[(v * width) + u];
        }
    }

    // x-(width/2) renders it at the centre point instead of the top-left
    render->BlockShiftBitmap(tmp, x - (width/2), y - (height/2), width, height, -1);

    delete[] tmp;
}

      

(Sorry for some of the wrong coding habits here, I'm only interested in the topic, everything else will be cleaned up some other time).

This code results in the following:

http://puu.sh/hp4nB/8279cd83dd.gif http://puu.sh/hp4nB/8279cd83dd.gif

It rotates around the top left corner and it also grabs memory. I could do with a solution that rotates around the center (or any point, which will be useful later for things like doors!), And also shoots corners and doesn't guarantee that there won't be any random bits of memory in the resulting bitmap.

The result should hopefully look something like this, with the black pixels turned white:

http://puu.sh/hp4uc/594dca91da.gif http://puu.sh/hp4uc/594dca91da.gif

(don't ask what the hell this creature is! he's some kind of reddish debug lizard)

Thank you, you great people helped me with this little project!

+3


source to share


2 answers


To rotate around the origin ( ox

, oy

), first align these coordinates, then rotate, and then add them again.

// Choose the center as the origin
ox = width / 2;
oy = height / 2;

// Rotate around the origin by angle
u =  cos(-angle) * (j-ox) + sin(-angle) * (i-oy) + ox;
v = -sin(-angle) * (j-ox) + cos(-angle) * (i-oy) + oy;

      



Then add a bounds check before referring to your image and use a replacement color for the "background" if the coordinates are not within:

 if (u >= 0 && u < width && v >= 0 && v < height)
     tmp[(i * width) + j] = bitmap[(v * width) + u];
 else
     tmp[(i * width) + j] = 0;   // However you represent white...

      

+1


source


You could try subtracting 8 from i and j's



u = cos(-angle) * (j-8) * (1.0) + sin(-angle) * (i-8) * (1.0);
v = -sin(-angle) * (j-8) * (1.0) + cos(-angle) * (i-8) * (1.0);

      

+2


source







All Articles