Buenas, estoy haciendo un proyecto 2d en FreeGlut con C++ y tengo un problema, cuando hago click en una zona, las coordenadas que coge no son las que debería, son de unos 10 píxeles más abajo, pero la cosa es que cuando redimensiono el área visible de la escena haciendo zoom, se descuadra la selección. Estoy calculándola mediante porcentajes, pero no doy con ello, mi código es este:
void mouse(int button, int state, int x, int y) {
if (button==GLUT_LEFT_BUTTON && state==GLUT_DOWN) {
// trasladarEscena('N',10);
//repaint();
//Si no había iniciado, se inicia
if (!started){
pintarInicial(x,y);
repaint();
// glutPostRedisplay();
} else{
square_x = xLeft + (x)*(abs(xRight)+abs(xLeft))/WIDTH;
square_y = yBot + (HEIGHT-y)* abs(yTop)+abs(yBot))/HEIGHT;
selection = Punto(square_x,square_y);
selection_enabled = true;
}
}
}
Gracias.
y no tendrás por algún casual los tipos de las variables implicadas, verdad??
square_x = xLeft + (x)*(abs(xRight)+abs(xLeft))/WIDTH;
mmmm
Hasta donde llego el ancho de la ventana debería calcularse como xRight-xLeft... ya que la suma puede darte de todo menos la anchura de la ventana.
Por tanto, square_x debería calcularse así:
square_x = xLeft + x*(abs(xRight)-abs(xLeft))/WIDTH;
Con la coordenada vertical te pasa lo mismo.
Como no aparece el algoritmo, puede que también tengas problemas al calcular xLeft y yBot.
Un saludo
No, eso no funciona. De momento selecciona bien si no se redimensiona ni mueve, pero selecciona unos píxeles por debajo de donde debería, pero si se cambia eso, ya empieza la locura.
Vale, espera... una cosa... qué pinta ahí la constante WIDTH??
square_x = xLeft + (x/WIDTH)*(xRight-xLeft);
se supone que x/WIDTH te va a dar el desplazamiento en porcentaje... eso lo multiplicas por la escala real y te debería dar las coordenadas reales, cierto??
También deberías mirar el tipo de las variables... si estás operando con int vas a tener problemas con los redondeos... sobretodo si las operaciones de división se ejecutan antes que las de producto.
También es posible que el problema esté en la redimensión del área visible de la escena. He de decir que el área visible y el puerto de vista son proporcionales.
void resize(int newWidth, int newHeight){
int oldwidth = WIDTH;
int oldheight = HEIGHT;
//Resize Viewport
WIDTH= newWidth;
HEIGHT= newHeight;
GLdouble RatioViewPort= (float)WIDTH/(float)HEIGHT;
glViewport ( 0, 0, WIDTH, HEIGHT ) ;
//Resize Scene Visible Area
//Se actualiza el área visible de la escena
//para que su ratio coincida con ratioViewPort
GLdouble SVAWidth= xRight-xLeft;
GLdouble SVAHeight= yTop-yBot;
GLdouble SVARatio= SVAWidth/SVAHeight;
if (newWidth < oldwidth || newHeight < oldheight){
if ( SVARatio >= RatioViewPort) {
// Increase SVAHeight
GLdouble newHeight= SVAWidth/RatioViewPort;
GLdouble yMiddle= ( yBot+yTop )/2.0;
yTop= yMiddle + newHeight/2.0;
yBot= yMiddle - newHeight/2.0;
}
if ( SVARatio < RatioViewPort) {
//Increase SVAWidth
GLdouble newWidth= SVAHeight*RatioViewPort;
GLdouble xMiddle= ( xLeft+xRight )/2.0;
xRight= xMiddle + newWidth/2.0;
xLeft= xMiddle - newWidth/2.0;
}
}
if (newWidth > oldwidth || newHeight > oldheight){
if ( SVARatio < RatioViewPort) {
// Increase SVAHeight
GLdouble newHeight= SVAWidth/RatioViewPort;
GLdouble yMiddle= ( yBot+yTop )/2.0;
yTop= yMiddle + newHeight/2.0;
yBot= yMiddle - newHeight/2.0;
}
if ( SVARatio >= RatioViewPort) {
//Increase SVAWidth
GLdouble newWidth= SVAHeight*RatioViewPort;
GLdouble xMiddle= ( xLeft+xRight )/2.0;
xRight= xMiddle + newWidth/2.0;
xLeft= xMiddle - newWidth/2.0;
}
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(xLeft, xRight, yBot, yTop);
}