lunes, 23 de abril de 2012

Circulos y Elipses


Circulos:
Utilizando B-Splines racionales, podemos dibujar circulos, elipses entre otras cosas bidimensionales. Además, se incluyen rutinas en el conjunto de herramientas de GLU (GLUT, OpenGL Utility Toolkit) que podemos utilizar para mostrar algunas cuádricas tridimencionales como esferas y conos y algunas otras formas geometricas.

Otro método que se puede utilizar para generar la grafica de una curva simple consiste en aproximarla utilizando una polilinea. Basta con localizarun conjunto de puntos a lo largo de la trayectoria y conectar dichos puntos mediante segmentos de lineas rectas. Cuantas mas secciones se incluyan mas suave sera la apariencia de la curva.

Puesto que el circulo es un componente muy frecuentemente utilizado en dibujos y gráficas, muchos paquetes gráficos incluyen un procedimiento para generar circulos completos o arcos circulares.

Puesto que el círculo es un componente muy frecuentemente utilizado en dibujos y gráficas, muchos paquetes gráficos incluyen un procedimiento para generar círculos completos o arcos circulares.

La forma del circulo es similar en cada uno de los cuadrantes. Por tanto, si determinamos las posiciones de la curva en el primer cuadrante, podemos generar la sección circular del segundo cuadrante del plano i observando que ambas secciones son simétricas con respecto al eje y. 

Uno de los algoritmos que se pueden utilizar es el del punto medio que consiste en:

Introducir el radio r y el centro del círculo (xv,yt) y luego establecer las coordenadas para el primer punto de la circunferencia de un círculo centrado en el origen mediante la fórmula Calcular el valor inicial del parámetro de decisión
Para cada posición xy comenzando en k = 0, realizar la siguiente comprobación. Si pk < 0, el siguiente punto a lo largo de un círculo centrado en (0,0) será {xk+iJyk) y, P^=Pt+2xktl+\
Determinar los puntos simétricos en los otros siete ociantes.
Mover cada posición de píxel (x, y) calculada hasta la trayectoria circular centrada en (xc,yc) y dibujar los valores de coordenadas: x=x+xc , y = y+yc
Repetir los Pasos 3 a 5 hasta que x > y.
Algoritmos para la generación de Elipces:

También podemos escribir una elipse como un circulo modificado cuyo radio varía desde un valor máximo en una dirección hasta un valor mínimo en la dirección perpendicular.



Código Carro

Código:

#include <GL/glut.h>
GLfloat TrasX=0.0f;
GLfloat TrasY=0.0f;
GLfloat TrasZ=0.0f;
GLint ancho=400;
GLint alto=400;
int hazPerspectiva = 0;
void reshape(int width, int height)
{
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if(hazPerspectiva)
    gluPerspective(60.0f, (GLfloat)width/(GLfloat)height, 1.0f, 20.0f);
     else
       glOrtho(-4,4, -4, 4, 1, 10);
    glMatrixMode(GL_MODELVIEW);
    ancho = width;
    alto = height;
}
void Piso(void)
{
    glColor3f(0.25f, 0.25f, 0.25f);
 glScalef(5.0f,0.0f,5.0f);
   
 glBegin(GL_QUADS);      
    glVertex3f( 2.5f,-1.0f, -1.0f);
    glVertex3f( 2.5f,-1.0f,  1.0f);
    glVertex3f(-1.0f,-1.0f,  1.0f);
    glVertex3f(-1.0f,-1.0f, -1.0f);
    glEnd();
}
void carro(void)
{
   glColor3f(1.0f, 0.0f, 1.0f);
glTranslatef(0.0f, -2.0f, 0.0f);
glBegin(GL_POLYGON); //carro
glVertex3f(-1.5f,0.5f, -2.0f);
glVertex3f( 3.5f,0.5f, -2.0f);
glVertex3f(3.5f,2.0f, -2.0f);
glVertex3f(2.0f,2.0f, -2.0f);
glVertex3f(1.f,3.0f, -2.0f);
glVertex3f(-0.5f,3.0f, -2.0f);
glVertex3f(-1.5f,2.0f, -2.0f);
glEnd();
}
void display()
{
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, -2.0f, -5.0f);
glRotatef(10, 1.0f, 0.0f, 0.0f);
glRotatef(10, 0.0f, 1.0f, 0.0f);
// dibuja piso
Piso();
// dibuja rueda
glLoadIdentity();
glTranslatef(3.0f,-1.5f,-1.0f);
glTranslatef(TrasX,TrasY,TrasZ);
glColor3f(0.0f, 0.0f, 0.0f);
glutSolidSphere(0.5f, 16, 16);



