我的仿射变换发生了一些奇怪的事情
Some odd things going on with my affine transforms
现在,我不是在问 如何 旋转我的对象,我想问的是到底为什么我的对象(SDL_Surface)在旋转时会拉伸公式:
x' = cos(角度) * x - sin(角度) * y;
y' = sin(角度) * x + cos(角度) * y;
理论上(我认为)这是正确的。但是,当我使用下面的代码(其中使用了这个公式)时,在角度超过 15 度后我得到了奇怪的拉伸和翻转!知道是什么原因造成的吗?
for (int y = -GAME_HEIGHT/2; y < GAME_HEIGHT/2; ++y) {
for (int x = -GAME_WIDTH/2; x < GAME_WIDTH/2; ++x) {
/*----------------Begin Mode7 FX-----------------*/
float px, py, pz;
px = x;
py = FOV;
pz = y - Xrot;
float sx, sy;
sx = x;
sy = y;
//sx = px != 0 && pz != 0 ? px / pz : 0;
//sy = py != 0 && pz != 0 ? py / pz : 0;
sx = cos(Yrot*PI/180) * sx - sin(Yrot*PI/180) * sy;
sy = sin(Yrot*PI/180) * sx + cos(Yrot*PI/180) * sy;
sx *= scaling;
sy *= scaling;
sx = (sx / GAME_WIDTH * 0.5f + 0.5f) * BG0.image->w;
sy = (sy / GAME_HEIGHT * 0.5f + 0.5f) * BG0.image->h;
sx = (float)wrap((int)sx, 0, BG0.image->w);
sy = (float)wrap((int)sy, 0, BG0.image->h);
/*------------------End Mode7 FX-----------------*/
Uint32 grabPixel = getpixel(BG0.image, sx, sy);
SDL_PixelFormat* myPixelFormat=backBuffer->format;
putpixel(backBuffer, x+GAME_WIDTH/2, y+GAME_HEIGHT/2, grabPixel);
}
}
请帮忙,因为我一直在用这个把头撞到桌子上。这是获得我正在做的完美软件渲染模式 7 效果的唯一障碍(这就是注释掉透视变换的原因)
编辑:解决了这个问题,下面的回答解释了我是如何搞砸的。 (基本上,我不小心给Y坐标生成错误的值,它使用的是已经转换过的X坐标)
当您执行 sx = ... 然后执行 sy = ... 时,sy 方程使用 sx。
我认为你应该这样做:
float ax = sx, ay = sy;
sx = cos(Yrot*PI/180) * ax - sin(Yrot*PI/180) * ay;
sy = sin(Yrot*PI/180) * ax + cos(Yrot*PI/180) * ay;
现在,我不是在问 如何 旋转我的对象,我想问的是到底为什么我的对象(SDL_Surface)在旋转时会拉伸公式:
x' = cos(角度) * x - sin(角度) * y; y' = sin(角度) * x + cos(角度) * y;
理论上(我认为)这是正确的。但是,当我使用下面的代码(其中使用了这个公式)时,在角度超过 15 度后我得到了奇怪的拉伸和翻转!知道是什么原因造成的吗?
for (int y = -GAME_HEIGHT/2; y < GAME_HEIGHT/2; ++y) {
for (int x = -GAME_WIDTH/2; x < GAME_WIDTH/2; ++x) {
/*----------------Begin Mode7 FX-----------------*/
float px, py, pz;
px = x;
py = FOV;
pz = y - Xrot;
float sx, sy;
sx = x;
sy = y;
//sx = px != 0 && pz != 0 ? px / pz : 0;
//sy = py != 0 && pz != 0 ? py / pz : 0;
sx = cos(Yrot*PI/180) * sx - sin(Yrot*PI/180) * sy;
sy = sin(Yrot*PI/180) * sx + cos(Yrot*PI/180) * sy;
sx *= scaling;
sy *= scaling;
sx = (sx / GAME_WIDTH * 0.5f + 0.5f) * BG0.image->w;
sy = (sy / GAME_HEIGHT * 0.5f + 0.5f) * BG0.image->h;
sx = (float)wrap((int)sx, 0, BG0.image->w);
sy = (float)wrap((int)sy, 0, BG0.image->h);
/*------------------End Mode7 FX-----------------*/
Uint32 grabPixel = getpixel(BG0.image, sx, sy);
SDL_PixelFormat* myPixelFormat=backBuffer->format;
putpixel(backBuffer, x+GAME_WIDTH/2, y+GAME_HEIGHT/2, grabPixel);
}
}
请帮忙,因为我一直在用这个把头撞到桌子上。这是获得我正在做的完美软件渲染模式 7 效果的唯一障碍(这就是注释掉透视变换的原因)
编辑:解决了这个问题,下面的回答解释了我是如何搞砸的。 (基本上,我不小心给Y坐标生成错误的值,它使用的是已经转换过的X坐标)
当您执行 sx = ... 然后执行 sy = ... 时,sy 方程使用 sx。
我认为你应该这样做:
float ax = sx, ay = sy;
sx = cos(Yrot*PI/180) * ax - sin(Yrot*PI/180) * ay;
sy = sin(Yrot*PI/180) * ax + cos(Yrot*PI/180) * ay;