jueves, 22 de marzo de 2012

Rebote de Pelota

#include <gl/glut.h>
#include <Math.h>    
#define PI 3.14159265f
     
char title[] = "Rebote de Pelota"; 
int windowWidth  = 640;    
int windowHeight = 480;    
int windowPosX   = 50;     
int windowPosY   = 50;     
  
GLfloat ballRadius = 0.2f;  
GLfloat xPos = 0.0f;        
GLfloat yPos = 0.0f;
GLfloat xPosMax, xPosMin, yPosMax, yPosMin;
GLdouble xLeft, xRight, yBottom, yTop;    
GLfloat xSpeed = 0.02f;     
GLfloat ySpeed = 0.007f;
int refreshMillis = 10;     
     
void initGL() {
   glClearColor(0.0, 1.0, 0.0, 0.0);
}
 
void display() {
   glClear(GL_COLOR_BUFFER_BIT);
 
   glLoadIdentity();              
   glTranslatef(xPos, yPos, 0.0f); 

   glBegin(GL_TRIANGLE_FAN);
      glColor3f(0.0f, 0.0f, 1.0f);
      glVertex2f(0.0f, 0.0f);      
      int numSegments = 100;
      GLfloat angle;
      for (int i = 0; i <= numSegments; i++) {
         angle = i * 2.0f * PI / numSegments; 
         glVertex2f(cos(angle) * ballRadius, sin(angle) * ballRadius);
      }
   glEnd();
  
   glutSwapBuffers(); 
  
 
   xPos += xSpeed;
   yPos += ySpeed;
  
   if (xPos > xPosMax) {
      xPos = xPosMax;
      xSpeed = -xSpeed;
   } else if (xPos < xPosMin) {
      xPos = xPosMin;
      xSpeed = -xSpeed;
   }
   if (yPos > yPosMax) {
      yPos = yPosMax;
      ySpeed = -ySpeed;
   } else if (yPos < yPosMin) {
      yPos = yPosMin;
      ySpeed = -ySpeed;
   }
}
 
void reshape(GLsizei weight, GLsizei height) {
   if (height == 0) height = 1;             
   GLfloat aspect = (GLfloat)weight / height;
  
   glViewport(0, 0, weight, height);
  
  
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();           
   if (weight <= height) {
      xLeft   = -1.0;
      xRight  = 1.0;
      yBottom = -1.0 / aspect;
      yTop    = 1.0 / aspect;
   } else {
      xLeft   = -1.0 * aspect;
      xRight  = 1.0 * aspect;
      yBottom = -1.0;
      yTop    = 1.0;
   }
   gluOrtho2D(xLeft, xRight, yBottom, yTop);
 
  
   yPosMin = yBottom + ballRadius;
   yPosMax = yTop - ballRadius;
  
  
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();          
}
 
void Timer(int value) {
 glutPostRedisplay();  
 glutTimerFunc(refreshMillis, Timer, 0);
}
  
int main(int argc, char** argv) {
   glutInit(&argc, argv);           
   glutInitDisplayMode(GLUT_DOUBLE);
   glutInitWindowSize(windowWidth, windowHeight); 
   glutInitWindowPosition(windowPosX, windowPosY);
   glutCreateWindow(title);     
   glutDisplayFunc(display);  
   glutReshapeFunc(reshape);  
   glutTimerFunc(0, Timer, 0);  
   initGL();                    
   glutMainLoop();             
   return 0;
}












miércoles, 14 de marzo de 2012


Proyección Ortogonal.



El tipo de proyección que hemos utilizado hasta ahora es una proyección ortogonal. Una proyección ortogonal define un volumen de la vista de tipo paralelepipédico tal y como se muestra en la siguiente figura. La principal característica de esta proyección es que el tamaño de los objetos es independiente de la distancia a la que estén del observador, por ejemplo, dos cilindros del mismo tamaño, uno a cinco unidades y el otro a diez unidades de distancia del observador se proyectarán con el mismo tamaño.







