Informática Gráfica PRÁCTICA 4. Transformaciones geométricas.

EJERCICIOS

Inicialmente debes construir un nuevo proyecto (practica4). Una vez creado, copia en el directorio de trabajo los ficheros examinar.c, examinar.h y la librería creada en la práctica anterior glig.c con su fichero prototipo glig.h. Añádelos al proyecto (por supuesto, acuérdate de añadir también las librerías glu32.lib, glut.lib y opengl32.lib).

1. Para la realización de esta práctica vas a necesitar una nueva primitiva que dibuje un cono. Añádela a tu librería glig.c.

void igWireCone (int pu, int pv); /* s1= 2.0, s2= 1.0, uMax= 1.0, vMax= 0.5 */

2. Utiliza las primitivas de la librería glig.c, para construir un abeto como el de la figura, sin utilizar las funciones glPushMatrix() y glPopMatrix(). Para ello crea una display list como en el ejemplo e introduce en su definición el código necesario para dibujar el abeto:

void CreaAbeto (void)

{

abeto = glGenLists (1);

if (abeto != 0) /* Cero no es un identificador valido para una display list */

{

glNewList (abeto, GL_COMPILE);

/* Código para dibujar el abeto */

glEndList ();

}

}

Los pasos a seguir para dibujar el abeto son:

  1. Dibuja el primer cono con los siguientes factores de escala: Sx=0.75 Sy=1.0 Sz=0.75.
  2. A continuación, dibuja dos nuevos conos aplicando los mismos factores de escala y trasladándolos sobre el eje Y, Tx=0.0 Ty=0.25 Tz= 0.0.
  3. Finalmente, dibuja el tronco llamando a la función igWireRulo(int pu, int pv).

Desde la función principal (main) debes llamar una única vez a CreaAbeto(). Para dibujar el abeto como una display list, llama desde la función Dibuja() a:
glCallList (abeto);

3. Construye el mismo abeto pero mediante el uso de las funciones  glPushMatrix() y glPopMatrix(). Es decir, haz que cada primitiva tenga sus transformaciones propias y que estas no afecten a las otras primitivas. Declara una nueva display list (abetoPush) y crea la display list para dibujar el abeto con las funciones glPush() y glPop() y llámala CreaAbetoPush().Comprueba que los dos abetos son iguales dibujando uno sobre otro con distintos colores.

4. Utilizando las primitivas de la librería glig.c, construye una display list para una escalera de caracol (escalera). Introduce el código en la función CreaEscalera(). Los pasos son los siguientes:

  1. Dibuja una caja a modo de eje de la escalera de altura=2.0 y lado= 0.2
  2. Realiza un bucle para dibujar cada uno de los escalones. Los escalones están escalados con factores de escala, Sx=0.5 Sy= 0.05 Sz=0.1. La separación entre escalones es de 0.2.

5. Realiza la construcción de la figura (lo más parecida posible) de acuerdo con los siguientes pasos:

  1. En primer lugar define una función Arco() que construya un arco individual (con tres cajas)
  2. Utiliza ese elemento para realizar la construcción circular.

modelado abetomodelado abeto pushmodelado escaleramodelado patioexaminar.c


/*************************************************************************/
/*                                                                       */
/*   examinar.c                                                          */
/*   Rev. 2.0  01/01/2002   AUTORES: O. Belmonte, M. Chover, J. Ribelles */
/*                                                                       */
/*************************************************************************/

/***************** INCLUDES DE LAS LIBRERIAS NECESARIAS ******************/
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include "examinar.h"
#include "glig.h"

/******************************************************************************************/
/* Establece el area visible y el tipo de proyeccion                                      */
/* Parametros: int ancho --> Ancho del area visible                                       */
/*             int alto --> Alto del area visible                                         */
/* Salida: Ninguna                                                                        */
/******************************************************************************************/
void TamanyoVentana (GLsizei ancho, GLsizei alto)
{
 /* Definicion del viewport */
 glViewport(0, 0, ancho, alto);

 /* Definicion de la vista */
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 glOrtho(-2.0, 2.0, -2.0*(GLfloat)alto/(GLfloat)ancho, 2.0*(GLdouble)alto/(GLfloat)ancho, -2.0, 2.0);
}

/******************************************************************************************/
/* Abre una ventana OpenGL                                                                */
/* Parametros: int numeroArgumentos --> El numero de argumentos en la llamada al programa */
/*             char ** listaArgumentos --> Vector de cadenas con cada argumento           */
/* Salida: Ninguna                                                                        */
/******************************************************************************************/
void AbreVentana (int numeroArgumentos, char ** listaArgumentos)
{
 glutInit(&numeroArgumentos, listaArgumentos);
 glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
 glutInitWindowSize (VentanaAncho, VentanaAlto);
 glutInitWindowPosition (VentanaX, VentanaY);
 glutCreateWindow (listaArgumentos[0]);
 glutDisplayFunc (Dibuja);
 glutReshapeFunc (TamanyoVentana);
 glClearColor (0.0f, 0.0f, 0.0f, 0.0f); /* Establece el color de borrado */
 glClear (GL_COLOR_BUFFER_BIT); /* Borra el buffer de color */
 glColor3f (1.0f, 1.0f, 1.0f); /* Establece el color de dibujo */
}

/******************************************************************************************/
/* Define las acciones tras una pulsacion del teclado                                     */
/* Parametros: unsigned char key --> Codigo de la tecla pulsada                           */
/*             int x --> Coordenada x del cursor en el momento de pulsar la tecla         */
/*             int y --> Coordenada y del cursor en el momento de pulsar la tecla         */
/* Salida: Ninguna                                                                        */
/******************************************************************************************/
void Teclado (unsigned char tecla, int x, int y)
{
 switch (tecla)
 {
 case 27 : /* Codigo de la tecla de Escape */
 exit(0);
 break;
 }
}

