lunes, 27 de febrero de 2017

Tarea animación y logo propio



#include <windows.h>
#include <C:\GLUT\include\GL\glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.1415926535897932384626433832795

#define CANTREBOTE 0.005  // cantidad de rebote que tendrá

float radio=1, a1, a2, rotar = 0, inc = 0, sentido = 0.1;
float sentido2 = 0.1;
float nx, ny, r, g, b, dx, dy;
int logoGActivo = 1; // 1 significa que G aparece
float escala = 1.0;
float incEscala = 1.0;
float limitesEscala = 1.0;
float rebote = 0.0;
float limitesRebote = 0.0;

int puntos = 0, ancho = 600, alto = 600, tam_px = 1;
int tx=0,ty=0;

void rombos()
{
    // Figura de Rombos rojos
    glBegin( GL_QUADS ); // establece el modo de trazo
    glColor3f( 0.854901, 0.011764, 0.129411 ); // establece el color
    // se ubican los puntes de interes para dar la forma deseada
    // rombo superior
    glVertex2f( 1126 - 1069, 253 - (243+157)/2.0 );
    glVertex2f( 1069 - 1069, 352 - (243+157)/2.0 );
    glVertex2f( 1010 - 1069, 253 - (243+157)/2.0 );
    glVertex2f( 1069 - 1069, 157 - (243+157)/2.0 ); // punto y centro común de los rombos

    // rombo izquierdo
    glVertex2f( 1069 - 1069, 157 - (243+157)/2.0 ); // punto y centro común de los rombos
    glVertex2f( 958 - 1069, 157 - (243+157)/2.0 );
    glVertex2f( 903 - 1069, 59 - (243+157)/2.0 );
    glVertex2f( 1013 - 1069, 59 - (243+157)/2.0 );

    // rombo derecho
    glVertex2f( 1069 - 1069, 157 - (243+157)/2.0 ); // punto y centro común de los rombos
    glVertex2f( 1124 - 1069, 59 - (243+157)/2.0 );
    glVertex2f( 1237 - 1069, 59 - (243+157)/2.0 );
    glVertex2f( 1178 -1069, 157 - (243+157)/2.0 );
    glEnd();

    glFlush(); // libera memoria
}

/**
 * Traza circulos acorde a los parámetros recibidos
 * @param cx Coordenada x donde se ubicará el centro del circulo
 * @param cy Coordenada y donde se ubicará el centro del circulo
 * @param radio Medida que tendrá de radio el circulor
 * @param r Color rojo de un RGB de 0.0 a 1.0
 * @param g Color verde de un RGB de 0.0 a 1.0lor
 * @param b Color azul de un RGB de 0.0 a 1.0
 * @param a1 Inicio del trazo del circulo en radianes
 * @param a2 Fin del trazo del circulo en radianes
 */
void circulo( float cx, float cy, float radio, float r,
    float g, float b, float a1, float a2 )
{
    glEnable( GL_LINE_SMOOTH ); // suaviza el trazado de la línea
    glBegin( GL_POLYGON ); // une los puntos de un poligono y lo rellena
    glColor3f(r,g,b); // establece el color
    glVertex2f(cx,cy); // coordenadas del origenl del circulo
    // ciclo for para la posición y unión de los puntos del circulo
    for( float i = a1; i<= a2; i += 0.01 )
    {
        dx = radio*cos(i) + cx;
        dy = radio*sin(i) + cy;
        glVertex2f( dx, dy);
    }
    glEnd();
}

void logoPropio()
{
    glPointSize(5); // el valor es el tamaño del punto que tendrá en pixeles

    r = 46.0/255.0;
    g = 134.0/255.0;
    b = 193.0/255.0;

    glBegin( GL_POLYGON ); // establece el modo de trazo
    glColor3f( r, g, b ); // establece el color
    // se ubican los puntes de interes para dar la forma deseada

    // Palito de la f
    glVertex2i( 0, -5 ); // punto y centro común de los rombos
    glVertex2i( 35, -5 );
    glVertex2i( 35, 5 );
    glVertex2i( 0, 5 );
    glEnd();

    glBegin( GL_POLYGON ); // establece el modo de trazo
    glColor3f( r, g, b ); // establece el color
    // se ubican los puntes de interes para dar la forma deseada

    // Palito de la f y la g
    glVertex2i( -5, 38 ); // punto y centro común de los rombos
    glVertex2i( -5, -50 );
    glVertex2i( 5, -50 );
    glVertex2i( 5, 38 );
    glEnd();


    // circulo de la g
    circulo( -25.0, 0.0, 30, r, g, b, 0.0, 2*PI ); // contorno negro de la primer figura
    circulo( -25.0, 0.0, 20, 0.0, 0.0, 0.0, 0.0, 2*PI ); // contorno negro de la primer figura

    // semicirculo de la g
    circulo( -25.0, -50.0, 30, r, g, b, PI, 2*PI ); // contorno negro de la primer figura
    circulo( -25.0, -50.0, 20, 0.0, 0.0, 0.0, PI, 2*PI ); // contorno negro de la primer figura


    glBegin( GL_POLYGON ); // establece el modo de trazo
    glColor3f( r, g, b ); // establece el color
    // se ubican los puntes de interes para dar la forma deseada

    // semicirculo de la F
    circulo( 25.0, 38.0, 30, r, g, b, 0, PI ); // contorno negro de la primer figura
    circulo( 25.0, 38.0, 20, 0.0, 0.0, 0.0, 0, PI ); // contorno negro de la primer figura

    glFlush(); // libera memoria
}