Para definir una proyección ortogonal en OpenGL hay que dar los siguientes pasos:



glMatrix(GL_PROJECTION); /* Voy a manejar la matriz de proyección */
glLoadIdentity(); /* Cargo inicialmente la identidad */
/* Y ahora defino la proyección ortogonal */
void glOrtho(izquierda, derecha, abajo, arriba, cerca, lejos);


Si lo que deseamos es trabajar con una proyección ortogonal 2D:

void gluOrtho2D(izquierda, derecha, abajo, arriba);

que no es más que una proyección ortogonal donde el plan delantero está en -1 y el trasero en 1.


Proyección Perspectiva.
La proyección ortogonal no da sensación de profundidad porque el tamaño de los objetos no depende de su distancia al observador. Para conseguir este efecto necesitamos definir una proyección perspectiva. Esta proyección define un volumen de la vista que es un prisma truncado de base rectangular, como el de la siguiente figura:







la función OpenGL que establece este tipo de perspectiva es:
void glFrustum(izquierda, derecha, abajo, arriba, cerca, lejos);

Este modo de definir la proyección perspectiva no es demasiado intuitivo, es más sencillo establecerla con un esquema como el que se muestra en la siguiente figura:






y la función OpenGL que la establece es:
void gluPerspective(fovy, aspecto, cerca, lejos);
donde fovy es el ángulo de apertura del objetivo de la cámara, en grados, y aspecto es la relación ancho/alto de la base de la pirámide.



Aplicandole Transformaciones
En el ejemplo vamos a aplicar transformaciones de rotacion y traslación. La de escalado no la vamos a utilizar principalmente para evitar "malos hábitos" debido a que este comando es MUY lento y el uso continuo del mismo hace descender nuestro queridos FPS.

    Para las transformaciones geométricas, OpenGL utiliza, al igual que D3D, matrices de 4x4. Aunque al contrario que D3D, OGL no se apoya directamente en la notación matemática y en su lugar, utiliza la traspuesta de la  matemática.

    Los comandos de traslación, rotación y escalado vienen explicados en Apendice 1: Visualización así que aquí me limitaré a nombrarlos.

   Traslación

void glTranslate{fd}(TYPE x, TYPE y, TYPE z);

Multiplica la matriz actual por una matriz de traslación que mueve el objeto.s


   Rotación

void glRotate{fd}(TYPE angle,TYPE x, TYPE y, TYPE z);

Multiplica la matriz actual por una matriz de rotación que rota el objeto en la dirección de las agujas del reloj sobre el radio de origen en el punto x,y,z.


   Escalado

void glScale{fd}(TYPE x, TYPE y, TYPE z);

            Multiplica la matriz actual por una matriz que cambia el tamaño del objeto a lo largo de los ejes. Las coordenadas

            x, y, z de cada objeto es multiplicada por los parámetros x, y, z.

C    Como dijimos anteriormente en nuestro ejemplo solamente aplicaremos las transformaciones de rotación y traslación. Para poder mover y rotar el cuadrado, vamos a declarar unas variables globales:

float fRotx,fRoty;

float fDesz=-3.0f;

Las dos primeras son los ángulos que vamos a rotar con respecto al eje x e y respectivamente. La tercera variable corresponde con el desplazamiento a travez del eje z (perpendicular a la pantalla). Gráficamente sería:
    

Pila de Matrices

En la función display() se encuentran las llamadas a dos funciones de matrices

 glPushMatrix() y glPopMatrix().

glTranslatef() que se utiliza para posicionar uno de los objetos.

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.

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().

glGetDoublev() Con esta función se obtiene la matriz actual de una de las pilas, a la que se indica que matriz se quiere obtener.

Viewport

Es poco probable que necesites usar el control Viewport (Vista) directamente. Es mucho más probable que uses el control ScrolledWindow, el cual usa un Viewport.