/******************************************************************************************/
/* Define las acciones tras una pulsacion del teclado ampliado                            */
/* Parametros: unsigned char key --> Codigo de la tecla pulsada                           */
/*             int x --> Coordenada x del cursor en el momento de pulsar la tecla         */
/*             int y --> Coordenada y del cursor en el momento de pulsar la tecla         */
/* Salida: Ninguna                                                                        */
/******************************************************************************************/
void TecladoAmpliado (int tecla, int x, int y)
{
 switch (tecla)
 {
 case GLUT_KEY_UP : /* Pulsacion cursor arriba del teclado ampliado */
 beta = beta + 15.0;
 if (beta > 360.0) beta = beta - 360.0;
 break;

 case GLUT_KEY_DOWN : /* Pulsacion cursor abajo del teclado ampliado */
 beta = beta - 15.0;
 if (beta < 0.0) beta = beta + 360.0;
 break;

 case GLUT_KEY_RIGHT : /* Pulsacion cursor derecha del teclado ampliado */
 alfa = alfa + 15.0;
 if (alfa > 360.0) alfa = alfa - 360.0;
 break;

 case GLUT_KEY_LEFT : /* Pulsacion cursor izquierda del teclado ampliado */
 alfa = alfa - 15.0;
 if (alfa < 0.0) alfa = alfa + 360.0;
 break;
 }
 glutPostRedisplay ();
}

/* Rutina de definiciÛn de eventos */
/******************************************************************************************/
/* Inicia las funciones de callback                                                       */
/* Parametros: Ninguno                                                                    */
/* Salida: Ninguna                                                                        */
/******************************************************************************************/
void IniciaFuncionesCallback (void)
{
 glutKeyboardFunc (Teclado);
 glutSpecialFunc (TecladoAmpliado);
}

/******************************************************************************************/
/* Funcion de dibujado                                                                    */
/* Parametros: Ninguno                                                                    */
/* Salida: Ninguna                                                                        */
/******************************************************************************************/
void Dibuja (void)
{
 glClear (GL_COLOR_BUFFER_BIT);

 /* Transformacion de la camara */
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
 glRotated (beta, 1.0,0.0,0.0);
 glRotated (-alfa, 0.0,1.0,0.0);

 glCallList (cuadrica);
 glCallList(abetoPush);
 glCallList (abeto);
 glCallList(escalera);
 glCallList(patio);

 /* Objetos */
 //glutWireTeapot(1.0);
 //glutWireIcosahedron();
 //glutWireTetrahedron();
 //glutWireOctahedron();
 //glutWireDodecahedron();
 //glutWireTorus(0.2,0.9,18,20);
 //glutWireCone(0.5, 2.0, 14, 14);
 //glutWireCube(1.0);
 //glutWireSphere(1, 20,50);

 //igCreateQuadricObject(50,80,0,0,1.0, 1, 1);
 //igWireSphere (50, 50);

 //igWireRulo (200, 200);
 //igWireDado (60, 60);
 //igWireSemiSphere (50, 50); // s1 y s2 a 1, uMax= 1, vMax= 0.5 */
 //igWireCubo();
 glFlush();
}

void IniciaCuadricas (void)
{
 cuadrica = glGenLists (1);
 escalera=glGenLists(1);
 abeto=glGenLists(1);
 abetoPush=glGenLists(1);
 patio=glGenLists(1);

 if (cuadrica != 0) /* Cero no es un identificador valido para una display list */
 {
 //glNewList (cuadrica, GL_COMPILE);
 //igCreateQuadricObject (20,20,0,0,1.0f, 1.0f, 1.0f);
 //igWireCubo();
 //igWireRulo(20, 20);
 //igWireCone(10,3);
 //igWireSphere(30, 30);
 //glEndList ();
 printf("Cuadratica\n");
 }
 if (escalera!=0)
 {
 //CreaEscalera();
 printf("Escalera\n");
 }
 if (abeto!=0)
 {
 //CreaAbeto();
 printf("Abeto\n");
 }
 if (abetoPush!=0)
 {
 glNewList(abetoPush, GL_COMPILE);
 //CreaAbetoPush();
 glEndList();
 printf("AbetoPush\n");
 }
 if (patio!=0)
 {

 CreaPatio();
 printf("patio\n");
 }

}

/******************************************************************************************/
/* Funcion principal                                                                      */
/* Parametros: int numeroArgumentos --> El numero de argumentos en la llamada al programa */
/*             char ** listaArgumentos --> Vector de cadenas con cada argumento           */
/* Salida: Un entero que se devuelve al sistema al acabar la ejecucion del programa       */
/******************************************************************************************/
int main(int numArgumentos, char ** listaArgumentos)
{

 /* CreaciÛn de la ventana de la aplicaciÛn */
 AbreVentana (numArgumentos, listaArgumentos);

 /* Rutinas para el control de eventos */
 IniciaFuncionesCallback ();
 IniciaCuadricas();
 /* A la espera de eventos.... */
 glutMainLoop();
 return (0);
}

glig.c


/*************************************************************************/
/*                                                                       */
/*                 glig.c LIBRERIA DE MODELADO GEOMETRICO                 */
/*                                                                       */
/*   Rev. 2.0  01/01/2002   AUTORES: O. Belmonte, M. Chover, J. Ribelles */
/*                                                                       */
/*************************************************************************/

/***************** INCLUDES DE LAS LIBRERIAS NECESARIAS ******************/
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
#include "glig.h"

#define PI 3.1415926535897932
#define ALFA (0.5-v)*PI
#define BETA 2*PI*u

