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

时间:2015-04-24 11:43:52

标签: c++ bitmap rotation

我的另一个关于位图的问题!快速介绍一下:我正在开展一个大学项目,我没有外部库,只有基本的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

(不要问这个生物到底是什么!他是某种红耳调试蜥蜴)

谢谢,你们这里很棒的人对我的这个小项目有很多帮助!

2 个答案:

答案 0 :(得分:2)

你能尝试从我和j&#39>中减去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);

答案 1 :(得分:1)

要围绕原点(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;

然后,在访问图像之前添加边界检查,并在&#34;背景&#34;中使用替换颜色,以防坐标不在边界内:

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