如何仅使用数学来旋转 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);
要绕原点旋转(ox
,oy
),先减去这些坐标,然后旋转,然后再添加。
// 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...
我又问了一个关于位图的问题!快速介绍一下:我正在做一个大学项目,我没有外部库,只有基本的 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);
要绕原点旋转(ox
,oy
),先减去这些坐标,然后旋转,然后再添加。
// 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...