Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Laboratorio 05
Proyecciones geométricas
y cámara móvil con
Diseño de vistas empleando
proyecciones geométricas.
OpenGL
Objetivo: El objetivo de esta práctica, es que el alumno conozca y sepa manejar apropiadamente las
proyecciones (ortográfica y/o perspectiva) en la elaboración de una aplicación con características
interactivas, para esto se incorporará la cámara móvil obteniéndose una mayor soltura en cuanto al
desplazamiento del usuario.
El conocimiento requerido para realizar esta práctica es de haber asimilado los conceptos básicos
de C/C++ y OpenGL y la teoría necesaria para proyecciones en 2D y 3D.
Para llevar a cabo una animación no solo se requiere saber transformar la geometría o los
elementos que son parte de la animación, sino que además hay que elegir como proyectarlos en un
sistema de visualización que en este caso es bidimensional (nuestro viewport o monitor). Este
laboratorio describe dos tipos de proyecciones en concreto además de tener un control del movimiento
y posición del observador cuando este se desplaza a través de la escena (alámbrica o sólida).
• PROYECCIONES:
Existen dos tipos de proyecciones que son muy usadas para efectos prácticos, las cuáles son las
siguientes:
• Proyecciones Paralelas. Dependiendo del ángulo que forma con el plano de proyección
pueden ser:
a. Oblicua
b. Ortográfica.
• Proyecciones en Perspectiva. Dependiendo del número de punto de fuga de eje pueden ser:
a. 1 punto de fuga
b. 2 puntos de fuga
c. 3 puntos de fuga
• PROYECCIÓN ORTOGRÁFICA:
A los valores Zmax y Zmin también se les denomina FAR o BACK y NEAR o FRONT.
En OpenGL la podemos definir de la siguiente forma (ya lo habíamos visto en algunos ejemplos
desarrollados anteriormente):
1
CAD (Computer Aided Design), se refiere a las herramientas computacionales que permiten asistencia a ingenieros, arquitectos
y áreas de diseño.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
• PROYECCIÓN EN PERSPECTIVA:
En la figura No 2, tenemos una proyección perspectiva con un sólo COP o punto de fuga. Todos
los proyectores emanan de él (o convergen hacia el) y se dirigen hasta el objeto intersecando el plano
de proyección. Como se puede deducir, los proyectores no son paralelos entre ellos.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(Angulo,Aspecto,Znear,Zfar);
glFrustrum(left,right,bottom,top,near,far);
2. LA CÁMARA MÓVIL
Todo lo que ella vea será proyectado, discretizado y finalmente mostrado en nuestra ventana de
visualización grafica. Podemos imaginar que de la cámara emana el volumen de visualización de forma
que se traslada con ella. La función en OpenGL viene a ser:
gluLookAt(eyeX,eyeY,eyeZ,atX,atY,atZ,upX,upY,upZ);
En cuanto a los parámetros que demanda la función gluLookAt son los siguientes:
• Coordenadas del "eye". Es literalmente la posición XYZ dónde colocar la cámara dentro del
mundo.
• Coordenadas del "at". Es el valor XYZ del punto al que queremos que mire la cámara. Un punto
del mundo obviamente.
• Coordenadas del vector "up". Es un vector y no un punto. Con él regularemos la orientación de
la cámara. Este ha de ser el vector que "mira hacia arriba" si entendemos que el vector que
apunta hacia adelante es el que va del "eye" hasta el "at". Variando el "up" variamos la
orientación:
Esta es la función que determina dónde y cómo está dispuesta la cámara. Hay que tener presente
que la posición de la cámara no tiene nada que ver con el tipo de proyección que hayamos definido.
La proyección se define sólo una vez, típicamente al principio del programa en una función
inicializadora, mientras que la cámara se mueve continuamente según nos convenga. Tome en cuenta
que la matriz que se modifica al llamar a esta función no tiene que ser GL_PROJECTION si no
GL_MODELVIEW. OpenGL calculará todas las transformaciones que aplicará al mundo 3D para que
manteniendo la cámara en el origen de coordenadas y enfocada en la dirección negativa de las Z's nos
dé la sensación de que lo estamos viendo todo desde un cierto lugar. Para ello siempre se debe activar
esta matriz antes de llamar a gluLookAt de esta forma:
glMatrixMode(GL_MODELVIEW);
Implemente funciones que le permitan desplazarse con libertad en un modelo alámbrico (objeto
geométrico); inicialmente, desplazarse hacia delante y hacia atrás, luego girar tanto a la derecha como
a la izquierda, y finalmente tener autonomía total, es decir, desplazarse hacia arriba o hacia abajo. Esta
aplicación incluye también transformaciones geométricas, para ello use el código del taller anterior
(taller 02).
#include <stdlib.h>
#include<conio.h>
#include<stdio.h>
#include<math.h>
#include <gl/glut.h>
void ejes(int);
GLdouble angulo=0, incremento_angulo=0.1;
GLdouble const radio=0.5;
GLfloat px0=0,py0=0,pz0=5;
GLfloat px1=0,py1=0,pz1=4;
static GLfloat theta[] = {0.0,0.0,0.0};
static GLint axis = 2 ;
void iniciar(void)
{
glClearColor (1.0, 1.0, 1.0, 0.0);
glShadeModel (GL_FLAT);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glLoadIdentity();
// la camara se desplaza sobre el plano xz
gluLookAt(px0,0.0,pz0,px1,0.0,pz1,0,1,0);
glColor3f (1.0, 0.0, 0.0);
ejes(2);
glRotatef(theta[0],1.0,0.0,0.0);
glRotatef(theta[1],0.0,1.0,0.0);
glRotatef(theta[2],0.0,0.0,1.0);
glColor3f (0.0, 0.0, 1.0);
glutWireDodecahedron();
glFlush();
glPopMatrix();
glutSwapBuffers();
}
void CubeSpin()
{
theta[axis] += .2;
if(theta[axis]>360) theta[axis] -= 360.0;
display();
}
void rotacamara()
{
px1=px0+radio*sin(angulo);
pz1=pz0-radio*cos(angulo);
}
void avanza()
{
px0=px1;pz0=pz1;
px1=px0+radio*sin(angulo);
pz1=pz0-radio*cos(angulo);
}
void retro()
{
px1=px0;pz1=pz0;
px0=px0-radio*sin(angulo);
pz0=pz0+radio*cos(angulo);
}
void teclado(unsigned char tecla,int x,int y)
{
switch(tecla){
case 'i' : avanza();break;
case 'm' : retro(); break;
case 'j' : angulo=angulo+incremento_angulo;rotacamara(); break;
case 'k' : angulo=angulo-incremento_angulo;rotacamara(); break;
case 'a' : axis = 0; break;
case 's' : axis = 1; break;
case 'd' : axis = 2; break;
4. EJERCICIOS PROPUESTOS
Ejercicio 01:
Nota:
Puede consultar las referencias para tener conocimiento de algunas primitivas graficas definidas
en OpenGL como, por ejemplo:
• glutWireCube
• glutWireSphere
Todas estas y otras se hallan en la referencia The OpenGL Utility Toolkit (GLUT) Programming
Interface; también consulte otras referencias con ejemplos.
Ejercicio 02:
Diseñe su propia primitiva grafica para un cilindro alámbrico; esta tendrá una altura y radio iguales
a la unidad, será paralelo al eje Y y centrado en el origen de coordenadas. su formato deberá ser:
Mi_Cilindro_Wire(Npara,Ncortes)
Donde:
Ejercicio 03:
Ejercicio 04:
Ejercicio 05:
Construir un modelo molecular (alámbrico) para el Cubano, sólido cristalino sintetizado en 1964
por el profesor Philip Eaton de la Universidad de Chicago.
Enlace de referencia:
http://www.quimicaorganica.net/quimica-organica/alcanos/alcanos.htm
Nota:
5. REFERENCIAS
1. Principles and Practice (Second Edition). Foley J. D., A.van Dam, S.K.Feiner and J.F.
Hughes Computer Graphics. Addison-Wesley. 1990
2. OpenGL Superbible. R. Wright and M. Sweet. Waite Group, Inc 1996
3. OpenGL Programming Guide: The Official Guide to Learning OpenGL. D. Sheiner, M.
Wood, J. Neider and T. Davis. Addison Wesley, 2007
4. The OpenGL Utility Toolkit (GLUT) Programming Interface (API Version 3). Mark J. Kilgard,
Silicon Graphics, Inc 1996
5. The OpenGL Graphics System: A Specification (Version 1.2). Mark segal & Kurt Akeley.
Silicon Graphics, Inc 1998