Un control de vista permite colocar un control más grande dentro de él de tal forma que se pueda ver una parte de él de una vez. Usa Adjustments para definir el área que se ve.

Un Viewport se crea con la función:

  viewport = gtk.Viewport(hadjustment=None, vadjustment=None)

Como se puede ver se pueden especificar los Adjustments horizontal y vertical que el control usa cuando se crea. Creará sus propios ajustes si se le pasa None como valor de los argumentos o simplemente no se le pasan argumentos.

Se pueden consultar y fijar los ajustes después de que el control se haya creado usando los siguientes cuatro métodos:

  viewport.get_hadjustment()

  viewport.get_vadjustment()

  viewport.set_hadjustment(adjustment)

  viewport.set_vadjustment(adjustment)

El otro método que se usa para modificar la apariencia es:

  viewport.set_shadow_type(type)

Los valores posibles para el parámetro type son:

  SHADOW_NONE         # sin sombra
  SHADOW_IN           # sombra hacia adentro
  SHADOW_OUT          # sombra hacia afuera
  SHADOW_ETCHED_IN    # sombra marcada hacia adentro
  SHADOW_ETCHED_OUT   # sombra marcada hacia fuera

Investigaciones


Proyección Ortogonal.



El tipo de proyección que hemos utilizado hasta ahora es una proyección ortogonal. Una proyección ortogonal define un volumen de la vista de tipo paralelepipédico tal y como se muestra en la siguiente figura. La principal característica de esta proyección es que el tamaño de los objetos es independiente de la distancia a la que estén del observador, por ejemplo, dos cilindros del mismo tamaño, uno a cinco unidades y el otro a diez unidades de distancia del observador se proyectarán con el mismo tamaño.







Para definir una proyección ortogonal en OpenGL hay que dar los siguientes pasos:



glMatrix(GL_PROJECTION); /* Voy a manejar la matriz de proyección */

glLoadIdentity(); /* Cargo inicialmente la identidad */

/* Y ahora defino la proyección ortogonal */

void glOrtho(izquierda, derecha, abajo, arriba, cerca, lejos);



Si lo que deseamos es trabajar con una proyección ortogonal 2D:



void gluOrtho2D(izquierda, derecha, abajo, arriba);



que no es más que una proyección ortogonal donde el plan delantero está en -1 y el trasero en 1.









Proyección Perspectiva.



La proyección ortogonal no da sensación de profundidad porque el tamaño de los objetos no depende de su distancia al observador. Para conseguir este efecto necesitamos definir una proyección perspectiva. Esta proyección define un volumen de la vista que es un prisma truncado de base rectangular, como el de la siguiente figura:







la función OpenGL que establece este tipo de perspectiva es:



void glFrustum(izquierda, derecha, abajo, arriba, cerca, lejos);



Este modo de definir la proyección perspectiva no es demasiado intuitivo, es más sencillo establecerla con un esquema como el que se muestra en la siguiente figura:







y la función OpenGL que la establece es:



void gluPerspective(fovy, aspecto, cerca, lejos);



donde fovy es el ángulo de apertura del objetivo de la cámara, en grados, y aspecto es la relación ancho/alto de la base de la pirámide.











Aplicandole Transformaciones



    En el ejemplo vamos a aplicar transformaciones de rotacion y traslación. La de escalado no la vamos a utilizar principalmente para evitar "malos hábitos" debido a que este comando es MUY lento y el uso continuo del mismo hace descender nuestro queridos FPS.

    Para las transformaciones geométricas, OpenGL utiliza, al igual que D3D, matrices de 4x4. Aunque al contrario que D3D, OGL no se apoya directamente en la notación matemática y en su lugar, utiliza la traspuesta de la  matemática.



    Los comandos de traslación, rotación y escalado vienen explicados en Apendice 1: Visualización así que aquí me limitaré a nombrarlos.



   Traslación

void glTranslate{fd}(TYPE x, TYPE y, TYPE z);

Multiplica la matriz actual por una matriz de traslación que mueve el objeto.s



   Rotación