/************************* FUNCIONES BASICAS **********************************************/
/******************************************************************************************/
/* Devuelve la coordenada x de un punto en R3 a partir de un punto (u,v)                  */
/*   de un espacio parametrico en R2                                                      */
/* Parametros: float u --> Primera coordenada de un punto en R2                           */
/*             float v --> Segunda coordenada de un punto en R2                           */
/*             float R --> Radio de la esfera envolvente                                  */
/*             float s1 --> Numero de divisiones en u                                     */
/*             float s2 --> Numero de divisiones en v                                     */
/* Salida: La coordenada x de un punto en R3                                              */
/******************************************************************************************/
float xSuperQuadric (float u, float v, float R, float s1, float s2)
{
 float cosalfa, cosbeta, powcosalfa, powcosbeta;

 cosalfa = (float)cos(ALFA);
 cosbeta = (float)cos(BETA);

 if(cosalfa > 0.0)
 powcosalfa = (float)pow(cosalfa,s1);
 else
 powcosalfa =(float) - pow(- cosalfa,s1);

 if(cosbeta > 0.0)
 powcosbeta = (float)pow(cosbeta,s2);
 else
 powcosbeta = (float) - pow(- cosbeta,s2);

 return (R*powcosalfa*powcosbeta);

}

/******************************************************************************************/
/* Devuelve la coordenada y de un punto en R3 a partir de un punto (u,v)                  */
/*   de un espacio parametrico en R2                                                      */
/* Parametros: float u --> Primera coordenada de un punto en R2                           */
/*             float v --> Segunda coordenada de un punto en R2                           */
/*             float R --> Radio de la esfera envolvente                                  */
/*             float s1 --> Numero de divisiones en u                                     */
/*             float s2 --> Numero de divisiones en v                                     */
/* Salida: La coordenada y de un punto en R3                                              */
/******************************************************************************************/
float ySuperQuadric (float u, float v, float R, float s1, float s2)
{
 float sinalfa, powsinalfa;

 sinalfa = (float)sin(ALFA);

 if(sinalfa > 0.0)
 powsinalfa = (float)pow(sinalfa,s1);
 else
 powsinalfa = (float)- pow(- sinalfa,s1);

 return (R*powsinalfa);
}

/******************************************************************************************/
/* Devuelve la coordenada de un punto en R3 a partir de un punto (u,v)                    */
/*   de un espacio parametrico en R2                                                      */
/* Parametros: float u --> Primera coordenada de un punto en R2                           */
/*             float v --> Segunda coordenada de un punto en R2                           */
/*             float R --> Radio de la esfera envolvente                                  */
/*             float s1 --> Numero de divisiones en u                                     */
/*             float s2 --> Numero de divisiones en v                                     */
/* Salida: La coordenada z de un punto en R3                                              */
/******************************************************************************************/
float zSuperQuadric(float u, float v, float R, float s1, float s2)
{
 float cosalfa, sinbeta, powcosalfa, powsinbeta;

 cosalfa = (float)cos(ALFA);
 sinbeta=(float)sin(BETA);

 if(cosalfa > 0.0)
 powcosalfa = (float)pow(cosalfa,s1);
 else
 powcosalfa=(float) - pow(- cosalfa,s1);

 if(sinbeta > 0.0)
 powsinbeta = (float)pow(sinbeta,s2);
 else
 powsinbeta = (float) - pow(- sinbeta,s2);

 return(R*powcosalfa*powsinbeta);
}

/********************** RUTINA DE DIBUJO *********************************/

void igCreateQuadricObject (int pu, int pv, float uMax, float vMax, float R, float s1, float s2)
{
 /* pu es el numero de divisiones en u */
 /* pv es el numero de divisiones en v*/
 float u, v;
 float iniu,iniv;
 float inc_u; //incremento de u
 float inc_v; //incremento de v
 float x, y, z; /*almanezaran las coordenadas en el espacio tridimensional*/
 int   i,j;/*contadores para los bucles for*/
 v= uMax;
 u =vMax;
 iniu=u;
 iniv=v;
 /*El maximo valor de u y v es 1 y el minimo es 0 por lo tanto debemos de distribuir
 las partes exigidas en la distancia establecida entre el valor de inicialización y
 el maximo valor*/
 inc_u= (1.0f-u)/pu;
 inc_v= (1.0f-v)/pv;

 //Dibujamos los paralelos de la esfera
 //tantas circunfencias como partes de v
 for (j=0;j<pv;j++)
 {
 glBegin (GL_LINE_LOOP);//Indicamos a openGL el modo de dibujado
 //indicamos los puntos (partes de u) que formaran la circunferencia
 for (i= 0; i<= pu; i++)
 {
 x= xSuperQuadric (u, v, R, s1, s2);//indicamos la coordenada x del punto
 y= ySuperQuadric (u, v, R, s1, s2);//indicamos la coordenada y del punto
 z= zSuperQuadric (u, v, R, s1, s2);//indicamos la coordenada z del punto
 glVertex3f (x, y, z); //pintamos el punto en el espacio tridimensional
 u= u+ inc_u;//avanzamos hasta el siguiente putno
 //printf("valor de v=%f valor de u=%f\n",v,u);
 if (u>1){u=iniu;}
 }
 glEnd();//indicamos a openGL que hemos acabado de indicar los puntos de la circunferencia

 v+=inc_v;//avanzamos a la siguiente circunferencia paralela
 }

 u=iniu;
 v=iniv;
 //Dibujamos os meridianos de la esfera
 //tantos meridianos como partes de v
 for (j=0;j<pu;j++)
 {
 glBegin(GL_LINE_STRIP);//Indicamos a OpenGL el modo de dibujado
 //Indicamos los puntos (partes de v) que formaran el meridiano
 v=iniv;
 for(i=0;i<=pv;i++)
 {
 x= xSuperQuadric (u, v, R, s1, s2);//indicamos la coordenada x del punto
 y= ySuperQuadric (u, v, R, s1, s2);//indicamos la coordenada y del punto
 z= zSuperQuadric (u, v, R, s1, s2);//indicamos la coordenada z del punto
 glVertex3f (x, y, z); //pintamos el punto en el espacio tridimensional
 v+=inc_v;//avanzamos hasta el siguiente punto

 //printf("valor de v=%f valor de u=%f\n",v,u);
 }
 //printf("Meridiano dibujado\n\n");
 glEnd();//Indicamos a openGL que ya hemos señalado los puntos del meridiano
 u+=inc_u;//avanzamos al siguiente meridiano

 }
}

