要反向旋转,请将ang更改为-ang。我怀疑你在旋转矩阵中弄错了符号,但我记不得了。(编辑:这相当于更改sin项的符号,因为sin(-x)==-sin(x)和{}。)
你无法避免翻译到中心。原因是您的转换修复了原点(0,0)(因为0*cos(...)==0),所以您总是围绕原点旋转。因此,要在其他任何地方旋转,必须首先将该点平移到原点。在
这是rotate的源代码,来自pygame源代码中的transform.c。它是用C写的static void
rotate (SDL_Surface *src, SDL_Surface *dst, Uint32 bgcolor, double sangle,
double cangle)
{
int x, y, dx, dy;
Uint8 *srcpix = (Uint8*) src->pixels;
Uint8 *dstrow = (Uint8*) dst->pixels;
int srcpitch = src->pitch;
int dstpitch = dst->pitch;
int cy = dst->h / 2;
int xd = ((src->w - dst->w) << 15);
int yd = ((src->h - dst->h) << 15);
int isin = (int)(sangle * 65536);
int icos = (int)(cangle * 65536);
int ax = ((dst->w) << 15) - (int)(cangle * ((dst->w - 1) << 15));
int ay = ((dst->h) << 15) - (int)(sangle * ((dst->w - 1) << 15));
int xmaxval = ((src->w) << 16) - 1;
int ymaxval = ((src->h) << 16) - 1;
switch (src->format->BytesPerPixel)
{
case 1:
for (y = 0; y < dst->h; y++)
{
Uint8 *dstpos = (Uint8*)dstrow;
dx = (ax + (isin * (cy - y))) + xd;
dy = (ay - (icos * (cy - y))) + yd;
for (x = 0; x < dst->w; x++)
{
if(dx < 0 || dy < 0 || dx > xmaxval || dy > ymaxval)
*dstpos++ = bgcolor;
else
*dstpos++ = *(Uint8*)
(srcpix + ((dy >> 16) * srcpitch) + (dx >> 16));
dx += icos;
dy += isin;
}
dstrow += dstpitch;
}
break;
case 2:
for (y = 0; y < dst->h; y++)
{
Uint16 *dstpos = (Uint16*)dstrow;
dx = (ax + (isin * (cy - y))) + xd;
dy = (ay - (icos * (cy - y))) + yd;
for (x = 0; x < dst->w; x++)
{
if (dx < 0 || dy < 0 || dx > xmaxval || dy > ymaxval)
*dstpos++ = bgcolor;
else
*dstpos++ = *(Uint16*)
(srcpix + ((dy >> 16) * srcpitch) + (dx >> 16 << 1));
dx += icos;
dy += isin;
}
dstrow += dstpitch;
}
break;
case 4:
for (y = 0; y < dst->h; y++)
{
Uint32 *dstpos = (Uint32*)dstrow;
dx = (ax + (isin * (cy - y))) + xd;
dy = (ay - (icos * (cy - y))) + yd;
for (x = 0; x < dst->w; x++)
{
if (dx < 0 || dy < 0 || dx > xmaxval || dy > ymaxval)
*dstpos++ = bgcolor;
else
*dstpos++ = *(Uint32*)
(srcpix + ((dy >> 16) * srcpitch) + (dx >> 16 << 2));
dx += icos;
dy += isin;
}
dstrow += dstpitch;
}
break;
default: /*case 3:*/
for (y = 0; y < dst->h; y++)
{
Uint8 *dstpos = (Uint8*)dstrow;
dx = (ax + (isin * (cy - y))) + xd;
dy = (ay - (icos * (cy - y))) + yd;
for (x = 0; x < dst->w; x++)
{
if (dx < 0 || dy < 0 || dx > xmaxval || dy > ymaxval)
{
dstpos[0] = ((Uint8*) &bgcolor)[0];
dstpos[1] = ((Uint8*) &bgcolor)[1];
dstpos[2] = ((Uint8*) &bgcolor)[2];
dstpos += 3;
}
else
{
Uint8* srcpos = (Uint8*)
(srcpix + ((dy >> 16) * srcpitch) + ((dx >> 16) * 3));
dstpos[0] = srcpos[0];
dstpos[1] = srcpos[1];
dstpos[2] = srcpos[2];
dstpos += 3;
}
dx += icos; dy += isin;
}
dstrow += dstpitch;
}
break;
}
}