void glRotate{fd}(TYPE angle,TYPE x, TYPE y, TYPE z);

Multiplica la matriz actual por una matriz de rotación que rota el objeto en la dirección de las agujas del reloj sobre el radio de origen en el punto x,y,z.



   Escalado

void glScale{fd}(TYPE x, TYPE y, TYPE z);

            Multiplica la matriz actual por una matriz que cambia el tamaño del objeto a lo largo de los ejes. Las coordenadas

            x, y, z de cada objeto es multiplicada por los parámetros x, y, z.

C    Como dijimos anteriormente en nuestro ejemplo solamente aplicaremos las transformaciones de rotación y traslación. Para poder mover y rotar el cuadrado, vamos a declarar unas variables globales:

float fRotx,fRoty;

float fDesz=-3.0f;

Las dos primeras son los ángulos que vamos a rotar con respecto al eje x e y respectivamente. La tercera variable corresponde con el desplazamiento a travez del eje z (perpendicular a la pantalla). Gráficamente sería:



                 

Pila de Matrices

En la función display() se encuentran las llamadas a dos funciones de matrices

 glPushMatrix() y glPopMatrix().

glTranslatef() que se utiliza para posicionar uno de los objetos.

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.

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().

glGetDoublev() Con esta función se obtiene la matriz actual de una de las pilas, a la que se indica que matriz se quiere obtener.















Viewport

Es poco probable que necesites usar el control Viewport (Vista) directamente. Es mucho más probable que uses el control ScrolledWindow, el cual usa un Viewport.

Un control de vista permite colocar un control más grande dentro de él de tal forma que se pueda ver una parte de él de una vez. Usa Adjustments para definir el área que se ve.

Un Viewport se crea con la función:

  viewport = gtk.Viewport(hadjustment=None, vadjustment=None)

Como se puede ver se pueden especificar los Adjustments horizontal y vertical que el control usa cuando se crea. Creará sus propios ajustes si se le pasa None como valor de los argumentos o simplemente no se le pasan argumentos.

Se pueden consultar y fijar los ajustes después de que el control se haya creado usando los siguientes cuatro métodos:

  viewport.get_hadjustment()

  viewport.get_vadjustment()

  viewport.set_hadjustment(adjustment)

  viewport.set_vadjustment(adjustment)

El otro método que se usa para modificar la apariencia es:

  viewport.set_shadow_type(type)

Los valores posibles para el parámetro type son:

  SHADOW_NONE         # sin sombra
  SHADOW_IN           # sombra hacia adentro
  SHADOW_OUT          # sombra hacia afuera
  SHADOW_ETCHED_IN    # sombra marcada hacia adentro
  SHADOW_ETCHED_OUT   # sombra marcada hacia fuera

Cubo en 3d