//dibuja 2da rueda
glLoadIdentity();
glColor3f(0.0f, 1.0f, 1.0f);
glLoadIdentity();
glTranslatef(TrasX,TrasY,TrasZ);
carro();
glLoadIdentity();
glTranslatef(-.5f,-1.5f,-1.0f);
glTranslatef(TrasX,TrasY,TrasZ);
glColor3f(0.0f, 0.0f, 0.0f);
glutSolidSphere(0.5f, 16, 16);
glFlush();
glutSwapBuffers();
}
void init()
{
    glClearColor(1,1,1,1);
    glEnable(GL_DEPTH_TEST);
    ancho = 400;
    alto = 400;
}
void idle()
{
    display();
}

void keyboard(unsigned char key, int x, int y)
{
    switch(key)
    {
    case 'p':
    case 'P':
  hazPerspectiva=1;
  reshape(ancho,alto);
 break;
    case 'o':
    case 'O':
  hazPerspectiva=0;
  reshape(ancho,alto);
 break;
    case 'a':
    case 'A':
  TrasX-=.10;
 break;
    case 's':
    case 'S':
  TrasX+=.10;
                break;
    }
}

int main(int argc, char **argv)
{
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
 glutInitWindowPosition(100, 100);
    glutInitWindowSize(ancho, alto);
    glutCreateWindow("Carro");
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);
    glutKeyboardFunc(keyboard);
    glutMainLoop();
    return 0;
}

 Resultado:





 

martes, 17 de abril de 2012

¿Que hace el "glutLookAt"?

Es la funsión que determina dónde y como está dispuesta la cámara, cuidando la posición de la cámara no tiene nada que ver con el tipo de proyección que se haya definido.

La proyección se define sólo una vez al principio del programa regularmente, en una función inicializadora, mientras que la cámara que se mueve continuamente como al programador le interese y aun mas en 3D.

A esto no se le añade la función GL_PROYECTION sino que se le agrega el GL_MEDELVIEW.


En ese momento OpenGL se encargara de calcular las transformaciones que se aplican al mundo 3D manteniendo la camara en el origen de las coordenadas y enfocada en direccion negativa de Z para así darnos la sensación de verlo desde cierto lugar.


Para ello siempre se debe activar esta matriz antes de llamar a gluLookAt:
glMatrixMode(GL_MEDELVIEW);

La función GLTRASLATE se utiliza para mover de un punto a otro un objeto y la función GLUTAT se usa para visualizar el objeto.

No se comportan de la misma manera puesto que uno mueve el objeto y el otro mueve la cámara para visualizar el objeto.

Código a examinar:


Rotate on x
  glRotatef(rotY,0.0,1.0,0.0); // Rotate on y
 glRotatef(rotZ,0.0,0.0,1.0); // Rotate on z
 glTranslatef(X, Y, Z);  // Translates the screen left or right,    // up or down or zoom in zoom out
    // Draw the positive side of the lines x,y,z
    glBegin(GL_LINES);
    glColor3f (0.0, 1.0, 0.0); // Green for x axis
    glVertex3f(0,0,0);
    glVertex3f(10,0,0);
    glColor3f(1.0,0.0,0.0); // Red for y axis
    glVertex3f(0,0,0);
    glVertex3f(0,10,0);
    glColor3f(0.0,0.0,1.0); // Blue for z axis
    glVertex3f(0,0,0);
    glVertex3f(0,0,10);
    glEnd();
    // Dotted lines for the negative sides of x,y,z