void igWireSphere (int pu, int pv)
{
 /* s1 y s2 a 1 */
 igCreateQuadricObject(pu,pv,0,0,1.0, 1, 1);

}

void igWireRulo (int pu, int pv)
{
 /* s1= 0.5, s2= 1 */
 igCreateQuadricObject(pu,pv,0,0,1.0, 0.5, 1);

}

void igWireDado (int pu, int pv)
{
 /* s1= 0.5, s2 =0.5 */
 igCreateQuadricObject(pu,pv,0,0,1.0, 0.5, 0.5);

}
void igWireSemiSphere (int pu, int pv)
{

 /* s1 y s2 a 1, uMax= 1, vMax= 0.5 */
 igCreateQuadricObject(pu,pv,0,0.5,1.0, 1, 1);

}

void igWireCubo (void)
{
 //Centramos en el origen de las coordenadas
 //El radio es 1
 glBegin (GL_LINE_LOOP);
 //aristas traseras
 glVertex3f(-0.5,-0.5,-0.5);
 glVertex3f(0.5, -0.5, -0.5);
 glVertex3f(0.5,0.5,-0.5);
 glVertex3f(-0.5,0.5,-0.5);
 glVertex3f(-0.5,-0.5,-0.5);
 //parte delantera
 glVertex3f(-0.5,-0.5,0.5);
 glVertex3f(-0.5,0.5,0.5);
 glVertex3f(0.5,0.5,0.5);
 glVertex3f(0.5,-0.5,0.5);
 glVertex3f(-0.5,-0.5,0.5);
 //lado izquierdo
 glVertex3f(-0.5,-0.5,-0.5);
 glVertex3f(-0.5,-0.5,0.5);
 glVertex3f(-0.5,0.5,0.5);
 glVertex3f(-0.5,0.5,-0.5);
 glVertex3f(0.5,0.5,-0.5);
 glVertex3f(0.5,0.5,0.5);
 glVertex3f(0.5,-0.5,0.5);
 glVertex3f(0.5,-0.5,-0.5);
 glEnd ();
}

void igWireCone (int pu, int pv)
{
/* s1= 2.0, s2= 1.0, uMax= 1.0, vMax= 0.5 */
 igCreateQuadricObject(pu, pv, 0.5, 0, 1, 2.0, 1.0);
}

void CreaAbetoPush(void)
 {
 //abetoPush= glGenLists(1);
 if (abetoPush != 0)
 {
 glNewList( abetoPush, GL_COMPILE);
 glColor3f(1,0,0);

 glPushMatrix();
 glRotated(180,0,0,1);
 glScalef(0.75, 1, 0.75);
 igWireCone(20, 20);
 glPopMatrix();

 glPushMatrix();
 glTranslatef(0,0.25, 0);
 glRotated(180,0,0,1);
 glScalef(0.75, 1, 0.75);
 glScalef(0.75, 1, 0.75);
 igWireCone(20, 20);
 glPopMatrix();

 glPushMatrix();
 glTranslatef(0, 0.5, 0);
 glRotated(180,0,0,1);
 glScalef(0.75, 1, 0.75);
 glScalef(0.75, 1, 0.75);
 glScalef(0.75, 1, 0.75);
 igWireCone(20, 20);
 glPopMatrix();

 glPushMatrix();
 glRotated(180,0,0,1);
 glScalef(0.75, 1, 0.75);
 glScalef(0.75, 1, 0.75);
 glScalef(0.75, 1, 0.75);
 glScalef(0.5, 1, 0.5);
 igWireRulo(15, 5);
 glPopMatrix();

 glEndList();
 }
 else
 {
 printf("Error al crear abetoPush\n");
 }

 }

void CreaAbeto (void)
{
 //abeto = glGenLists (1);
 if (abeto != 0) /* Cero no es un identificador valido para una display list */
 {
 glNewList (abeto, GL_COMPILE);
 /* Código para dibujar el abeto */
 /*Sx=0.75 Sy=1.0 Sz=0.75*/
 glColor3f(0,1,0);
 glRotated(180,0,0,1);
 glScalef(0.75,1,0.75);
 igWireCone(20, 20);
 glScalef(0.75,1,0.75);
 glTranslatef(0,-0.25,0);
 igWireCone(20, 20);
 glScalef(0.75,1,0.75);
 glTranslatef(0,-0.25,0);
 igWireCone(20, 20);
 glTranslatef(0, 0.5, 0);
 glScalef(0.5, 1, 0.5);
 igWireRulo(15, 5);
 glEndList ();
 }
}
void CreaEscalera(void)
 {
 int x;
 glNewList(escalera, GL_COMPILE);
 printf("mierda\n");
 //# Dibuja una caja a modo de eje de la escalera de altura=2.0 y lado= 0.2
 escalon();
 for(x=0;x<100;x++)
 {
 glPushMatrix();
 glRotated(90,1,0,0);
 //Sx=0.5 Sy= 0.05 Sz=0.1
 glScalef(0.5, 0.5, 0.1);

 glTranslatef(0,  0,-x*(0.2));
 glRotated((360/50)*x,0,0,1);
 escalon();
 glPopMatrix();
 }
 glEndList();

 }

void escalon(void)
 {
 glBegin (GL_LINE_LOOP);
 //base
 glVertex3f(-0.1,0,-0.1);
 glVertex3f(0.1,0,-0.1);
 glVertex3f(0.1,0,0.1);
 glVertex3f(-0.1,0,0.1);
 glVertex3f(-0.1,0,-0.1);
 //subimos
 glVertex3f(-0.1,2,-0.1);
 glVertex3f(0.1,2,-0.1);
 //bajamos y subimos
 glVertex3f(0.1,0,-0.1);
 glVertex3f(0.1,2,-0.1);
 glVertex3f(0.1,2,0.1);
 //bajamos y subimos
 glVertex3f(0.1,0,0.1);
 glVertex3f(0.1,2,0.1);
 glVertex3f(-0.1,2,0.1);
 //bajamos y subimos
 glVertex3f(-0.1,0,0.1);
 glVertex3f(-0.1,2,0.1);
 glVertex3f(-0.1,2,-0.1);
 glEnd();
 }

void CreaPatio(void)
 {
 int x;

 glNewList( patio , GL_COMPILE);
 for(x=0;x<12;x++)
 {
 glPushMatrix();
 glScalef(0.2, 0.2, 0.2);
 glRotated(30*x, 0, 1, 0);
 glTranslatef(0, 0, -4);
 arco();
 glPopMatrix();
 }
 glEndList();
 }

void arco(void)
 {
 glPushMatrix();
 //glColor3f(1, 0, 0);//rojo
 glTranslatef(-0.75, 0, 0);
 columna();
 glPopMatrix();
 glPushMatrix();
 //glColor3f(0, 1, 0);//verde
 glTranslatef(0.75, 0, 0);
 columna();
 glPopMatrix();
 glPushMatrix();
 //glColor3f(0, 0, 1);//azul
 glRotated(270, 0, 0, 1);
 glTranslatef(-1.75, -1, 0);
 columna();
 glPopMatrix();
 }

void columna(void)
 {
 glBegin (GL_LINE_LOOP);
 //base
 glVertex3f(-0.25,0,-0.25);
 glVertex3f(0.25,0,-0.25);
 glVertex3f(0.25,0,0.25);
 glVertex3f(-0.25,0,0.25);
 glVertex3f(-0.25,0,-0.25);
 //subimos
 glVertex3f(-0.25,2,-0.25);
 glVertex3f(0.25,2,-0.25);
 //bajamos y subimos
 glVertex3f(0.25,0,-0.25);
 glVertex3f(0.25,2,-0.25);
 glVertex3f(0.25,2,0.25);
 //bajamos y subimos
 glVertex3f(0.25,0,0.25);
 glVertex3f(0.25,2,0.25);
 glVertex3f(-0.25,2,0.25);
 //bajamos y subimos
 glVertex3f(-0.25,0,0.25);
 glVertex3f(-0.25,2,0.25);
 glVertex3f(-0.25,2,-0.25);

 glEnd();
 }

Posibles preguntas para el primer examen practico de TALF

tirando de archivo me encontre unas preguntitas de exámenes prácticos de talf:

Modelar el autómata tal que acepte el lenguaje que contenga palabras con 2 o más pares de ceros consecutivos .

Ej 0000 , 100100100 , 111111001100 , 11111100100100100

autómata que contenga dos pares de ceros consecutivos

Tomado de la corrección en el primer comentario

Modelar el autómata tal que acepte el lenguaje que contenga palabras con como mínimo 4 ceros .

minimo 4  cerosModelar el autómata tal que acepte el lenguaje tal que { a^n b^m / n>= 1 y m>=2 }

una a dos besModelar el autómata tal que acepte el lenguaje tal que formula_3

tres a dos b alguna cModelar el autómata tal que acepte el lenguaje tal que acepte todos los binarios excepto los que contengan la subcadena 101.

Lo hacemos por el método del complemento primero modelamos un autómata que acepte palabras que contengan la subcadena 101.

acepta subcadena 101aplicamos el metodo del complemento (los estados finales se transforman en no finales y viceversa)

no acepta subcadena 101

Modelar el autómata tal que acepte el lenguaje binario tal que la tercera cifra por la derecha sea distinta a la segunda cifra por la izquierda.

segundo izquierda distinto tercero derechaDado un alfabeto {a, b, c}, construir un AFD que acepte aquellas palabras que contengan al menos dos ‘a’, una ‘b’ y una ‘c’

dos a una b una cteneis aqui el Autómata

Practica 5 TALF

Enunciado practica 5

Autómatas finitos no deterministas

1.- Dado el autómata finito no determinista descrito por la siguiente tabla, obtener el autómata finito determinista y posteriormente minimizarlo. El alfabeto que usa el autómata se compone de los símbolos: ∑ = {a,b}; el estado inicial es q0; y los estados finales q2 y q4.

tabla autómata 1modelamos el autómata en JFlap

autómata sin minimizar 1Ahora es el momento de minimizarlo, primero debemos transformarlo en un AFD. para eso seleccionamos la opción (“Convert to DFA”) del menú Convert.

convirtiendo a AFD

Pinchamos en Complete y finalmente en Done? lo que nos creara un AFD en una nueva ventana.

AFD convertido

Pinchamos en la opción minimize DFA del menú convert para obtener el AFD mínimo

minimizando

Pinchamos en el primer elemento del árbol de estados y pinchamos en el botón “Complete Subtree” para posteriormente pinchar en el botón “finish”

Esto creara una nueva ventana con el conjunto de estados.

conjunto de estados

pinchamos en “complete” para que cree los enlaces

enlaces creados

y finalmente en “done” que nos mostrara una ventana con el AFD minimizado.

AFD minimo

2.- Dado el autómata finito no determinista descrito por la siguiente tabla, obtener el autómata finito determinista y posteriormente minimizarlo. El alfabeto que usa el autómata se compone de los símbolos: ∑ = {0,1}; el estado inicial es q0; y el estado final q1.

tabla autómata 2

modelamos el autómata en JFLAP

lo transformamos en un AFD siguiendo los pasos del ejercicio anterior.

y lo minimizamos igual que en el ejercicio anterior.

Hoja 6 (6 de Abril de 2010)

P1: ¿Qué lenguajes definen las siguientes expresiones regulares?

  • Expresión regular numero 1: (((0.1)∗ + (0.1)∗ .0) + ((1.0)∗ + (1.0)∗ .1))
    Descomponemos la expresión regular

primera formula despiece webempezamos a descomponer la expresión regular a partir de los nodos finales (marcados en rojo).

Primera Formula Nodos finales marcadosPaso 1:  intentamos minimizar los nodos finales: en esta expresión no se puede

Paso 2:Describimos el lenguaje de cada nodo final:

  • :  cero o mas repeticiones  de la cadena 01
  • :cero o mas repeticiones de la cadena 01
  • : Cadena 0
  • formula 1 nodo final 4:cero o mas repeticiones de la cadena 10
  • formula 1 nodo final 5: Cadena 1

subimos al nivel anterior y unimos los nodos en los que sus elementos siguientes estén descritos hasta que lleguemos a la raíz del árbol.

formula 1  primera iteracion miramos si podemos minimizar los nodos a describir (marcados de rojo), en este caso no podemos.

asi que describimos los nodos en los que nos encontramos

  • formula 1 segunda interacion nodo 1: cero o mas repeticiones  de la cadena 01 unidas con 0
  • formula 1 segunda iteracion nodo 2:cero o mas repeticiones de la cadena 10 unidos con 1

nueva iteración. subimos al nivel superior

formula 1 tercera iteracion nodo 1

miramos si podemos minimizar los nodos a describir (marcados de rojo), en este caso no podemos.

asi que describimos los nodos en los que nos encontramos

  • formula 1 tercera iteracion nodo 1: cero o mas repeticiones de la cadena 01 ó cero o mas repeticiones  de la cadena 01 unidas con 0

subimos

ultima subida

Describimos la expresión regular  uniendo los elementos anteriores (+=0) (*=y)

cero o mas repeticiones de la cadena 01 ó cero o mas repeticiones  de la cadena 01 unidas con 0, o cero o mas repeticiones de la cadena 10 unidos con 1

Expresión regular numero 2: expresion regular numero dos

Paso 1: Descomponemos la expresión regular en pequeñas expresiones.

expresion regular numero 2 descompuesta

marcamos los nodos finales

expresion regular numero 2 nodos finalesMinimizamos los nodos finales, en este caso no se puede

Describimos los nodos finales

  • expresión_2_nodo_1:  la cadena 1 o nada
  • expresion numero 2 nodo 2: cero o mas repeticiones de la cadena 01
  • expresion 2 nodo 3:la cadena 0 o nada

subimos al siguiente nivel de la estructura

expresion regular numero 2 segunda iteracion

intentamos minimizar la expresión actual: no se puede

Describimos la expresión actual.

  • expresion regular numero dos:la cadena 1 o nada unida a cero o mas repeticiones de la cadena 01 unida a la cadena 0 o nada

  • Expresión regular numero 3 expresion regular numero 3

Paso 1: Descomponemos la expresión regular en pequeñas expresiones.

Arbol tercera expresion regular

marcamos los nodos finales

Arbol 3 era expresion nodos finales marcadosintentamo minimizar algún nodo final en este caso si que podemos

  • primera equivalencia
  • segunda equivalencia

empezamos a minimizar hacia arriba y nos queda la siguiente expresión minimizada

expresion regular numero 3 minimizada

describimos las expresiones del segundo nivel

  • minimizados primer elemento: la cadena 01
  • minimizado segundo elemento: cero o mas repeticiones de la cadena  con 0 o mas repeticiones de cero o de la cadena 01
  • : la cadena 1

por lo tanto el lenguaje que define esta expresión regular es: la cadena 01 o cero o mas repeticiones de la cadena  con 0 o mas repeticiones de cero o de la cadena 01 unido a la cadena 1

P2: Escribe una expresión regular sobre el alfabeto {a, b, c} que define todas las palabras que tengan dos a’s consecutivos o dos b’s consecutivos.

(a+b+c)*.((aa)+(bb)).(a+b+c)*

P3: Construye según procedimiento visto en clase un AFND–ε que acepta las mismas palabras que define la expresión regular de P1 apartado 2.
modelamos  las pequeñas expresiones el las que hemos descompuesto la expresión 2:

expresión_2_nodo_1

primer subautomata

expresion numero 2 nodo 2

2a_parte

expresion 2 nodo 3

Ahora unimos las partes en un autómata .

Practica 4 TALF

Enunciado Practica 4

afnd1

1.- Dado el AFND- ε afnd1
a. Marcar los estados no deterministas

Pinchamos en Test ->  Highlight NonDeterminism

Estados no deterministas marcados

b. Marcar las transacciones ε (λ)

Pinchamos en Test ->  Highlight λ-Transitions

transiciones epsilon

c. Indica la traza de todos los caminos recorridos hasta aceptar o no aceptar
las palabras:

  • aaabbaab
    • No existen trazas en las que  acepte el automa
    • Trazas que no aceptan
  • aaaaaabbbbbb
    • Trazas que Acepta
    • Trazas que no Acepta

NOTA: utiliza para ello todas las opciones del Step by State (Step,Reset,Freeze,Thaw,Trace, Remove)

2.-Modela un autómata sobre el paso de una persona de un estado civil a otro: tener en cuenta al menos los estados civiles “soltero”, “casado”, “divorciado”, “viudo”. Considere al divorcio como un proceso con duración (instantáneo).

estados civiles

3.-Diseñar usando el método del complemento un AFD que acepte las palabras en {a, b} que no inicien con abab.

metodo complemento

4.- Construir autómatas finitos deterministas que acepten cada uno de los lenguajes siguientes.
a.

no 4 as

b. Los números binarios en los que la primera cifra es diferente de la última.

numeros binarios
c. Todas las cadenas sobre  que contienen al menos una vez cada símbolo de  .

todos los símbolos del alfabeto

Practica 3 TALF

Enunciado de la practica Enunciado Practica 3 Talf.

1.-Introduce en JFlap el siguiente autómata e intenta averiguar que lenguaje describe

autómata ejercicio 1Para averiguar que lenguaje genera el autómata la forma mas intuitiva es transformarlo en una expresión regular,  en el menu de JFlap seleccionamos “Convert->Convert FA to RE”

Convert FA to REpinchamos en el boton “Do It” el cual generara transiciones vaciás entre estados

Empty trasitions addedVolvemos a pinchar en “Do It” para eliminar estados no iniciales o no finalesintermediate states eliminated

la etiqueta de informacion situada debajo de la pestaña de conversión nos indica que la transformación de autómata finito a expresion regular esta completada, por lo tanto ya podemos pinchar en el botón Export el cual creara una nueva ventana mostrándonos la expresión regular

expresión regular

por lo tanto el lenguaje que crea este autómata  esta compuesto por un numero de caracteres (a>=0)  una letra b y un numero de repeticiones de la cadena bb>=0

2.- Modela el autómata que reconozca cadenas con un número par de “0”s y “1”s

Partimos de que 0 es par por lo tanto ε es una palabra valida, y el estado inicial.

Los posibles estados para este autómata son:

  • Numero de 1’s par y numero de 0’s par
  • Numero de 1’s par y numero de 0’s impar
  • Numero de 1’s impar y numero de 0’s par
  • Numero de 1’s impar y numero de 0’s impar

creamos un nuevo autómata en JFlap introduciendo los cuatro posibles estados:

estados autómatahabíamos quedado en que ε tiene un numero par de 0’s y un numero par de 1’s por lo tanto 1P0P es estado inicial y final. Asi que lo que nos queda es completar las transiciones.

automata numero de unos paresy numero de  ceros pares3.- Autómata que reconozca cadenas impares de de “0”s y “1”s

igual que el apartado anterior pero cambiando el estao final en lugar de 1P0P es 1I0I

automata unos impares ceros impares4.- Construye un AFD que acepte identificadores, con las siguientes características
a. Solo letras vocales minúsculas
b. Es válido el carácter de subrayado, con la condición que como máximo exista uno
c. No se permiten espacios en blanco
d. También puede tener números, pero no pueden estar al principio ni al final del identificador, ni haber más de tres consecutivos

automata 4

TALF Hoja 4 (16 de Marzo de 2010)

P1: Convierte el AFND de la hoja anterior en un autómata finito determinista. Incluye en tu solución la tabla de conversión tal como lo vimos en clase, la quintupla del AFD obtenido finalmente, y su grafo.

Partimos del siguiente AFND.

AFND BaseAñadimos el estado de Error.

AFND Base con estado de error

Comenzamos a crear la tabla de conversión

partimos del estado inicial {a}. con 0 vamos a {a} y con 1 a {a,b}

Tabla AFND AFD paso 1{a} ya pertenece al conjunto de estados, pero {a,b} no por lo tanto añadimos el estado {a,b}.

Tabla AFND AFD paso 2en el conjunto {a,b} con valor 0  a nos lleva a {a} y b nos lleva a {c,d} por lo tanto {a,b} con 0 nos lleva a {a,c,d} como {a,c,d} no esta en el conjunto de estados lo añadimos y añadimos las transiciones.

Tabla AFND AFD paso 3repetimos el procedimiento hasta que no se creen mas elementos para el conjunto de estados. quedándonos la siguiente tabla (a menos que me haya equivocado)

Tabla AFND AFD paso final

ahora pasamos la tabla a un grafo.

AFD sin estados finales ni inicialesLos primeros estados iniciales de nuestro AFND “con los que empezamos la tabla” son nuestros estados iniciales, en esta caso A.

AFD sin estados finales pero con inicialesTodo estado del AFD donde exista un estado final del AFND es final (en este caso todos donde este d)

AFD convertidoFinalmente la quintupla queda definida por:
M=(∑,Q,δ,q0,F)

siendo

  • ∑   El alfabeto
  • Q   Conjunto finito de estados
  • δ    la función de transición
  • q0 conjunto de estados iniciales
  • F    conjunto de estados finales
por lo tanto para este AFD la quintupla sera:
  • ∑   {0,1}
  • Q    [{a},{a,b},{a,c,d},{a,b,c},{a,d,error},{a,b,d,error},{a,b,c,d},{a,error},{a,b,error},{a,c,d,error},{a,b,c,error},{a,b,c,d,error}]
  • δ    es la tabla de transiciones
  • q0 {a}
  • F     [{a,c,d},{a,d,error},{a,b,d,error},{a,b,c,d},{a,c,d,error},{a,b,c,d,error}]

Practica 2 TALF

Modelar la gramática en JFlap

Enunciado Practica 2

Acción
Abreviatura
S A
PAÑAL_SUCIO B
FRÍO C
CAMBIO_POSTURA D
GASES E
HAMBRE F
DOLOR G
BIENESTAR H
CONT_PS I
PATALEO_PS J
CONT_FRÍO K
CONT_CP L
BOCA_HAMBRE M
quejido a
para_quejido b
llanto_medio c
pataleo d
estiramiento_pierna e
ceño_fruncido f
encoger_cuerpo g
llanto_alto h
llanto_bajo i
giro_lento_cabeza j
ojos_abiertos k
boca_abierta l
chupeteo_pausado m
puños_apretados n
giro_rápido_cabeza o
cuerpo_relajado p
sonrisa q

Producciones

A→B|C|D|E|F|G|H
B→abI
I→abI|cJ
J→d|e|dJ|eJ
C→abK
K→abK|cfg
D→abL
L→abL|cd
E→hgf
F→ijkM
M→lM|mM|ε
G→hdnflo
H→pqm

Comprobar si las siguientes sentencias pertenecen al lenguaje generado y en caso afirmativo hallar su árbol de derivación, y averiguar qué le está pasando al bebé.

Quejido para_quejido quejido para_quejido llanto_medio pataleo pataleo
estiramiento_pierna pataleo
Se corresponde con: ababcdded  <– Acepta
Podría significar que el bebé tiene calor.

Llanto_bajo giro_lento_cabeza ojos_abiertos boca_abierta boca_abierta chupeteo_pausado chupeteo_ pausado boca_abierta
Se  corresponde con: ijkllmml <- Acepta
Podría significar que el bebé tiene sed.

Inventar una sentencia válida y otra inválida.

VALIDA
abcde
INVALIDA
acll

Construir una posible regla de producción para comunicar MIEDO

Miedo = N
N ->llanto_alto encoger_cuerpo ceño_fruncido quejido
N ->hgfa

Ejercicio 2 Teoria TALF

p1: Dados dos lenguajes y sobre el alfabeto . Anotamos con la unión, con la intersección, el complemento y con la diferencia.

Verifica o contradice:

    • Cierto: supongamos que  es un lenguaje que genera palabras de la forma  comprenderá todas las palabras sobre el alfabeto excepto las que cumplan la forma  si a  le sacamos el sublenguaje generado por  obtendremos el mismo resultado.
    • cierto:supongamos que es un lenguaje que genera palabras de la forma  y que  genera el lenguaje  por lo tanto generaran un lenguaje de la forma   por lo tanto  serán todas las combinaciones del lenguaje  excepto las que cumplan con el patrón .
      serán todas las palabras del lenguaje  excepto las que cumplan la forma .
      serán todas las palabras del lenguaje excepto las que cumplan la forma .
      por lo tanto la intersección de ambos lenguaje serán todas las palabras de   excepto las que cumplan el patrón .
    • cierto: La intersección de  y   serán las palabras comunes entre los dos sublenguajes y su complemento sera  para la segunda parte de la ecuación
    • Falso con  generaríamos palabras de la forma  y con  generaríamos palabras de la forma  .

p2: Construye un autómata finito determinista que “acepta” el lenguaje L que contiene todas las palabras (finitas) sobre el alfabeto {0, 1} con un número par de 0s y un número impar de 1s.

El modelo del autómata en JFlap lo podéis descargar en este enlace: autómata practica 2

Edit: Corregido el autómata que tenia mal un enlace, un 0 en lugar de un 1. Muchas gracias a Ymourino

Practica 1 Talf

Búsquedas basadas en Expresiones Regulares

El objetivo de la práctica es utilizar herramientas del sistema operativo como por
ejemplo Word en Windows para hacer búsquedas en archivos .doc; y greo o egrep
para buscar en archivos de texto plano.

Buscar en el “Himno Galego” o “Conxuro da Queimada” usando Word.

  • Palabras completas. Por ejemplo “de” “dos” “terra” o cualquiera que se te ocurra.
    • <na>
      <dos>
      <terra>
  • Palabras que comiencen por una letra o conjunto de ellas. Por ejemplo palabras que comiencen por “de”.
    • <de
  • Que además de comenzar por un conjunto de letras, estén al principio de una línea. Líneas que empiecen por “de”.
    • ^v<de
  • Palabras que terminen con una letra o conjunto de letras. Por ejemplo, palabras que terminen en “os” o “en”.
    • os>^l  
      en>^l
  • Que además de terminar en un conjunto de letras estén al final o al principio de una línea.
    • >as^| (no funciona)
  • Palabras que tienen dos vocales “a”.
    • [a-z,A-Z]@a[a-z,A-Z]@a

Buscar en el archivo de personas que contienes nombres de personas e información adicional sobre ellas (correo, ciudad, teléfono). Usando grep.

  • Personas que se llaman Carlos, mostrando la línea que ocupan en la lista.
    • cat personas.txt | grep -n “Carlos”
  • Personas cuyo nombre comience por las letras comprendidas entre M y S.
    • cat personas.txt | grep -n “[MS]”
  • Líneas del archivo de personas que contengan por lo menos diez letras mayúsculas consecutivas.
    • cat personas.txt | grep “[A-Z][A-Z][A-Z][A-Z][A-Z][A-Z][A-Z][A-Z][A-Z][A-Z]”
  • Líneas que tengan su dirección de correo electrónico en el servidor uvigo.
    • cat personas.txt | grep “@uvigo”
  • Personas cuyo nombre comience por la letra “E” o “M”.
    • cat personas.txt | grep “^[EM]”
  • Personas cuyo número de teléfono termine en 21.
    • cat personas.txt | grep “21$”
  • Personas cuyo prefijo de teléfono sea el 988
    • cat personas.txt | grep ” 988″
  • Otras búsquedas que se te ocurran.

Archivos conxuro himno personas