#include <GL/glut.h>
#include <GL/gl.h>
GLfloat anguloCuboY;
void drawCube(void)
{
      glColor3f(.50f, 0.0f, 0.0f);
    glBegin(GL_QUADS);      
 glVertex3f(  0.0f,  0.0f,0.0f); 
 glVertex3f(50.0f,  0.0f,0.0f);
 glVertex3f(50.0f,50.0f,0.0f);
 glVertex3f(  0.0f,50.0f,0.0f);  
    glEnd();
    glColor3f(1.0f, 1.0f, 1.0f);
    glBegin(GL_QUADS);      
    glVertex3f(  0.0f,50.0f,-50.0f);
 glVertex3f(50.0f,50.0f,-50.0f);
 glVertex3f(50.0f,  0.0f,-50.0f);
 glVertex3f(  0.0f,  0.0f,-50.0f);
    glEnd();
    glColor3f(0.0f, 0.0f, 1.0f);
    glBegin(GL_QUADS);      
    glVertex3f(50.0f,  0.0f,   0.0f);
 glVertex3f(50.0f,  0.0f,-50.0f);
 glVertex3f(50.0f,50.0f,-50.0f);
 glVertex3f(50.0f,50.0f,   0.0f);
    glEnd();
    glColor3f(1.0f, 1.0f, 0.0f);
    glBegin(GL_QUADS);     
    glVertex3f(0.0f,50.0f,   0.0f);  
    glVertex3f(0.0f,50.0f,-50.0f);
 glVertex3f(0.0f,  0.0f,-50.0f);
 glVertex3f(0.0f,  0.0f,   0.0f); 
    glEnd();
    glColor3f(0.0f,1.0f, 1.0f);
    glBegin(GL_QUADS);     
   
 glVertex3f(50.0f,50.0f,-50.0f);
 glVertex3f(  0.0f,50.0f,-50.0f);
 glVertex3f(  0.0f,50.0f,   0.0f);  
 glVertex3f(50.0f,50.0f,   0.0f);
    glEnd();

    glColor3f(1.0f, 0.0f, 1.0f);
    glBegin(GL_QUADS);      
     glVertex3f( 0.0f,0.0f,-50.0f);
 glVertex3f(50.0f,0.0f,-50.0f);
 glVertex3f(50.0f,0.0f,   0.0f);
 glVertex3f(  0.0f,0.0f,   0.0f); 
    glEnd();
}
void myinit(void)
{


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-75,75,-75,75,1,500.0);
glMatrixMode(GL_MODELVIEW);

}
void init()
{
    glClearColor(0,0,0,0);
    glEnable(GL_DEPTH_TEST);
}

void display(void) 
{
 glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
 glLoadIdentity();
 glTranslatef(0.0f,0.0f,-75.0f);
   
 glRotatef(anguloCuboY, 1.0f,1.0f,0.0f);
 drawCube();

    glFlush();
  glutSwapBuffers();
 anguloCuboY+=0.1f;

}

int main(int argc, char** argv) 
{
        glutInit(&argc, argv);
    
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
        glutInitWindowSize(650, 650);
        glutCreateWindow("Cubo 3D");
         init();
        glutDisplayFunc(display);
   myinit();
  glutIdleFunc(display);
        glutMainLoop();
  return 0;
}











lunes, 12 de marzo de 2012

Proyeccion Ortogonal y Perspectiva.


Proyección Ortogonal 

Es aquella cuyas rectas proyectantes auxiliares son perpendiculares al plano de proyección (o a la recta de proyección), estableciéndose una relación entre todos los puntos del elemento proyectante con los proyectados.

En el plano, la proyección ortogonal es aquella cuyas líneas proyectantes auxiliares son perpendiculares a la recta de proyección L.

Así, dado un segmento AB, bastará proyectar los puntos "extremos" del segmento –mediante líneas proyectantes auxiliares perpendiculares aL–, para determinar la proyección sobre la recta L.

Una aplicación de proyecciones ortogonales son los teoremas de las Relaciones métricas en el triángulo mediante las cuales se puede calcular la dimensión de los lados de un triángulo.

El concepto de proyección ortogonal se generaliza a espacios euclidianos de dimensión arbitraria, inclusive de dimensión infinita. Esta generalización juega un papel importante en muchas ramas de matemática y física.



Proyección Perspectiva.

La proyección perspectiva es el ángulo de donde se mira un objeto, pudiendo estar desde arriba o desde abajo o en cualquiera de los ángulos laterales del objeto

Preguntas:

1. Puede diferenciar entre los dos tipos de proyección?

En la ortogonal solo se puede apreciar desde un solo ángulo  y en perspectiva la profundidad con que se ve la imagen depende del ángulo de visión.

2. Entiende para que se usan las matrices y como las maneja opengl? expliquelo.

OpenGL almacena las matrices en un array unidimensional de 16 elementos y es el programador quien decide cómo prefiere interpretarlas.

3. Que es la matriz identidad y para que se utiliza en opengl?

- Matriz diagonal en la que los elementos de la diagonal principal son iguales a 1.

