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