glEnable(GL_LINE_STIPPLE);  // Enable line stipple to use a
    // dotted pattern for the lines
 glLineStipple(1, 0x0101);  // Dotted stipple pattern for the lines
  glBegin(GL_LINES);
    glColor3f (0.0, 1.0, 0.0);  // Green for x axis
    glVertex3f(-10,0,0);
    glVertex3f(0,0,0);
    glColor3f(1.0,0.0,0.0);  // Red for y axis
    glVertex3f(0,0,0);
    glVertex3f(0,-10,0);
    glColor3f(0.0,0.0,1.0);  // Blue for z axis
    glVertex3f(0,0,0);
    glVertex3f(0,0,-10);
    glEnd();
    glDisable(GL_LINE_STIPPLE);  // Disable the line stipple
    glPopMatrix();   // Don't forget to pop the Matrix
    glutSwapBuffers();
}
// This function is called whenever the window size is changed
void reshape (int w, int h)
{
    glViewport (0, 0, (GLsizei) w, (GLsizei) h); // Set the viewport
    glMatrixMode (GL_PROJECTION);  // Set the Matrix mode
    glLoadIdentity ();
    gluPerspective(75, (GLfloat) w /(GLfloat) h , 0.10, 100.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
// This function is used for the navigation keys
void keyboard (unsigned char key, int x, int y)
{
switch (key) {   // x,X,y,Y,z,Z uses the glRotatef() function
    case 'x': // Rotates screen on x axis
    rotX -= 0.5f;
    break;    case 'X': // Opposite way
    rotX += 0.5f;
    break;    case 'y': // Rotates screen on y axis
    rotY -= 0.5f;
    break;    case 'Y': // Opposite way
    rotY += 0.5f;
    break;
    case 'z': // Rotates screen on z axis
    rotZ -= 0.5f;
    break;    case 'Z': // Opposite way
    rotZ += 0.5f;
    break;
    // j,J,k,K,l,L uses the gluLookAt function for navigation   
    case 'j':
    rotLx -= 0.2f;
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    break;    case 'J':
    rotLx += 0.2f;
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    break;
    case 'k':
    rotLy -= 0.2f;
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    break;    case 'K':
    rotLy += 0.2f;
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    break;    case 'l':  // It has a special case when the rotLZ becomes
  // less than -15 the screen is viewed from the opposite side
    // therefore this if statement below does not allow rotLz be less than -15   
if(rotLz + 14 >= 0)
    rotLz -= 0.2f;          
    glMatrixMode(GL_MODELVIEW);   
    glLoadIdentity(); 
    gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    break;    case 'L':
    rotLz += 0.2f;
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    break;    case 'b': // Rotates on x axis by -90 degree
    rotX -= 90.0f;
    break;    case 'B': // Rotates on y axis by 90 degree
    rotX += 90.0f;
    break;    case 'n': // Rotates on y axis by -90 degree
    rotY -= 90.0f;
    break;    case 'N': // Rotates on y axis by 90 degree
    rotY += 90.0f;
    break;    case 'm': // Rotates on z axis by -90 degree
    rotZ -= 90.0f;
    break;
    case 'M': // Rotates on z axis by 90 degree
    rotZ += 90.0f;
    break;    case 'o': // Default, resets the translations vies from starting view
    case 'O':
    X = Y = 0.0f;
    Z = 0.0f;
    rotX = 0.0f;
    rotY = 0.0f;
    rotZ = 0.0f;
    rotLx = 0.0f;
    rotLy = 0.0f;
    rotLz = 0.0f;
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(rotLx, rotLy, 15.0f + rotLz, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); 
    break;}
    glutPostRedisplay(); // Redraw the scene
}
// called on special key pressed
void specialKey(int key, int x, int y) {
// The keys below are using the gluLookAt() function for navigation
// Check which key is pressed
switch(key) {
    case GLUT_KEY_LEFT : // Rotate on x axis
    X -= 0.1f;
    break;
    case GLUT_KEY_RIGHT : // Rotate on x axis (opposite)
    X += 0.1f;
    break;
    case GLUT_KEY_UP : // Rotate on y axis
    Y += 0.1f;
    break;
    case GLUT_KEY_DOWN : // Rotate on y axis (opposite)
    Y -= 0.1f;
    break;
    case GLUT_KEY_PAGE_UP: // Rotate on z axis
    Z -= 0.1f;
    break;
    case GLUT_KEY_PAGE_DOWN: // Rotate on z axis (opposite)
    Z += 0.1f;
    break;
}
    glutPostRedisplay(); // Redraw the scene
}
// Main entry point of the program
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);  // Setup display mode to
      // double buffer and RGB color
    glutInitWindowSize (600,600); // Set the screen size
    glutCreateWindow("OpenGL 3D Navigation Program");
    init ();
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutKeyboardFunc(keyboard); // set window's key callback
    glutSpecialFunc(specialKey); // set window's to specialKey callback
    glutMainLoop();
    return 0;
}