4. Haga  otro programa con el cubo pero con proyección  en perspectiva

5. Explique las diferencias

La diferencia seria que el primer cubo solo se puede ver la cara frontal o solo apreciar un lado pero en el de perspectiva se puede ver todas las caras.




Unidad 2 Glosari



Coordenadas Geométricas:  Instrumento usado para describir un punto en el espacio proyectivo.  


Stack: Es una lista ordinal o estructura de datos en la que el modo de acceso a sus elementos es de tipo LIFOque permite almacenar y recuperar datos. Esta estructura se aplica en multitud de ocasiones en el área de informática debido a su simplicidad y ordenación implícita de la propia estructura.

Transformaciones Geometricas


2.4. Transformación Ventana-Área de Vista
Algunos paquetes gráficos permiten que el programador especifique coordenadas de primitivas de salida en un sistema de coordenadas de mundo de punto flotante, usando las unidades que sean relevantes para el programa de aplicación: angstroms, micras, metros, millas, años luz, etcétera. Se emplea el término de mundo porque el programa de aplicación representa un mundo que se crea o presenta interactivamente para el usuario:
Como las primitivas de salida se expresan en coordenadas de mundo, hay que indicar al paquete de subrutinas gráficas cómo establecer la correspondencia entre las coordenadas de mundo y las coordenadas de pantalla (usaremos el término específico coordenadas de pantalla para relacionar este análisis específicamente con SRGP, pero podrían usarse dispositivos de impresión, en cuyo caso sería más apropiado el término coordenadas de dispositivo).

2.5. Transformaciones de Composición General y de Eficiencia Computacional
Una transformación bidimensional general, que representa una combinación de traslaciones, rotaciones y escalaciones. Solo necesitamos efectuar cuatro multiplicaciones y cuatro adiciones para transformar las posiciones de las coordenadas. Este es el número máximo de cálculos que se requieren para cualquier secuencia de transformación, una vez que se han concatenado las matrices individuales y evaluadas los elementos de la matriz compuesta. Sin concatenación, se aplicarían las transformaciones individuales una a la vez y se podría reducir en forma considerable el número de cálculos. De esta manera, una implementación eficiente de las operaciones de transformación consiste en formular matrices de transformación, concatenar cualquier secuencia de transformación y calcular las coordenadas transformadas

2.6. Representación Matricial de Transformaciones Tridimensionales
Así como las transformaciones bidimensionales se pueden representar con matrices de3 X 3 usando coordenadas homogéneas, las transformaciones tridimensionales se pueden representar con matrices de 4 X 4, siempre y cuando usemos representaciones de coordenadas homogéneas de los puntos en el espacio tridimensional. Así, en lugar de representar un punto como (x, y, z ), lo hacemos como (x, y, z, W ), donde dos de estos cuádruplos representan el mismo punto si uno es un multiplicador distinto de cero del otro: no se permite el cuádruplo (0, 0, 0, 0). Como sucede en el espacio bidimensional, la representación estándar de un punto (x, y, z, W ) con W ≠ 0 se indica (x/W, y/W, z/W, 1).


2.7. Composición de Transformaciones Tridimensionales
El objetivo es transformar los segmentos de línea dirigida P1P2 y P1P3 en la figura 2.18 de su posición inicial en la parte (a) a su posición final en la parte (b). De esta manera, el punto P1 se trasladará al origen P 1P2 quedará en el eje positivo y P 1P3 quedará en la mitad del eje positivo del plano (x, y ). Las longitudes de las líneas no se verán afectadas por la transformación. Se presentan dos formas de lograr la transformación deseada. El primer método es componer las transformaciones primitivas T , R x , Ry y Rz . Este método, aunque es algo tedioso, es fácil de ilustrar y su comprensión nos ayudará en nuestro conocimiento de las transformaciones. El segundo método, que utiliza las propiedades de las matrices ortogonales especiales que se analiza en la sección anterior, se explica de manera mas breve pero es más abstracto.