Tuesday, March 06, 2007

Transformaciones Geometricas.

Una transformaciòn geomètrica permite eliminar la distorciòn geomètrica que pudiese existir cuando una imagen es capturada.

Una transformaciòn geòmetrica es una funciòn de vectores que mapea el pixel (x,y) a una nueva posición (x',y'),Las transformaciones más usuales son las traslaciones, rotaciones y escalado.

· Traslación : Una traslaciòn simplemente mueve un objeto de un lugar a otro, al poner un ligero offset en X y en Y:


El segundo tipo de transformacion que existe se llama escalamiento. El escalamiento cambia el tamaño del objeto al multiplcar las coordenadas X y Y de un objeto por una constante de escalamiento.S

scaling
Figure 5: Scaling by Sx=2 Sy=2.

El ùltimo tipo de transformaciòn que veremos es la de rotacion. Puntos son rotados con respecto al origen un cierto àngulo.

rotation around the origin
Figure 6: Rotation around the origin.

object rotation
Figure 7: Rotation of an object by 45 degrees.

Las tres transformaciones se llevan acabo al efectuar multiplicaciones entre matrices.

Las matrices con las que se multiplica a los vectores son respectivamente:


transformation matrices
Figure 8: Formulas para translacion, escalamiento y rotaciòn.



Ahora bien OpenGl, nos brinda difernetes funciones para llevar acabo estas operaciones.

o Traslación (Translation)

glTranslatef( GLfloat x, GLfloat y, GLfloat z); en donde la función toma la medida de las variables x, y ,z para mover el objeto en sus ejes correspondientes dichas unidades.

o Escala (Scaling)
glScalef(GLfloat x , GLfloat y, Glfloat z); en donde cada uno de los parámetros mostrados indica la coordenada por la cual se multiplicará el valor real del objeto para posteriormente escalarlo a la medida deseada.

o Rotación

glRotatef(GLfloat angle, GLfloat x, GLfloat y, Glfloar z); en donde el parámetro se refiere a el ángulo que se desea rotar el objeto ; así tambien los tres subsecuentes especifican la rotaciòn a través de algun eje en especifico dando lugar asì al vector.

Charlando ahora de otro tema, entremos a ver que diablos es
GL_PROJECTION: Es bàsicamnete una matriz de transformaciòn que se aplica a todos los puntos que vienen despuès de este comando. GL_MODELVIEW es una matriz de transformaciòn que se aplica a cada punto de un modelo en particular. Hay una jeraqruia entre las transformaciones , se tiene a GL_PROJECTION hasta arriba y se tienen como ramas a GL_MODEL .

Por ello, antes de realizar una operación de transformación es necesario indicar sobre que matriz se va a realizar. Se especifica con la función glMatrixMode(Glenum mode) que tiene como argumento una de las tres constantes enumeradas. Se comporta como un estado, por tanto, hasta que se especifique un nuevo estado todas las transformaciones se realizan sobre la última matriz especificada.Para poder intercambiar entre una y otra matriz se emplea el comando glMatrixMode(Glenum mode) y posteriormente se inicia la matriz con glLoadIdentity()

A continuaciòn mostrarè un còdigo para ejemplificar màs esto:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, -1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, -1.0, 1.0);
glTranslate( 100, 100, 100 );
glRotateF( 45, 1, 0, 0 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslate( modelx, modely, modelz );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, -1.0, 1.0);
glTranslate( camerax, cameray, cameraz );

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslate( carx, cary, carz );
// draw car here, by specifying various gl vertices

glLoadIdentity();
glTranslate( battleshipx, battleshipy, battleshipz );
// draw battleship here, by specifying various gl vertices
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, -1.0, 1.0);
glTranslate( camerax, cameray, cameraz );
glRotateF( cameraanglex, 1, 0, 0 );


¿ Què podemos concluir del còdigo anterior?
Es una MENTIRA QUE SE USA LA CAMARA, It is, because its pretty
obvious that we're really moving the entire world to get our picture,
and not some "camera"!!!

Ahora bien...ya que estamos chlando tan agusto, toquemos otro tema interesantòn:


En la función display() se encuentran las llamadas a dos funciones de matrices que todavía no han sido comentadas. Se trata de glPushMatrix() y glPopMatrix(). Para comprender su funcionamiento, primero se va a experimentar que es lo que ocurre cuando no están dichas llamadas. Para ello se comentan en la función display() ambas llamadas:

void display(void) {

...

// glPushMatrix();

...

glTranslatef(0.0, 0.0, .5);

...

// glPopMatrix();

glutSwapBuffers();

}

Al ejecutar de nuevo la aplicación, primeramente tiene el mismo aspecto que sin comentar las llamadas, pero si obligamos a que se llame varias veces a la función display(), por ejemplo pulsando la tecla “c” (que activa y desactiva los polígonos posteriores del objeto), vemos que además de producirse el efecto de cambiar el modo GL_CULL_FACE, el objeto se va moviendo progresivamente a lo largo de eje “Z”.

La razón de este movimiento es que en la función display está incluida una llamada a glTranslatef() que se utiliza para posicionar uno de los objetos. Como se ha explicado anteriormente, las funciones de traslación multiplican la matriz actual por una matriz de traslación creada con los argumentos que se le pasan, por tanto, sucesivas llamadas a la función display() provocan sucesivas multiplicaciones de la matriz actual con el efecto que se observa de incrementar la traslación.

Para solucionar este problema OpenGL dispone de unos stacks o pilas de matrices, que ermiten almacenar y recuperar una matriz anterior. Aunque OpenGL dispone de pilas para las matrices GL_MODELVIEW y GL_PROJECTION, sólo se suele utilizar la pila de GL_MODELVIEW. Una pila es un almacén con funcionamiento LIFO, el último en entrar es el primero en salir, por lo que suele comparar a una pila de platos en la que sólo se puede dejar uno encima de la pila o coger el superior que es el último depositado. La pila de matrices tiene el mismo funcionamiento sustituyendo los platos por matrices. La matriz superior de la pila es sobre la que se aplican las distintas transformaciones, multiplicándola por la matriz que generan las distintas funciones.

Para poder guardar una determinada matriz y posteriormente recuperarla OpenGLdispone de las dos funciones comentadas: glPushMatrix() y glPopMatrix().

La función glPushMatrix() realiza una copia de la matriz superior y la pone encima de la pila, de tal forma que las dos matrices superiores son iguales. En la figura 1 se observa la pila en la situación inicial con una sola matriz, al llamar a la función glPushMatrix() se duplica la matriz superior. Las siguientes transformaciones que se realizan se aplican sólo a la matriz superior de la pila, quedando la anterior con los valores que tenía en el momento de llamar a la función glPushMatrix().

La función glPopMatrix() elimina la matriz superior, quedando en la parte superior de

la pila la matriz que estaba en el momento de llamar a la función glPushMatrix().


En la función display() al llamar a la función glPushMatrix() se realiza una copia de la matriz actual. La traslación en el eje Z se realiza en la matriz superior de la pila, es decir, en la copia de la matriz, de tal forma que al llamar a la función glPopMatrix(), como se muestra en la figura 1, se elimina la matriz superior, que es la que tenía el efecto de esta transformación, quedando la matriz que estaba en el momento de llamar a glPushMatrix(). Al descomentar las llamadas a las funciones glPushMatrix() y glPopMatrix() las transformaciones realizadas entre ambas no afectan al resto de la aplicación.



Pues parece ser que ya mero estamos listos para entrar a programar en Opengl...But there is still something very important about OpenGl that you should know about:

Para crear cualquier figura geométrica en OpenGL hay que definir los vértices entre un par de llamadas a las funciones glBegin() y glEnd(). A la función glBegin se le puede pasar un argumento que determina qué tipo de figura geométrica se va construir. Después se definen los vértices mediante llamadas a la función glVertex. A ontinuación vemos un ejemplo en el que se define el polígono de la figura.

glBegin (GL_POLYGON);

glVertex2f (0.0, 0.0);

glVertex2f (0.0, 3.0);

glVertex2f (3.0, 3.0);

glVertex2f (4.0, 1.5);

