el código es el sig:
- Código: Seleccionar todo
- /*
 * Archivo: rotacion_x_ref.cpp
 * Carlos Villanueva
 */
 #include<SDL>
 #include<math>
 #include<SDL>
 #include<iostream>
 #define PI 3.14159265
 using namespace std;
 float angulo (int x1, int y1, int x2, int y2)
 {
 float ppunto, longv1, longv2;
 ppunto = x1 * x2 + y1 * y2;
 longv1 = sqrt ((x1 * x1) + (y1 * y1));
 longv2 = sqrt ((x2 * x2) + (y2 * y2));
 if (x1 == 0 && y1 == 0)
 return 0;
 else
 return acos (ppunto / (longv1 * longv2));
 }
 float to_rad(int ang)
 {
 return ang*PI/180;
 }
 float to_ang(float rad)
 {
 return rad*180/PI;
 }
 int mod2 (int x, int y)
 {
 return sqrt (x * x + y * y);
 }
 int dist(int x1, int y1, int x2, int y2)
 {
 return mod2(x2-x1,y2-y1);
 
 }
 Uint32 time_inicio, time_actual;
 void reset_time ()
 {
 time_inicio = SDL_GetTicks ();
 }
 Uint32 current_time ()
 {
 time_actual = SDL_GetTicks ();
 return time_actual - time_inicio;
 }
 void rotar_ref(SDL_Surface *src, SDL_Surface *dest, float ang, int pos_x, int pos_y, int x_ref, int y_ref)
 {
 
 SDL_Rect punto, dest1, ref;
 SDL_Surface *src_rot;
 src_rot=rotozoomSurface (src, ang, 1, 1);
 float ancho=src->w;
 float alto=src->h;
 
 dest1.y=dest1.x=0;
 punto.x=pos_x;//coordenada donde se sitia el grafico a girar
 punto.y=pos_y;
 
 ref.x=x_ref;//coordenada del punto de referencia con respecto a la imagen
 ref.y=y_ref;
 float largo=mod2(ref.x, ref.y);
 int cuadrante=ang/90;
 
 float phi1, phi2, phi3, rho;
 
 switch(cuadrante)
 {
 case 0:
 //Giro para angulos de 0 a 89
 phi1=to_ang(acos(ref.y/largo))+ang;
 
 punto.y-=ancho*sin(to_rad(ang))-ref.y+largo*cos(to_rad(phi1));
 punto.x-=largo*sin(to_rad(phi1))-ref.x;
 break;
 case 1:
 //giro para angulos de 90 a 180
 phi3=to_ang(acos(ref.x/largo))+180.0-ang;
 rho=to_ang(acos(ref.x/largo));
 punto.x-=ancho*cos(to_rad(180.0-ang))-ref.x-largo*cos(to_rad(phi3));
 punto.y-=ancho*sin(to_rad(180.0-ang))+largo*sin(to_rad(ang-90))-ref.y;
 //punto.y-=(ancho*sin(to_rad(180-ang))-largo*cos(to_rad(rho))-largo*sin(to_rad(180-ang)))*sin(to_rad(180-ang))-ref.y;
 ;
 break;
 
 case 2:
 
 //giro para angulos de 181 a 270
 phi2=to_ang(acos(ref.x/largo))-180.0+ang;
 
 punto.x-=ancho*cos(to_rad(180.0+ang))-ref.x-largo*cos(to_rad(phi2));
 punto.y+=ref.y-largo*sin(to_rad(phi2));
 break;
 case 3:
 //giro para angulos de 271 a 359
 
 phi1=to_ang(atan(ref.x/ref.y))+ang-270.0;
 
 punto.x-=alto*cos(to_rad(ang-270.0))-largo*cos(to_rad(phi1))-ref.x;
 punto.y+=ref.y-largo*sin(to_rad(phi1));
 
 }
 SDL_BlitSurface(src_rot, NULL, dest, &punto);
 
 }
 int main ()
 {
 SDL_Surface *image, *screen;
 
 SDL_Event event;
 int done = 0;
 SDL_Rect pos, dest;
 dest.y=dest.x=0;
 dest.w = 640;
 dest.h = 480;
 atexit (SDL_Quit);
 // Iniciar SDL
 if (SDL_Init (SDL_INIT_VIDEO) < 0)
 {
 printf ("No se pudo iniciar SDL: %s\n", SDL_GetError ());
 exit (1);
 }
 // Activamos modo de video
 screen = SDL_SetVideoMode (640, 480, 32, SDL_HWSURFACE);
 if (screen == NULL)
 {
 printf ("No se puede inicializar el modo gráfico: %s\n",
 SDL_GetError ());
 exit (1);
 }
 // Cargamos gráfico
 image = SDL_LoadBMP ("rect.bmp");//Nombre del archivo de la imagen BMP
 if (image == NULL)
 {
 printf ("No pude cargar gráfico: %s\n", SDL_GetError ());
 exit (1);
 }
 
 //pos.x=pos.y=50;
 for(float i=0;i<360>format, 0, 0, 0));
 //SDL_BlitSurface(image, NULL, screen, &pos);
 rotar_ref(image, screen,i,50,50,0,image->h/2);//imagen a rotar, destino, angulo,posicion en x donde se pondrá, posición en y donde se pondra, coordenadas de referencia a rotar
 
 SDL_Flip(screen);
 while(current_time()<10);
 }
 while (done == 0)
 {
 
 
 while (SDL_PollEvent (&event))
 {
 if (event.type == SDL_KEYDOWN)
 done = 1;
 }
 
 
 }
 }
rotozoom lo que hace es girar la imagen pero la citua de diferentes formas segun el angulo, siempre la pega a la esquina superior izquierda.
Pero creo que tiene algun error las operaciones matematicas, todo va bien, si el punto 'y' de referencia esta a la mitad del alto de la imagen, y 'x' es cero, si lo cambio empieza a haber un cierto movimiento aveces es brusco.
pero solo sucede para angulos de 90 a 179 y de 270 a 360
Espero que me puedan ayudar a corregir el problema o tambien otra solucion que conozcan.
Usé una imagen de un rectangulo para probar, se aprecia mejor
agregar -lSDL -lSDL_gfx en las opciones del compilador