void dibujarG()
{
    int cx=0;int cy=0;
    circulo(cx,cy,5,0.858,0.196,0.211,0.7854,2.7);
    circulo(cx,cy,5,0.956,0.76,0.05,2.65,3.65);
    circulo(cx,cy,5,0.235,0.73,0.33,3.65,5.49);
    circulo(cx,cy,5,0.282,0.52,0.93,5.48,2*3.22);
    circulo(cx,cy,3,0,0,0,0,2*3.1416);
    glColor3f(0.282,0.52,0.93);
    glBegin(GL_TRIANGLE_FAN);
    glVertex2f(0+cx,0.8+cy);glVertex2f(4.98+cx,0.8+cy);
    glVertex2f(4.93+cx,-1+cy);glVertex2f(0+cx,-1+cy);
    glEnd();
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);

    glTranslatef( 0, rebote, 0 );
    glScalef( escala, escala, 1.0 );
    glRotatef(rotar, 0, 0, 1);
    if( logoGActivo == 1 )
    {

        dibujarG();
        glFlush();
    } else if( logoGActivo == 0 )
    {
        glPushMatrix();
            glTranslatef( 0, 0.9, 0);
            glScalef( 0.02, 0.02, 1 );
            rombos();
        glPopMatrix();
    } else if( logoGActivo == 2 )
    {
        glPushMatrix();
            glScalef( 0.1, 0.1, 1 );
            logoPropio();
        glPopMatrix();
    }


}

void key(unsigned char c, int x, int y)
{
    if (c == 27) {
        exit(0);
    }
}

void ajustar(int ancho, int alto)
{

    float aspectratio;
    aspectratio = 1;
    if (1>(ancho/alto))
    {
    // glViewport recibe 4 parametros, uno el origen en x, y y otro el ancho y otro el alto
        glViewport(0, 0, ancho,  ancho/aspectratio);
    }
    else
    {
        glViewport(0, 0, alto*aspectratio,alto);
    }

}

void seleccion(int valor) {
    switch(valor) {
        case 1:
            inc = 1;
            break;
        case 2:
            inc = 0;
            break;
        case 3: // casos 3 y 4 sentidos de la rotacion
            sentido = sentido2;
            break;
        case 4:
            sentido = -1*sentido2;
            break;
        case 5:
            logoGActivo = 1; // cambio a logo G
            break;
        case 6:
            logoGActivo = 0; // cambio al otro logo
            break;
        case 7:
            logoGActivo = 2; // cambio al logo propio
            break;
        case 8:
            incEscala = 0.999;
            break;
        case 9:
            incEscala = 1.001;
            break;
        case 10:
            incEscala = 1.0;
            break;
        case 11:
            rebote = CANTREBOTE;
            break;
        case 12:
            rebote = 0;
            break;
        default:
            break;
    }
}


void animar(void) {
    rotar = inc*sentido;

    // 0.1 y 3 son los limites de reduccion y de apliacion a partir de los cuales deja de escalar
    if( limitesEscala > 0.1 && limitesEscala < 3 )
    {
        escala = incEscala;
        if( incEscala > 1 )
            limitesEscala = limitesEscala*incEscala;
        else if( incEscala < 1 )
            limitesEscala = limitesEscala*incEscala;
    } else
    {
        escala = 1.0;
        if( incEscala != 1 )
            limitesEscala = limitesEscala*incEscala;
    }
    if( limitesEscala < 0.1 || limitesEscala > 3 )
        incEscala = 1.0;

    // MANEJO DEL REBOTE
    if( rebote > 0 )
    {
        limitesRebote = limitesRebote + CANTREBOTE;
    } else if( rebote < 0 )
    {
        limitesRebote = limitesRebote - CANTREBOTE;
    }
    if( limitesRebote > 2 && rebote != 0 )
    {
        rebote = -1*CANTREBOTE;
    }
    if( limitesRebote < -2 && rebote != 0 )
    {
        rebote = CANTREBOTE;
    }


    glutPostRedisplay();
}


void Init()
{   glClearColor(0,0,0,0);
    gluOrtho2D(-10, 10, -10, 10);
    glPointSize(tam_px);
    glEnable(GL_POINT_SMOOTH);

}

void menu(){
    int movimiento;
    movimiento = glutCreateMenu(seleccion); // como servira para un submenu se asigna a una variable
    glutAddMenuEntry("Izquierda", 3);
    glutAddMenuEntry("Derecha", 4);
    // cada menu tiene una jerarquia

    int logo; // guardara la selccion del logo elegido
    logo = glutCreateMenu(seleccion);
    glutAddMenuEntry("Logo G", 5);
    glutAddMenuEntry("Logo Rombos", 6);
    glutAddMenuEntry("Logo Propio", 7);

    int subMEsc; // guardara la selccion escalamiento
    subMEsc = glutCreateMenu(seleccion);
    glutAddMenuEntry("Reducir", 8);
    glutAddMenuEntry("Ampliar", 9);
    glutAddMenuEntry("Deshabilitar", 10);

    int subMReb; // guardara la selccion escalamiento
    subMReb = glutCreateMenu(seleccion);
    glutAddMenuEntry("Habilitar", 11);
    glutAddMenuEntry("Deshabilitar", 12);

    //menú con el click derecho
    glutCreateMenu(seleccion);
    glutAddMenuEntry("Iniciar", 1);
    glutAddMenuEntry("Detener", 2);
    glutAddSubMenu("Sentido", movimiento); // para agregar un submenu.... movimiento se crea antes para que se conozca
    glutAddSubMenu("Logo", logo);
    glutAddSubMenu("Escalamiento", subMEsc);
    glutAddSubMenu("Rebote", subMReb);
    glutAttachMenu(GLUT_RIGHT_BUTTON); // con clic derecho se accede al menú
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE );
    glutInitWindowSize(500, 500);
    glutCreateWindow("Menu,animación y relación de aspecto");


    Init();
    menu();

    glutDisplayFunc(display);

    glutIdleFunc(animar);  // Idle significa en espera
    glutReshapeFunc(ajustar);
    glutKeyboardFunc(key);
    glutMainLoop();
    return 0;
}