glVertex2f (3.0, 0.0);

glEnd ();



void glBegin (GLenum mode);

Marca el principio de una lista de vértices que describen una primitivageométrica



void glEnd (void);

Marca el final de una lista de vértices.


Another yet interesting subject is of course: MODElADO gEOMETRICO!

Un modelo geometrico describe la figura de un objeto fisico o matematico mediante conceptos geometricos. El modelado geometrico es la construcion o
uso de modelos geometricos.
Los modelos Geometricos se suelen usar en computacion grafica,diseÑo asistido por computadora, asi como en muchas otras ramas aplicadas, como es
procesamiento de imagenes medicas.
 
 
Los modelos geometricos se pueden construir para objetos de cualquier Dimension en cualquier espacio geometricos. Asi los diferentes tipos de
modelados geometricos se distinguen  justo en la dimension para la cual han sido construido. Tanto
los modelos para   dimensiones de 2D y 3D son usados mucho en computacion grafica.
 
 
Los modelos geometricos se  distinguinguen mucho  de los modelos orientados a objetos, debido a que esos modelos  definen la figura usando
implicitamente un algoritmo.  Tambien contrastan con las imàgenes digitales y los modelos
volumetricos, asi como con modelos matematicos implicitos  como es el set zero
de un polinomio arbitrario. Sin embargo, la distincion es en ocasiones un
poco confusa, por ejemplo figuras geometricas pueden ser representadas por objetos,
una imagen digital puede ser interpretada como una coleccion de cuadrados de
colores, figuaras gèometricas, como peude ser un cìrculo, està  definido por una ecuacion matematica implicita. Asimismo, el modelado de un
objeto fractal requiere de una combiancion de difernetes tipos de tecnicas.


