如何仅使用数学来旋转 16x16 位图数组的内容(无缩放,只需剪掉角)

How to rotate the contents of 16x16 bitmap array using only maths (no scaling, just clip the corners off)

我又问了一个关于位图的问题!快速介绍一下:我正在做一个大学项目,我没有外部库,只有基本的 windows/c++,这个位图旋转必须完全通过简单地修改数组中的像素来完成。

我有一个 16x16 位图(它只是一个 16x16 元素长的 COLORREF 数组),我想围绕中心点(或实际上的任何点)旋转它。

我有一些代码 几乎 可以工作,它围绕左上角旋转它所以我知道我很接近,我只是不知道要编辑什么将其偏移 8 个像素,因为我能想到的所有内容都会溢出 16x16 区域。

这是我目前拥有的代码(我从 DrDobbs 抓取并稍微修改了它,它有一个我不需要的缩放参数((1.0) 部分))。

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;
}

(请原谅这里的一些不良编码习惯,我只对手头的主题感兴趣,其他一切都会在其他时间清理)。

该代码的结果是:

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

它绕着左上角旋转,它也抢越界内存。我可以使用围绕中心旋转的解决方案(或任何点,这将在以后派上用场,例如门!)并且还可以剪掉角落并确保不会在生成的位图中出现随机的内存位。

结果应该希望看起来像这样,黑色像素变成白色:

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

(别问那个生物到底是什么东西!他是某种红耳调试蜥蜴)

谢谢,你们这些很棒的人对我的这个小项目帮助很大!

你可以试着从 i 和 j 中减去 8

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);

要绕原点旋转(oxoy),先减去这些坐标,然后旋转,然后再添加。

// 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;

然后,在访问图像之前添加边界检查,并为 "background" 使用替换颜色,以防坐标不在边界内:

 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...