martes, 21 de febrero de 2017

Práctica 2

Ejercicio 1:

#include <windows.h>
#include <C:\GLUT\include\GL\glut.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>



float r=1,g=0,b=0;
float dx,dy;
int lado=20,linea=7,inc=1,i;
int ban=1;
int b2 = 0;

void cuadro(float r, float g, float b)
{
    glColor3f(r,g,b);
    glEnable( GL_LINE_SMOOTH );
    glBegin( GL_POLYGON);
    glVertex2f(6,3);glVertex2f(3, 3);
    glVertex2f(3,6);glVertex2f(6,6);
    glEnd();
}

void cuadrof(float r, float g, float b)
{
    glColor3f(r,g,b);
    glEnable( GL_LINE_SMOOTH );
    glBegin(GL_LINE_LOOP);
    glVertex2f(6,3);glVertex2f(3,3);
    glVertex2f(3,6);glVertex2f(6,6);
    glEnd();
}


void display(void)
{
   // ban=1;
    glClear( GL_COLOR_BUFFER_BIT );
    glEnable( GL_LINE_SMOOTH );
    if(ban==1){
        cuadro(r,g,b);

    }else
    {
        cuadrof(r,g,b);
    }


    glFlush();

}

void key(unsigned char c, int x, int y)
{
    if (c == 27) {
        exit(0);
    }if(c == 'a')
    {
        r=0;
        g=0;
        b=1;
    } else if(c == 'v')
    {
        r=0;
        g=1;
        b=0;
    }else if(c == 'r')
    {
        r=1;
        g=0;
        b=0;
    }else if(c='w'){
        if( ban == 1 )
            ban=0;
            else
                ban = 1;
    }
    glutPostRedisplay();
    //glFlush();

}




int main(int argc, char** argv){
    glutInit(&argc, argv); // Inicializa la libreria GLUT
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB );
    glutInitWindowSize(550,550); // Inicializa el tamaño de la ventana
    glutInitWindowPosition(100,50); // posicion de la ventana
    glutCreateWindow("CuadroFrame"); // crea la ventana

    glClearColor( 1, 1, 1, 0);
    gluOrtho2D( 0, 9, 9, 0 );
    glutDisplayFunc(display);
    glutKeyboardFunc(key);
    glutMainLoop();
    return EXIT_SUCCESS;
}



Ejercicio 2:


#include <windows.h>
#include <C:\GLUT\include\GL\glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define PI 3.1415926535897932384626433832795


float r, g, b, y;
int ancho = 600, alto = 300, linea = 6, inc = 1;

void funcionseno(float r,float g, float b)
{
    glLineWidth(linea);
    glBegin( GL_LINE_STRIP );
    glColor3f(r,g,b);
    //glVertex2f(0,0);
    for( float i = -3.005*PI; i<= 3.005*PI; i = i + PI/20 )
    {
        y = 2*sin(i);
        //x = i;
        glVertex2f( i,y);
    }
    glEnd();
}

void funcioncoseno(float r,float g, float b)
{
    glLineWidth(linea/3);
    glBegin( GL_LINE_STRIP );
    glColor3f(r,g,b);
    for( float i = -3.005*PI; i<= 3.005*PI; i = i + PI/20 )
    {
        y = 2*cos(i);
        //x = i;
        glVertex2f( i,y);
    }
    glEnd();
}




void referencia(float r, float g, float b)
{
    glLineWidth(linea/4); //ANCHO DE LINEA
    glColor3f(r, g, b);
    glBegin(GL_LINES);
    glVertex2f(-1000,0);glVertex2f(1000,0);// EN X
    glVertex2f(0,-1000);glVertex2f(0,1000);//EN Y
    glEnd();
    //glLineWidth(linea);
}


void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    referencia(0,0,0);
    glPushMatrix();
        glScalef( 30.0, 30.0, 1.0 );
        funcionseno(1,0,0);
        funcioncoseno(0,1,0);
    glPopMatrix();

    glFlush();
}

void Init()
{   glClearColor(1.0,1.0,1.0,0);
    gluOrtho2D( -ancho/2, ancho/2, -alto/2, alto/2 );
}

int main(int argc, char **argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(100,100);
    glutInitWindowSize( ancho, alto);
    glutCreateWindow("Graficas");

    Init();

    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}



Ejercicio 3:

Versión 1:


#include <windows.h>
#include <C:\GLUT\include\GL\glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

float r = 0.5, g = 0.5, b = 0.5;
int ancho = 600, alto=600;
int tam_px = 10;
int matrizPuntos[1000][2];
int i = 0;
int clics = 0;


void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glPointSize(tam_px);
    glColor3f(r,g,b);
    glBegin( GL_LINE_STRIP );

    if( clics >= 2 )
    {
        int j;
        for( j = 0; j < clics; j++ )
        {
            glVertex2f( matrizPuntos[j][0], matrizPuntos[j][1] );
        }
    }

    glEnd();
    glFlush();

}
void mouse(int boton, int estado, int x, int y)
{
    if ( boton == GLUT_LEFT_BUTTON && estado == GLUT_DOWN ) // BOTON IZQ y el estado es presionado
    {
        clics++;
        matrizPuntos[i][0] = x;
        matrizPuntos[i][1] = y;
        i++;
    }
    glutPostRedisplay();
}


void miInicializacion()
{   glClearColor( 1.0, 1.0, 1.0,0);
    gluOrtho2D( 0, ancho, alto, 0 );
    glEnable(GL_POINT_SMOOTH);
}