And since we are writing on into the night, let`s touch yet another matter:


glClearColor - Especifica  valores para limpiar  el buffer de color.
Su especificacion esta dada por:
 
void glClearColor( GLclampf  red, GLclampf green, GLclampf blue,Glclampf alpha )
 
Los parámetros son:  red, green, blue, alpha
 
Especifica  los valores rojo, verde, azul y alpha que son usados cuando  el buffer de  color es reseteado.  Los valores iniciales son todos cero.
 
Descripción: GLClearColor especifica los valores red, green, blue y alpha que serán usados por glClear para limpiar los colores del buffer. Los valores especificados por glClearColor están dentro del rango de [0,1].
 
 
glClear - Limpia los buffers para poner nuevos valores.
 
C ESPECICACION:void glClear(    GLbitfield mask   )
 
PARAMETROS: mask       Es una serie de Operaciones Bitwise de las masks que indican  los buffers que deben ser vaciados.
Las 4 mascaras son GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT, GL_ACCUM_BUFFER_BIT, and
                               GL_STENCIL_BUFFER_BIT.
 
DESCRIPCION: glClear  pone en el área del bitplane los valores antes seccionados por el             glClearColor, glClearIndex, glClearDepth,glClearStencil,y glClearAccum. Múltiples bufferS de color
pueden ser limpiados simultáneamente al seleccionar mas de un buffer a la vez utilizando la herramienta de glDrawBuffer.
 
 glClear toma un solo argumento que es el resultante de la operación
bitwise OR de diversos valores, este argumento indica cual de los buffers ha de ser limpiado.
 
 
               
EJEMPLO DE CODIGO USANDO glClear y glClearColor
 
 
 
               #include 
#include 
#include 
using namespace std;
 
// function prototypes
void disp(void);
void keyb(unsigned char key, int x, int y);
 
 
// window identifier
static int win;
 
int main(int argc, char **argv){
 
  //////////
  // INIT //
  //////////
 
  // initialize glut
  glutInit(&argc, argv);
 
  // specify the display mode to be RGB and single buffering
  // we use single buffering since this will be non animated
  glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
 
  // define the size
  glutInitWindowSize(500,500);
 
  // the position where the window will appear
  glutInitWindowPosition(100,100);
 
 
  // if we would want fullscreen:
  // glutFullScreen();
 
  // create the window, set the title and keep the
  // window identifier.
  win = glutCreateWindow("Yet another teapot");
 
  //////////////
  // CALLBACK //
  //////////////
 
  glutDisplayFunc(disp);
  glutKeyboardFunc(keyb);
 
  ////////////
  // OPENGL //
  ////////////
 
  // define the color we use to clearscreen
  glClearColor(0.0,0.0,0.0,0.0);
 
 
 
  // enter the main loop
  glutMainLoop();
 
  return 0;
}
 
 
void disp(void){
 
  // do  a clearscreen
  glClear(GL_COLOR_BUFFER_BIT);
 
  // draw something
 
  glutWireTeapot(0.5);
  // glutSolidTeapot(0.5);
  // glutWireSphere(0.5,100,100);
  // glutSolidSphere(0.5,100,100);
  // glutWireTorus(0.3,0.5,100,100);
  // glutSolidTorus(0.3,0.5,100,100);
  // glutWireIcosahedron();
  // glutSolidIcosahedron();
  // glutWireDodecahedron();
  // glutSolidDodecahedron();
  // glutWireCone(0.5,0.5,100,100);
  // glutSolidCone(0.5,0.5,100,100);
  // glutWireCube(0.5);
  // glutSolidCube(0.5);
}
 
void keyb(unsigned char key, int x, int y){
  cout << "Pressed key " <<>
")";
  cout <<>
  if(key == 'q'){
    cout << "Got q,so quitting " <<>
    glutDestroyWindow(win);
    exit(0);
  }
9)
glutInit
 
glutInit es utilizada para inicializar la  librería de  GLUT.
Se usa de la siguiente forma:
void glutInit(int *argcp, char **argv);
argcp: es un apuntador a la variable argc del main.
argv: la variable argv sin modificar del main.
Descripción:glutInit inicializara la librería GLUT y negociara una sesión con la ventana
del  sistema .
 
 
glutInitDisplayMode: Asigna el modo de display inicial.
Se utiliza de la siguiente forma:
void glutInitDisplayMode(unsigned int mode);
mode: Es el modo de display. Algunos ejemplos son:
GLUT_RGBA: Mascara bit para seleccionar una ventana de modo RBGA.
GLUT_STEREO: Mascara de bit para seleccionar una ventana de tipo stereo.
 
glutInitWindowPosition pone el valor inicial de la ventana . La sintaxis para su uso es:
 
glutInitWindowPosition(x,y) x, y: localización de la ventana en pixeles.
 
 
glutInitWindowSize — Pone el tamaño de la ventana inicial.
glutInitWindowSize(width,height)
 
glutCreateWindow (): Crea una ventana de nivel superior. La sintaxis es: int glutCreateWindow(char *name)
 
glutDisplayFunc(): Fija el callback del display para la ventana en cuestion.Se utiliza de la siguiente forma:
void glutDisplayFunc(void (*func)(void));
 
func es la nueva funcion de callback.
Cuando GLUT determina que el plano normal de la ventan necesita volverse a desplejar, el display callback para la ventana es llamado.
 
glutReshapeFunc() pone el callback de  la redefinicion del tamanio para la ventana en cuestion.
 
void glutReshapeFunc(void (*func)(int width, int height));
func: es la nueva funcion  reshape callback
 
El  reshape callback es llamado cuando se cambia el tamanio de la ventana.
 
glutKeyboardFunc(): Pone el callback del teclado para la ventana actual.
void glutKeyboardFunc(void (*func)(unsigned char key,int x, int y));
func: es la nueva funcion  teclado callback
glutMainLoop() mete el  loop del  evento de procesameinto de GLUT. Una vez que es llamada esta rutina nunca retornara
 
Hemos estado usando mucho la palabra callback aquì...but what the f* es un callback?
 
Callback: Se dice que existe un callback, cuando ocurre un cierto  evento y uno programa la respuesta que dará el programa.
Uno define que función será llamada (called) cuando sucede un evento.  Ahora bien, Glut tiene una serie de callbacks bien definidas.
ejemplo:
void glutDisplayFunc(void (*func)(void));
Esto especifica la función que necesita ser llamada cuando se redibuja la ventana



No comments: