SDL_Surfaceを任意の座標を中心に回転する関数を書いたのでメモ。
ただし毎回rotozoomで回転させるようなことは計算量の関係で避けた方がいい。座標の計算を参考にする程度で。
#include <SDL.h> #include <SDL_rotozoom.h> #include <SDL_gfxPrimitives.h> void draw(SDL_Surface *src, int cx, int cy, int x, int y, SDL_Surface *dst, double angle, double zoom_x, double zoom_y) { double th, s_th, c_th; SDL_Surface *s1; SDL_Rect drect; Sint16 w, h; if ( angle == 0 && zoom_x == 1 && zoom_y == 1) { s1 = src; drect.x = x - cx; drect.y = y - cy; } else if ( angle == 0 ) { s1 = zoomSurface (src, zoom_x, zoom_y, 0); drect.x = x - zoom_x * cx; drect.y = y - zoom_y * cy; } else { w = src->w * zoom_x; h = src->h * zoom_y; if (angle>0) { while (angle>360.0) angle -= 360.0; } else { while (0 > angle) angle += 360.0; } th = angle * 2.0 * M_PI / 360.0; s_th = sin(th); c_th = cos(th); // [MEMO] ほんとはx,y方向の倍率を引数で指定したいんだけど // rotozoomSurfaceXYがちゃんと動かない //s1 = rotozoomSurfaceXY (src, angle, zoom_x, zoom_y, 0); s1 = rotozoomSurfaceXY (src, angle, zoom_x, zoom_x, 0); drect.x = x - ( c_th * zoom_x * cx + s_th * zoom_y *cy); drect.y = y - (-s_th * zoom_x * cx + c_th * zoom_y *cy); if (th < M_PI/2.0) { //drect.x -= 0; drect.y -= w * s_th; } else if (th < M_PI) { drect.x -= -w * c_th; drect.y -= s1->h; //drect.y -= w * s_th - h * c_th; } else if (th < 3 * M_PI / 2) { //drect.x -= s1->w ; drect.x -= -w * c_th - h * s_th; drect.y -= - h * c_th; } else { drect.x -= -h * s_th; //drect.y -= 0; } } SDL_BlitSurface(s1, NULL, dst, &drect); if (s1 != src) SDL_FreeSurface(s1); } int main(int argc, char* argv[]) { int x, y; int cx, cy; int frame; SDL_Surface *scr; SDL_Surface *s; double angle, zoom; SDL_Init(SDL_INIT_EVERYTHING); scr = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE|SDL_DOUBLEBUF); s = SDL_LoadBMP("icon.bmp"); x = 320; y = 240; cx = s->w / 2; cy = s->h / 2; angle = -180; zoom = 1.5; frame = 0; while(frame++ < 360) { angle += 5; SDL_FillRect(scr, NULL, SDL_MapRGB(scr->format,0,0,0) ); draw(s, cx, cy, x, y, scr, angle, zoom, zoom); lineRGBA(scr, 320-2, 240, 320+2, 240, 0x00, 0xff, 0x00, 0xff); lineRGBA(scr, 320, 240-2, 320, 240+2, 0x00, 0xff, 0x00, 0xff); SDL_UpdateRect(scr, 0, 0, scr->w, scr->h); } SDL_Quit(); return 0; }