int main(int argc, char **argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(ancho,alto);
    glutCreateWindow("Dibujo a mano alzada");

    miInicializacion();

    glClear(GL_COLOR_BUFFER_BIT);
    glutDisplayFunc(display);
    glutMouseFunc(mouse);

    glutMainLoop();
    return 0;
}



Versión 2:


#include <windows.h>
#include <C:\GLUT\include\GL\glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

float r = 0.5, g = 0.5, b = 0.5;
int ancho = 600, alto=600;
int tam_px = 10;
int matrizPuntos[60000][2];
int i = 0;
int clics = 0;


void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glPointSize(tam_px);
    glColor3f(r,g,b);
    glBegin( GL_LINE_STRIP );

    if( i >= 2 )
    {
        int j;
        for( j = 0; j < i; j++ )
        {
            glVertex2f( matrizPuntos[j][0], matrizPuntos[j][1] );
        }
    }

    glEnd();
    glFlush();

}
void mouse( int x, int y)
{
    matrizPuntos[i][0] = x;
    matrizPuntos[i][1] = y;
    i++;
    //printf( "x: %d,   y: %d, iii:%d       ", x, y, i );
    glutPostRedisplay();
}


void miInicializacion()
{   glClearColor( 1.0, 1.0, 1.0,0);
    gluOrtho2D( 0, ancho, alto, 0 );
    glEnable(GL_POINT_SMOOTH);
}

int main(int argc, char **argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(ancho,alto);
    glutCreateWindow("Dibujo a mano alzada");

    miInicializacion();

    glClear(GL_COLOR_BUFFER_BIT);
    glutDisplayFunc(display);
    glutPassiveMotionFunc(mouse);

    glutMainLoop();
    return 0;
}

lunes, 20 de febrero de 2017

Tarea 4 Ajedrez con G - Edgar


#include <windows.h>
#include <C:\GLUT\include\GL\glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define PI 3.1415926535897932384626433832795

/** Descripcion: Tablero de Ajedrez sobre fondo azul, donde se mueve por las casillas
 *  la letra G de Google.
 *
 * Autores:
 *  Edgar Villa Miguel.
 * Fecha de creacion: 18/02/17
 * Revisiones: ---
 *  programa.
 * Fecha de ultima actualizacion: 20/02/17
 */

int ancho = 734, alto = 734; // alto y ancho para la ventana
int tableroBlanco = 296; // tamaño del tablero blanco
int cuadroNegro = 37; // tamaño de un cuadrito negro del tablero
int xG = ancho/2 - cuadroNegro; // coordenada x para mover G
int yG = alto/2 + cuadroNegro; // coordenada y para mover G
int bnG = 1; // variable para cambiar fonode de G, 1 significa blanco, 0 negro
int confirmaCambia = 1; // bandera que ayuda a cambiar de manera correcta los colores para G
float dx,dy;

/**
 * Traza circulos acorde a los parámetros recibidos
 * @param cx Coordenada x donde se ubicará el centro del circulo
 * @param cy Coordenada y donde se ubicará el centro del circulo
 * @param radio Medida que tendrá de radio el circulor
 * @param r Color rojo de un RGB de 0.0 a 1.0
 * @param g Color verde de un RGB de 0.0 a 1.0lor
 * @param b Color azul de un RGB de 0.0 a 1.0
 * @param a1 Inicio del trazo del circulo en radianes
 * @param a2 Fin del trazo del circulo en radianes
 */
void circulo( float cx, float cy, float radio, float r,
    float g, float b, float a1, float a2 )
{
    // glEnable( GL_LINE_SMOOTH );
    glBegin( GL_POLYGON );
    glColor3f(r,g,b);
    glVertex2f(cx,cy);
    for( float i = a1; i<= a2; i+=0.01 )
    {
        dx = radio*cos(i) + cx;
        dy= radio*sin(i) + cy;
        glVertex2f(dx,dy);
    }
    glEnd();
}

void cuadro( float lado, float r, float g, float b)
{
    glColor3f(r,g,b);
    glBegin(GL_POLYGON );
    glVertex2f(lado, lado);
    glVertex2f(-lado, lado);
    glVertex2f(-lado, -lado);
    glVertex2f(lado, -lado);
    glEnd();

}

void logoG( int bn ) // b(blanco) = 1, n(negro) = 0
{
    glPointSize(10); // el valor es el tamaño del punto que tendrá en pixeles
    glColor3f(0, 0, 1.0); // RGB B = 1, Blue

    circulo( 0.0, 0.0, 40, 0.917647, 0.262745, 0.207843, 0.872664626, 2.617993878 ); // Rojo
    circulo( 0.0, 0.0, 40, 0.984313, 0.737254, 0.019607, 2.60, 3.665191429 ); // Amarillo
    circulo( 0.0, 0.0, 40, 0.203921, 0.658823, 0.325490, 3.66, 5.410520681 ); // Verde
    circulo( 0.0, 0.0, 40, 0.258823, 0.521568, 0.956862, 5.4, 6.5 ); // Azul
    if( bn == 1 )
        circulo( 0.0, 0.0, 23, 1.0, 1.0, 1.0, 0, 2*PI ); // Blanco
    else
        circulo( 0.0, 0.0, 23, 0.0, 0.0, 0.0, 0, 2*PI ); // Blanco

    glBegin( GL_POLYGON ); // Rectangulo azul
    glColor3f( 0.258823, 0.521568, 0.956862 ); // Azul
    glVertex2i(0,8);
    glVertex2i(0,-7);
    glVertex2i(39,-7);
    glVertex2i(39,8);

    glEnd();
}

void cuadritoNegro( int x, int y)
{
    // sino se pone push y pop Matriz solo se pintaría un cuadro que se esta movimiento n...
    // ... veces que se llame esta función
    glPushMatrix();
        glTranslatef( x, y, 0);//traslada
        cuadro( cuadroNegro, 0.0, 0.0, 0.0 ); // cuadros pequeños de color negro para el tablero
    glPopMatrix();
}

void key(unsigned char c, int x, int y)
{
    int siAvanzo = 0; // verifica si se puede avanzar la G para entonces cambiar de color a G

    if ( c == 27 )
        exit(0);

    // mueve G una posición a la izquierda al presionar 'a' o 'A'
    if ( (c == 'a' || c == 'A') && xG > 181 )
    {
        xG = xG - 74;
        siAvanzo = 1;
    }
    // mueva G una posición a la derecha al presionar 'd' o 'D'
    if ( (c =='d' || c == 'D') && xG < 625 )
    {
        xG = xG + 74;
        siAvanzo = 1;
    }

    // mueve G una posición hacia abajo al presionar 's' o'S'
    if ( (c =='s' || c == 'S') && yG > 109 )
    {
        yG = yG - 74;
        siAvanzo = 1;
    }
    // mueve G una posición hacia arriba al presionar 'w' o 'W'
    if ( (c =='w' || c == 'W') && yG < 624 )
    {
        yG = yG + 74;
        siAvanzo = 1;
    }

    if( siAvanzo == 1 ) // si G avanza entonces cambia de color, su fondo
    {
        if( confirmaCambia == 0 )
        {
            bnG = 0; // negro

            // si bnG es negro, se permite cambiar a blanco en el sig movimiento de G
            confirmaCambia = 1;
        }
        else
            bnG = 1; // blanco
    }

    glutPostRedisplay();
}

void display(void){
    int i, j; // contador de for

    if( bnG == 1 ) // si bnG es blanco, se permite cambiar a negro en el sig movimiento de G
        confirmaCambia = 0;

    glClear( GL_COLOR_BUFFER_BIT ); // limpia, libera el buffer

    // Tablero parte blanca
    /*************************************************************/
    glPushMatrix();
        glTranslatef( ancho/2-1, alto/2+1, 0);//traslada
        cuadro( 296, 1.0, 1.0, 1.0 ); // color blanco del tablero
    glPopMatrix();
    /*************************************************************/


    int x, y; // coordenadas donde se traladarán los cuadritos negros
    // Tablero
    /*************************************************************/
    x = 70 + cuadroNegro + 2*cuadroNegro; // cuadroNegro es la mitad de un lado del cuadrito
    y = alto - (70 + cuadroNegro);

        for ( i = 0; i < 8; ++i ) // recorre las filas o renglones
        {
            for( j = 0; j < 4; j++ ) // recorre las columnas de las filas
            {
                cuadritoNegro( x, y); // dibuja cada cuadrito negro
                x = x + 2*(2*cuadroNegro); // 2 por un lado completo de un cuadrito
            }

            y = y - 2*cuadroNegro; // cuadroNegro es la mitad de un lado del cuadrito
            if( i%2 != 0 )
                x = 70 + cuadroNegro + 2*cuadroNegro; // cuadroNegro es la mitad de un lado del cuadrito
            else
                x = 70 + cuadroNegro; // cuadroNegro es la mitad de un lado del cuadrito
        }
    /*************************************************************/



    // movimientos de G a través del tablero
    /** ------------------------------------------------------- **/
    glPushMatrix();
        glTranslatef( xG, yG, 0);//traslada
        glScalef( 0.76, 0.76, 1.0 ); // para escalar reduciendo el logo de la G
        logoG(bnG); // trae el logo de la letra G de Google
    glPopMatrix();
    /** ------------------------------------------------------- **/

    glFlush(); // libera memoria
}

int main(int argc, char** argv){
    glutInit(&argc, argv); // Inicializa la libreria GLUT
    // glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB );
    glutInitWindowSize( ancho, alto ); // Inicializa el tamaño de la ventana
    glutInitWindowPosition(10,50); // posicion de la ventana
    glutCreateWindow("Tablero de Ajedrez con G"); // crea la ventana

    glClearColor( 2.0/255.0, 75.0/255.0, 123.0/255.0, 0); // establece el color de fondo de la ventana
    gluOrtho2D( 0, ancho, 0, alto );

    // glutDisplayFunc(display); Aqui le indicamos a GLUT que la rutina
    // utilizada como Display sera la llama display. Este tipo de rutinas se
    // ejecuta una vez por ciclo de programa, y será la que realice
    // todas las operaciones gráficas (render).

    //  glutDisplayFunc(display);

    // ciclo de la aplicación
    glutDisplayFunc(display);
    glutKeyboardFunc(key);
    glutMainLoop();
    return 0;

    return 0;
}

Práctica 1 Sol y Nube - Equipo




#include <windows.h>
#include <C:\GLUT\include\GL\glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define PI 3.1415926535897932384626433832795

/** Descripcion: Sol formado por dos cuadros y un circulo que gira
 * y una nube formada por cuatro círculos que se desplaza, esto al
 * presionar las teclas 'a' o 'z'
 *
 * Autores:
 *  Edgar Villa
 *  Karina Miranda
 *  Abigail Romero
 *  Isabel Gaona
 * Fecha de creacion: 16/02/17
 * Revisiones: ---
 * Fecha de ultima actualizacion: 18/02/17
 */

float r,g,b,dx,dy;
int ancho = 500, alto = 500; // alto y ancho para la ventana
int inc = 1; // variable usada para trasladar la nube al presionar las teclas 'a' y 'z'
int giro = 0; // variable usada para rotar el sol al presionar las teclas 'a' y 'z'

/* dibua un cuadrao
*/
void cuadro( float lado, float r, float g, float b)
{
    glColor3f(r,g,b);
    glBegin(GL_POLYGON );
    glVertex2f(lado, lado);
    glVertex2f(-lado, lado);

    glColor3f(r-0.1,g-0.3,b);
    glVertex2f(-lado, -lado);
    glVertex2f(lado, -lado);
    glEnd();

}

/**
 * Traza circulos acorde a los parámetros recibidos
 * @param cx Coordenada x donde se ubicará el centro del circulo
 * @param cy Coordenada y donde se ubicará el centro del circulo
 * @param radio Medida que tendrá de radio el circulor
 * @param r Color rojo de un RGB de 0.0 a 1.0
 * @param g Color verde de un RGB de 0.0 a 1.0lor
 * @param b Color azul de un RGB de 0.0 a 1.0
 * @param a1 Inicio del trazo del circulo en radianes
 * @param a2 Fin del trazo del circulo en radianes
 */
void circulo( float cx, float cy, float radio, float r,
    float g, float b, float a1, float a2 )
{
    glEnable( GL_LINE_SMOOTH );
    glBegin( GL_POLYGON );
    glColor3f(r,g,b);
    glVertex2f(cx,cy);
    for( float i = a1; i<= a2; i+=0.01 )
    {
        dx = radio*cos(i) + cx;
        dy= radio*sin(i) + cy;
        glVertex2f(dx,dy);
    }
    glEnd();
}


void key(unsigned char c, int x, int y)
{
    if (c==27)
        {
            exit(0);
        }
    if (c=='a')
    {
        inc= inc + 5;
        giro = giro + 5;
    }
    if (c=='z')
    {
        inc= inc - 5;
        giro = giro - 5;
    }

    // if para que la nube vuelva a aparecer del otro lado al llegar a un borde
    if( inc < -394 )
        inc = 286; // al llegar al borde izquierdo y desaparecer se va al borde derecho

    if( inc > 286 )
        inc = -394; // al llegar al borde derecho y desaparecer se va al borde izquierdo
    glutPostRedisplay();
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);

    glPushMatrix();
        glRotatef(90 ,0,0,1);
        glTranslatef(0,100,0);//traslada
        glRotatef(giro ,0,0,1);
        glPushMatrix();
            cuadro(100,1,0.85,0);
    //cuadro(100,1,0.8,0);
            glRotatef(45,0,0,1);
            cuadro(100,1,0.9,0);
    // cuadro(100,1,0.7,0);
            circulo( 0,0, 100,1,0.9,0,0,2*PI+0.1);
            glPopMatrix();
    glPopMatrix();


    glPushMatrix(); //empieza de adentro hacia afuera
        glTranslatef(inc,0,0);
        glPushMatrix();
        glTranslatef(100,-60,0);
        circulo( 0, 0, 45, 1, 1, 1, 0, PI);
        glTranslatef(-30,30,0);
        circulo( 0, 0, 40,1,1,1, 0, PI+0.8);
        glTranslatef(-30,20,0);
        circulo( 0, 0, 40, 1, 1, 1, 0, PI+0.5);
        glTranslatef(-20,-50,0);
        circulo( 0, 0, 50,1,1,1, 0, PI);
    glPopMatrix();
    glPopMatrix();
    glFlush();
}

void Init()
{   glClearColor( 65.0/255.0, 161.0/255.0, 245.0/255.0,0);
    gluOrtho2D(-ancho/2,ancho/2,-alto/2,alto/2);
}

int main(int argc, char **argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(ancho,alto);
    glutCreateWindow("Sol con nube");

    Init();

    glutDisplayFunc(display);
    glutKeyboardFunc(key);
    glutMainLoop();
    return 0;
}

Tarea 3 Logos - Edgar


Tarea 3
#include <windows.h>
#include <C:\GLUT\include\GL\glut.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.1415926535897932384626433832795

/** Descripcion: Mediante el uso de OpenGL y GLUT.h se generan tres logos
 * Yin y Yang
 * Domino's Pizza
 * Rombos Rojos
 *
 * Autores:
 *  Edgar Villa Miguel.
 * Fecha de creacion: 11/02/17
 * Revisiones: ---
 * Fecha de ultima actualizacion: 11/02/17
 */

float dx,dy;

/**
 * Traza circulos acorde a los parámetros recibidos
 * @param cx Coordenada x donde se ubicará el centro del circulo
 * @param cy Coordenada y donde se ubicará el centro del circulo
 * @param radio Medida que tendrá de radio el circulor
 * @param r Color rojo de un RGB de 0.0 a 1.0
 * @param g Color verde de un RGB de 0.0 a 1.0lor
 * @param b Color azul de un RGB de 0.0 a 1.0
 * @param a1 Inicio del trazo del circulo en radianes
 * @param a2 Fin del trazo del circulo en radianes
 */
void circulo( float cx, float cy, float radio, float r,
    float g, float b, float a1, float a2 )
{
    glEnable( GL_LINE_SMOOTH ); // suaviza el trazado de la línea
    glBegin( GL_POLYGON ); // une los puntos de un poligono y lo rellena
    glColor3f(r,g,b); // establece el color
    glVertex2f(cx,cy); // coordenadas del origenl del circulo
    // ciclo for para la posición y unión de los puntos del circulo
    for( float i = a1; i<= a2; i += 0.01 )
    {
        dx = radio*cos(i) + cx;
        dy = radio*sin(i) + cy;
        glVertex2f( dx, dy);
    }
    glEnd();
}

void display(void){
    glClear( GL_COLOR_BUFFER_BIT ); // limpia, libera el buffer

    glPointSize(5); // el valor es el tamaño del punto que tendrá en pixeles

    // Logo de Yin y Yang
    circulo( 185.0, 210.0, 155, 0.0, 0.0, 0.0, 0.0, 2*PI ); // contorno negro de la primer figura
    circulo( 185.0, 210.0, 152, 1.0, 1.0, 1.0, PI/2.0, 3*PI/2.0 ); // medio circulo blanco izquierdo

    circulo( 185.0, 285.0, 76, 1.0, 1.0, 1.0, 0, 2*PI ); // circulo mediano blanco
    circulo( 185.0, 133.0, 76, 0.0, 0.0, 0.0, 0, 2*PI ); // circulo mediano negro

    circulo( 185.0, 285.0, 19, 0.0, 0.0, 0.0, 0, 2*PI ); // circulo pequeño negro
    circulo( 185.0, 133.0, 19, 1.0, 1.0, 1.0, 0, 2*PI ); // circulo pequeño blanco

    // Logo de Domino's Pizza
    // primera sección azul
    glBegin( GL_POLYGON ); // establece el modo de trazo
    glColor3f( 0.0, 0.482352, 0.678431 ); // establece el color
    // se ubican los puntes de interes para dar la forma deseada
    glVertex2i( 583.0, 241.0 );
    glVertex2i( 490.0, 148.0 );
    glVertex2i( 490.0, 140.0 );
    glVertex2i( 578.0, 51.0 );
    glVertex2i( 588.0, 51.0 );
    glVertex2i( 681.0, 144.0 );
    glEnd();

    // circulos pequeños en las esquinas de la izquierda
    circulo( 492.0, 144.0, 4.0, 0.0, 0.482352, 0.678431, PI/2.0, 3*PI/2.0 );
    circulo( 583.0, 52.0, 4.0, 0.0, 0.482352, 0.678431, PI, 2*PI );

    // circulos blanco sobre el cuadro azul
    circulo( 547.0, 144.0, 24.0, 1.0, 1.0, 1.0, 0, 2*PI );
    circulo( 619.0, 144.0, 24.0, 1.0, 1.0, 1.0, 0, 2*PI );

    // segunda sección roja
    glBegin( GL_POLYGON ); // establece el modo de trazo
    glColor3f( 0.882352, 0.090196, 0.207843 ); // establece el color
    // se ubican los puntes de interes para dar la forma deseada
    glVertex2i( 590, 247 );
    glVertex2i( 687, 149 );
    glVertex2i( 780, 243 );
    glVertex2i( 780, 251 );
    glVertex2i( 692, 340 );
    glVertex2i( 682, 340 );
    glEnd();

    // circulos pequeños en las esquinas de la derecha
    circulo( 778.0, 247.0, 4.0, 0.882352, 0.090196, 0.207843, 3*PI/2.0, 5*PI/2.0 );
    circulo( 687.0, 337.0, 5.0, 0.882352, 0.090196, 0.207843, 0.0, PI );

    // circulos blanco sobre el cuadro azul
    circulo( 687.0, 247.0, 24.0, 1.0, 1.0, 1.0, 0, 2*PI );


    // Figura de Rombos rojos
    glBegin( GL_POLYGON ); // establece el modo de trazo
    glColor3f( 0.854901, 0.011764, 0.129411 ); // establece el color
    // se ubican los puntes de interes para dar la forma deseada
    // rombo superior
    glVertex2i( 1126, 253 );
    glVertex2i( 1069, 352 );
    glVertex2i( 1010, 253 );
    glVertex2i( 1069, 157 ); // punto y centro común de los rombos
    glEnd();

    glBegin( GL_POLYGON ); // establece el modo de trazo
    glColor3f( 0.854901, 0.011764, 0.129411 ); // establece el color
    // se ubican los puntes de interes para dar la forma deseada

    // rombo izquierdo
    glVertex2i( 1069, 157 ); // punto y centro común de los rombos
    glVertex2i( 958, 157 );
    glVertex2i( 903, 59 );
    glVertex2i( 1013, 59 );
    glEnd();

    glBegin( GL_POLYGON ); // establece el modo de trazo
    glColor3f( 0.854901, 0.011764, 0.129411 ); // establece el color
    // se ubican los puntes de interes para dar la forma deseada

    // rombo derecho
    glVertex2i( 1069, 157 ); // punto y centro común de los rombos
    glVertex2i( 1124, 59 );
    glVertex2i( 1237, 59 );
    glVertex2i( 1178, 157 );
    glEnd();


    glFlush(); // libera memoria
}

int main(int argc, char** argv){
    glutInit(&argc, argv); // Inicializa la libreria GLUT
    // glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB );
    glutInitWindowSize( 1280, 400 ); // Inicializa el tamaño de la ventana
    glutInitWindowPosition( 10,50); // posicion de la ventana
    glutCreateWindow("Tarea 3 - 3 Logos"); // crea la ventana

    glClearColor( 1.0, 1.0, 1.0, 0);
    gluOrtho2D( 0, 1280, 0, 400 );

    // glutDisplayFunc(display); Aqui le indicamos a GLUT que la rutina
    // utilizada como Display sera la llama display. Este tipo de rutinas se
    // ejecuta una vez por ciclo de programa, y será la que realice
    // todas las operaciones gráficas (render).

    //  glutDisplayFunc(display);

    // ciclo de la aplicación
    glutDisplayFunc(display);
    glutMainLoop();

    return 0;
}

domingo, 19 de febrero de 2017

Algoritmo de Bresenham y Algortimo de DDA

Algoritmo de Bresenham

El algoritmo de Bresenham, desarrollado por Bresenham (1965), es un algoritmo creado para dibujar rectas en los dispositivos de gráficos rasterizados, como por ejemplo un monitor de computadora, que determina qué pixeles se rellenarán, en función de la inclinación del ángulo de la recta a dibujar.

El algoritmo busca cual de dos pixeles es el que está más cerca según la trayectoria de la línea.

Es un algoritmo preciso para la generación de lineas de ratreo que convierte mediante rastreo las líneas al utilizar solo cálculos incrementales con enteros que se pueden adaptar para desplegar circunferencias y curvas. Los ejes verticales muestran las posiciones de rastreo y los ejes horizontales identifican columnas de pixel.


Algoritmo:

Consideremos el proceso de conversión para líneas con pendiente positiva 0 < m < 1.

Las posiciones de pixel a lo largo de la trayectoria de una línea se determinan al efectuar un muestreo de x en intervalos unitarios.

Si se inicia desde el extremo izquierdo (x0,y0) de una línea determinada, se pasa a cada columna sucesiva y se traza el pixel cuyo valor de y se aproxima más a la trayectoria de la línea de rastreo.

Si suponemos que se debe desplegar el pixel en (xk, yk), a continuación se necesita decidir que pixel se debe desplegar en la columna xk+1.

Las alternativas son los pixeles (xk+1,yk), y (xk+1,yk+1).

Al realizar el muestreo en la posición xk+1 designamos la separación de pixeles verticales de la trayectoria de la línea matemática como d1 y d2.


Codificación a color del Algoritmo de Bresenham:



Codificación en texto plano del Algoritmo de Bresenham:

void LineasBresenham( float red, float green, float blue, int x0, int y0, int x1, int y1 )
{
 int x, y, dx, dy, xEnd, p, incE, incNE;
 dx = abs(x1 - x0);
 dy = abs(y1 - y0);
 p = 2*dy - dx;
 incE = 2*dy;
 incNE = 2*(dy-dx);

 /* determinar que punto usar para empezar, cual para terminar */
 if (x0 > x1) {
  x = x1;
  y = y1;
  xEnd = x0;
 }
 else {
  x = x0;
  y = y0;
  xEnd = x1;
 }

 /* se cicla hasta llegar al extremo de la línea */
 while ( x <= xEnd )
 {
  glBegin( GL_POINTS );
  glColor3f( red, green, blue );
  glVertex2f( x, y);
  glEnd();

  x = x + 1;
  if (p < 0)
   p = p + incE;
  else {
   y = y + 1;
   p = p + incNE;
  }
 }
}



Algoritmo de Línea DDA
El analizador diferenciador digital (DDA - Digital Differential Analyzer) es un algoritmo de conversión de rastreo que se basa en el cálculo ya sea de ∆y o ∆x por medio de las ecuaciones 

∆y=m∆x
o
∆x= ∆y/m

Se efectúa un muestreo de la línea en intervalos unitarios en una coordenada y se determina los valores enteros correspondientes mas próximos a la trayectoria de la línea para la otra coordenada.

Tomemos una línea con pendiente positiva, si la pendiente |m|≤1, se hace el muestreo en x en intervalos unitarios (∆x=1 y ∆y=m dado que m=∆y/∆x ) y se calcula cada valor sucesivo de y como:

y_(k+1)=y_k+m

El subíndice toma valores enteros a partir de 1 y aumenta a razón de 1 hasta alcanzar el valor final.

Ya que m puede ser cualquier número real entre 0 y 1, los valores calculados de y deben redondearse al entero más cercano. Para líneas con una pendiente |m| > 1, se revierten las funciones de x y y, o sea, se realiza un muestreo de y en intervalos unitarios (∆y=1 y ∆x=1/m dado que m=∆y/∆x) y se calcula cada valor sucesivo de x como:

x_(k+1)=x_k+1/m

Las ecuaciones anteriores se basan en la suposición de que las líneas deben procesarse del extremo izquierdo al derecho. Si este procesamiento se revierte, entonces ∆x o ∆y serian -1, y

y_(k+1)=y_k-m o x_(k+1)=x_k-1/m



Codificación a color del Algoritmo DDA:



Codificación en texto plano del Algoritmo DDA:

void LiniaDDA( float red, float green, float blue, int x0, int y0, int x1, int y1)
{
 float x, y, xs, ys;
 int dx, dy, steps;
 dx = x1 - x0;
 dy = y1 - y0;
 
 /* se asigna el punto de donde se comenzara a dibujar la línea */
 x = x0;
 y = y0;
 
 /* verificar si la pendiente es mayor de x o y, para luego asignarla a steps */
 if (abs(dx) > abs(dy))
  steps = abs(dx);
 else
  steps = abs(dy);
 
 /* se divide por la pendiente mayor, para dar xs o ys igual a 1 (o -1) */
 if (steps == 0) {
  
  glBegin( GL_POINTS );
  glColor3f( red, green, blue );
  glVertex2f( redonder(x), redondear(y) );
  glEnd();
  
  printf( "Esta linea es un punto" );
  return;
 }
 
 xs = dx/steps;
 ys = dy/steps;
 
 /* se cicla uno a la vez hasta llegar al numero de steps máximo */
 for (i = 0; i <= steps; i++)
 {
  glBegin( GL_POINTS );
  glColor3f( red, green, blue );
  glVertex2f( redonder(x), redondear(y) );  /* redondear(x) -> x+0.5 */
  glEnd();
  x = x + xs;
  y = y + ys;
 }
}




Fuente:
http://technogy-2012.blogspot.mx/2012/05/blog-post.html
http://www.cannes.itam.mx/Alfredo/Espaniol/Cursos/Grafica/Linea.pdf
http://www.nosolounix.com/2010/04/algoritmo-dda-dibujar-linea.html