martes, 22 de mayo de 2012

AVANCE NAVE ESPACIAL EN EQUIPO

IMAGENES DE LA NAVE ESPACIAL QUE SE DESARROLLARA.




RESUMEN


PROCESAMIENTO DE IMAGENES.
Es el procesamiento digital de imágenes que se distinguen en dos niveles en General.
Imágenes de bajo nivel. Las cuales usan poco conocimiento respecto a imágenes yllevan 4 pasos adquisición de la imagen, pre-procesamiento, segmentación y clasificación.
Imágenes de alto nivel. Estas tienen la capcidad de tomar decisionbes conr especto a las imagenes y sus objetos


El procesamiento de imágenes esta dado por un conjunto de operaciones llevadas a cabo sobre las imágenes de realizar mediciones cuantitativas para poder describirlas es decir, extraer ciertas características que permitan mejorar la imagen.


El poder realizar medida sobre las imágenes requiere de caracteristicas bine datalladas de los bordes y limites de su aparencia visual.
Las herramientas para la adquisición de  imágenes transforman la imagen visual de un objeto fisico y sus características intrínsecas en un conjunto de datos organizados para procesarla.


Filtros
Existen filtros para la eliminación de ruido en imágenes, Esto se detecta en un electrocardiograma como los cuadros que aparecen en el fondo de la imagene, asi como un pixel. 
Por eso se desarrollaron algoritmo parala restauracion de imagenes.



Filtro gaussiano
Este filtro tienen el inconveniente de que, además de remover el ruido, empana la imagen ocasionando perdida de los detalles mas finos. Es comúnmente utilizado en aplicaciones de detección de bordes y análisis de escala espacial.

Filtro mediana (rango de vecindades)
El objetivo del filtro mediana es reducir el empañamiento de los bordes. Este filtro reemplaza el pixel actualmente analizado en la imagen por la mediana del brillo con respecto a los vecinos mas cercanos.

Contraste.
La técnica de realce de contraste tiene como objetivo mejorar la calidad de las imágenes bajo ciertos criterios subjetivos del ojo humano. Normalmente esta técnica es utilizada como una etapa de pre-procesamiento para sistemas de reconocimiento de patrones.
El contraste entre dos objetos se puede definir como la razón entre sus niveles de gris medios.

Filtro paso bajo.
El filtro paso bajo es un tipo de filtro de suavizado empleado para remover ruido de alta frecuencia espacial en una imagen digital. Este ruido es generalmente introducido en la imagen durante el proceso de conversión de analógico a digital como un efecto secundario de la conversión física de patrones de energía luminosa a patrones eléctricos.

Filtro paso alto.
De manera general, el filtro paso alto opera de la misma manera que el filtro paso bajo, mediante el análisis de los valores de cada pixel y cambiando estos de acuerdo a los valores de los pixeles vecinos.

Filtro SUSAN (Smallest Univalue Segment Assimilating Nucleus) 
Este algoritmo es para la eliminación de ruido preserva la estructura de la imagen alisando únicamente sobre los píxeles que se encuentran dentro de la región del pixel analizado (pixel central) tomando un excedente del promedio de los pixeles en la localidad que cae dentro del USAN (Univalue Segment Assimilating Nucleus).

Operaciones para la detección de errores
La detección de esquinas y líneas se basa en los operadores de detección de bordes, mismo que mediante el cálculo de primeras y segundas derivadas permiten determinar puntos de principal importancia para poder realizar las mediciones necesarias.
Al hablar de detección de bordes, el termino sugiere que la aplicación de un algoritmo con este propósito dará como resultado un contorno.


ANIMACION POR COMPUTADORA
La animación por computadora es la simulación de un movimiento creado por la muestra de imágenes consecutivas. Se puede definir por algún formato de presentación de información digital en movimiento través de una secuencia de imágenes.
También existe la animación en 3D con la cual se han desarrollado muchs peliculas y caricaturas en los últimos anos.
Tambien se pueden desarrollar partes de la película por separada y no todo en un soilo frame.
Dependiendo de como se desarrolle la película y el tamaño de los objetos es la credibilidad de la misma.

Técnicas de animación
Algunas técnicas en la animación tradicional son la animación en acetatos, la animación en cuadros y la animación en sprite.

Animación Basada en Cuadros.
La animación basada en cuadros es una de las mas utilizadas. Una película contiene 24 cuadros por segundo generalmente, las caricaturas tienen solamente 12. Para hacer una secuencia se van filmando las imágenes cuadro por cuadro y luego estos se unen para formar la animación. Es posible formar bibliotecas de movimientos de cada parte del cuerpo de la animación para de esta forma combinarlas y hacer animaciones diferentes.

Animación basada en sprites.
Sobre la aniumacion en Sprites, esta se refiere a animaciones de objetos sobre fondos estáticos, es decir, lo que cambia son los personajes. Esta técnica es aplicada en los videojuegos. Con el paso del tiempo, se han creado nuevas técnicas como key framing, rotoscopiado, motion control y wavelets.

Key framming
Se refiere a establecer posiciones en puntos específicos de tiempo en animación y la parte intermedia la obtiene la computadora por medio de interpolación matemática. Es necesario hacer un key frame para cada control en cada nivel de la jerarquía del modelo.

Rotoscopiado.
Consiste en una forma mas elaborada de key framming. En este caso se obtiene la posición y el ángulo de los puntos clave de imágenes reales y se trata de hacer converger los modelos en computadora con ellos.

Motion Control.
La técnica de Motion control es muy utilizada actualmente, sobre todo en sets virtuales y en el cine. Consiste en obtener posiciones clave de manera automática a partir de un actor real por medio de dispositivos que se conectan a su cuerpo.

Wavelets.
Significa “pequeñas ondulaciones”. Esta técnica permite que en una sola imagen se compriman una gran cantidad de datos para que al acercarse a ella, se vayan viendo los detalles.

Técnicas de pixar.
El proceso que utiliza pixar para crear animaciones se compone de cuatro etapas principales: Desarrollo (crear guion de la historia), preproducción (se direccionan los retos técnicos), producción (creación de la película) y post producción (pulir los últimos detalles). El proceso es largo.

sábado, 19 de mayo de 2012

jueves, 17 de mayo de 2012

Graficos por medio de computadora

GRAFICACION EN LA MEDICINA

La graficacion a ayuda a la medicina de una forma sorpredente ya que gracias a esta, se simula los sistemas del cuerpo para entender mas a fondo sus funciones.

La graficacion a formulado desde el simple sensor arterial, o de pulsos par aun entendimiento, hasta la forma fisica del adn para ver como se esta combinado

GRAFICACION EN LA EDUCACION

De igual forma que hacia la medicina, los estudiantes de esta rama se ven beneficiados ya que por esto se conocen mas a fondo los aparatos de una forma visual.

Para los estudiantes de otras carreras influyen en mucho como en nuestra clase la cual no enseña a crear todo visual para hacer un atractivo visual.

Para los niños el que sea mas visual las cosas llama la atencion, asi de esta forma los niños son itneresados por los estudios, el uso del computador y el manejo de una orden en sus proyectos.

Gracias a la graficacion se simulan los movimientos de robots antes de que estos salgan al mercad.

Loa programas de educacion son desarrollados en programas que no tengo ni idea como se puedan llamar



GRAFICACION EN LA PUBLICIDAD

Una imagen dice mas de mil palabras. Para la publicidad siempre funciona por medio d euan beuna amrca, politica o un emblema que lo diferencie.

Si un puesto o lugar no tiene una atractivo para el cliente este no es apresiado. Para la gente lo mas nuevo o con aires de novedad les llama la atencion. Un ejemplo basico seria un pizeria. si hay dos juntas y una tiene un dibujo esta le llama la atnecion mas a los clientes que la anterior.

La graficacion permite desarrollar una buena imagen en 3D o inclusive un comercial para la propoganda de cualquier negocio. Hay que irse innovando ya que todo va evolucionando de una manera exponencial y hay que tenerse todo al margen.

La graficacion se peude producir en programas desarrollados por AS, C#, entre otros programas de programas.



GRAFICACION EN EL ENTRETENIMIENTO

Para el entretenimiento la graficacion lo es todo, por eso mismo se ven tarjetas de video para llegar a la calidad suiciente para correr los juegos, el shadder de los pixeles, velocidad del clock, entre otros.

En la actualidad los videos, peliculas y juegos son capaces de simular una persona fisicamente con sus caracteristicas de una forma presisa, dependiendo del hardware adicional se puede llegar a nivel optimo de video para que paresca un 80% real.

Los videos musicales aprovechan las gráficas de muchas maneras, se pueden combinar objetos gráficos con acción en vivo, o se pueden utilizar técnicas de procesamiento de imágenes para producir una transformación de una persona o un objeto en otro

Los juegos se producen en c# en su mayoria.



viernes, 27 de abril de 2012

Investigación 4ta unidad



AGREGAR UN SOMBREADO A UN POLIGONO EN OPENGL

Es el método que utiliza OpenGL para rellenar de color los polígonos. Se especifica con la función glShadeModel. Si el parámetro es GL_FLAT, ogl rellenará los polígonos con el color activo en el momento que se definió el último parámetro; si es GL_SMOOTH, ogl rellenará el polígono interpolando los colores activos en la definición de cada vértice.
 Este código es un ejemplo de GL_FLAT: 
glShadeModel(GL_FLAT);
glBegin(GL_TRIANGLES);  
      glColor3f(1.0f, 0.0f, 0.0f);  // activamos el color rojo
glVertex3f(-1.0f, 0.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);  // activamos el color verde
      glVertex3f(1.0f, 0.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);  // activamos el color azul
      glVertex3f(0.0f, 1.0f, 0.0f);
glEnd();




Tecnicas de sombreado clasicas y avanzadas

Clásicas: Iluminación local.
Luces que no son extensas, como las reales, sino inextensas, puntuales. Y, por añadidura, se relacionan con los objetos como mónadas aisladas, sin tener en cuenta la interacción entre ellos. Esto explica lo artificioso de muchas de las técnicas que se describirán más adelante y que buscan compensar estas limitaciones.

Cálculos de iluminación por vértices
Para aplicar iluminaciona un objeto necesitamos asociar un vector normal a cada vertice del objeto.  Cuando tenemos la normal calculada tenemos que normalizarla, o sea, dividir ese vector por su propio modulo para que sea unitario, pero también podemos hacer que se encargue la OpengGl activando la normalización con el comando glEnable GL_NORMALIZE o desactivarla con glDisable GL_NORMALIZE.
El usar GL_NORMALIZE dependerá de nuestra aplicación ya que si forzamos a que sea OpenGl el que las utilice se ralentiza por que le estamos obligando a hacer mas cálculos de los que debe.
Para definir las normales en opengl utilizaremos la función glNormal3f(X,Y,Z) por ejemplo para definir una cara con 4 vértices la definiremos de la siguiente manera:
GlBegin GL_QUADS
glNormal3f nX,nY,nZ
glvertex3f x,y,z
glvertex3f x,y,z
glvertex3f x,y,z
glvertex3f x,y,z
glEnd

Renderizado en Tiempo real
La idea fundamental del procesado en tiempo real es que todos los objetos deben ser descompuestos en polígonos. Estos polígonos serán descompuestos a su vez en triángulos. Cada triángulo será proyectado sobre la ventana bidimensional y rellenado con los colores adecuados para reflejar los efectos de la iluminación, texturas, etc. Una vez se han generado los triángulos, en la pipeline existen dos partes claramente diferenciadas: una primera etapa operaciones realizadas sobre cada uno de los vértices, y después de que éstos se proyecten sobre la ventana, entonces comienza una segunda fase de cálculos realizados para cada pixel cubierto por triángulos.


Realistas: iluminación global
 Son aquellos en los que se considera que la intensidad de luz en un punto de la superficie de un objeto se debe a las fuentes luminosas y al resto de los elementos existentes en la escena.


Realistas: Iluminación global
Son sencillos y rápidos pero proporcionan imágenes muy simples, que no representan adecuadamente el modo en que la luz ilumina los objetos y los espacios. Esto no quiere decir que no sean útiles para un gran número de casos, y es muy importante calibrar adecuadamente que es lo que se necesita, pues puede muy bien ocurrir que un cálculo local proporcione imágenes relativamente esquemáticas pero más adecuadas para la representación de un proyecto.


Trazado de rayos
El trazado de rayos computa la interacción de la luz desde un punto de vista determinado y es particularmente adecuado para superficies reflectantes. Puede utilizarse como propiedad especifica de un determinado material. Se traza un rayo desde la posición del observador a través de cada uno de los píxeles del plano de proyección (una de las ventajas del raytracing es que los rayos que se procesan son sólo los rayos que parten del observador ),

Radiosidad
Está basado en principios generales que se pueden encontrar en un manual general sobre rendering. En el estadio inicial la escena consta de dos tipos de objetos: objetos que emiten luz y objetos que reciben luz. A partir de aquí, en una primera vuelta, se computa la luz que recibe cada objeto o, en una aproximación más exacta, cada parte de un objeto, según una subdivisión cuya densidad puede precisarse en sucesivas aproximaciones.


Cálculos de iluminación por pixel
La iluminación por píxel en tiempo real es una tecnología revolucionaria ofrecida como primicia por NVIDIA Shading Rasterizer. La iluminación dinámica a nivel de píxel libera a los desarrolladores de las restricciones de otros sistemas de iluminación y pone a su alcance toda una gama de sofisticados efectos. Antes de que el color final del píxel sea decidido, un cálculo de iluminación debe ser computado para sombrear a los píxeles basados en alguna luz que puede estar presente en la escena.

Alto Acabado
Sombreado Constante o plano. Un cálculo para todo el polígono. Obtenemos una intensidad  que aplicamos a un conjunto de puntos de un objeto (p.ej. todo un triángulo). Aceleramos el proceso de síntesis.  Correcto si se verifica: Fuente de luz en el infinito. Observador en el infinito. El polígono representa una superficie plana real del objeto que se modela y no es una aproximación de un objeto curvo.

 Sombreado Constante o Plano
 Obtenemos una intensidad que aplicamos a un conjunto de puntos de un objeto 
  *Aceleramos el proceso de síntesis
  *Correcto si se verifica.
  * Fuente de luz en el infinito
  *Observador en el infinito

Modelo de Reflexión Phong 
El modelo de reflexión de Phong es eficiente y suficientemente aproximado a la realidad física para producir buenas imágenes, bajo una variedad de condiciones de luz y propiedades de materiales. Apoya los tres tipos de interacciones material-luz: ambiente, difusa y especular. Si se tiene un conjunto de fuentes puntos, con componentes independientes para cada uno de los tres colores primarios para cada uno de los tres tipos de interacciones material-luz.

Ray Tracing 
En muchas formas, ray tracing es una extensión al enfoque de rendering con un modelo de iluminación local. Está basado en la observación previa que, de los rayos de luz saliendo de una fuente, los únicos que contribuyen a la imagen son aquellos que entran al lente de la cámara sintética y pasan por el centro de proyección. 

Buffer Stencil. 
Stencill Buffer es una memoria intermedia que analiza y actualiza píxeles (con sus operaciones) junto con “depth buffer” o buffer de profundidad. Añade planos de bits adicionales para cada píxel además de los bits de color y profundidad. 

 Stencil buffer es similar al buffer de profundidad en que los dos son colección de planos de bit que no se pueden mostrar. Del mismo modo que el buffer de profundidad asocia a cada píxel de la ventana un valor de profundidad, el stencil buffer asocia su propio valor a cada píxel mostrado. Cuando el buffer de profundidad esta activado los valores de profundidad son usados para aceptar o rechazar fragmentos, del mismo modo los valores de Stencil buffer son usados para aceptar o rechazar fragmentos.

Buffer de Acumulacion
 Normalmente se usa un buffer de acumulación para unir las 2 imágenes 


Fuentes de Luz 
  La luz puede dejar una superficie mediante dos procesos fundamentales:
  • Emisión propia 
  • Reflexión 
 Normalmente se piensa en una fuente de luz como un objeto que emite luz solo mediante fuentes de energía internas, sin embargo, una fuente de luz, como un foco, puede reflejar alguna luz incidente a esta del ambiente. 

 Fuentes de Luz
La luz puede dejar una superficie mediante dos procesos fundamentales:
*  Emisión propia
* Reflexión

Luz Ambiente
La luz ambiente ilumina por igual todas las zonas en sombra para simular el efecto de interacción entre objetos que hace que las partes en sombra de los objetos queden parcialmente iluminadas.

Spotlights (direccionales) 
 Los spotlights se caracterizan por un rango delgado de ángulos por los cuales se emite luz. Se puede construir un spotlight sencillo de una fuente de punto limitando los ángulos de donde la luz de la fuente se puede ver. Se puede usar un cono cuyo ápice está en ps, apuntando en la dirección ls, y cuyo ancho está determinado por el ángulo θ.







http://sabia.tic.udc.es/gc/Contenidos%20adicionales/trabajos/3D/modelosIlumionacion/introduccion_intensidad_completa.html
http://e-md.upc.edu/diposit/material/24099/24099.pdf
http://informatica.uv.es/iiguia/AIG/web_teoria/tema3.pdf
http://dac.escet.urjc.es/docencia/IG/08-IluminacionSombreado4.pdf




domingo, 22 de abril de 2012

Carro Movimiento

Carro 2da dimensión y movimiento



#include <GL/glut.h>
GLfloat anguloCuboX = 0.0f;
GLfloat anguloCuboY = 0.0f;
GLfloat anguloEsfera = 0.0f;




GLint ancho=900;
GLint alto=600;
 int ang =0 ;
 int movx = 0;
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(1.0f, 0.0f, 1.0f);
 glScalef(1.5f,0.0f,1.5f);
    glBegin(GL_QUADS);       //cara abajo
    glVertex3f( 10.0f,-10.0f, -10.0f);
    glVertex3f( 10.0f,-10.0f,  10.0f);
    glVertex3f(-10.0f,-10.0f,  10.0f);
    glVertex3f(-10.0f,-10.0f, -10.0f);
    glEnd();
}
void carro(void)
{
    glColor3f(0.0f, 1.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, 0.0f, -5.0f);
    glRotatef(15, 1.0f, 0.0f, 0.0f);
    glRotatef(15, 0.0f, 1.0f, 0.0f);
     Piso();
  
 //dibuja 2da rueda
 glLoadIdentity();




  glColor3f(0.98f, 0.04f, 0.7f);
  glTranslatef(movx,0.0,0.0);
  carro();
  glLoadIdentity();
       
  glTranslatef(-.5f,0.5f,-1.0f);
  glColor3f(0.98f, 0.04f, 0.7f);
  glRotatef(ang,1.0,0.0,0.0);
  glTranslatef(movx,0.0,0.0);
  glutSolidSphere(0.5f, 16, 16);
  glLoadIdentity();




  glTranslatef(3.0f,0.5f,-1.0f);
  glColor3f(0.98f, 0.04f, 0.7f);
  glRotatef(ang,1.0,0.0,0.0);
  glTranslatef(movx,0.0,0.0);    
      glutSolidSphere(0.5f, 16, 16);
      glLoadIdentity();
    glFlush();
    glutSwapBuffers();
}
void init()
{
    glClearColor(0,0,0,0);
    glEnable(GL_DEPTH_TEST);
    ancho = 600;
    alto = 900;
}
void idle()
{
    display();
}
void specialkeyevent( int key, int Xx, int Yy )
{    
 switch ( key ) {
   
  case GLUT_KEY_LEFT:
   movx-=1;
   ang-=1;
   display();
   break;
  case GLUT_KEY_RIGHT:
   movx+=1;
   ang-=1;
   display();
   break;   
 }
 glutPostRedisplay();
}
int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(ancho, alto);
    glutCreateWindow("Carrito Movimiento");
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);
    glutSpecialFunc(specialkeyevent );
    glutMainLoop();
    return 0;





miércoles, 18 de abril de 2012

Como se realiza un circulo y una elipse



¿Que es y como desarrollar un circulo?

Un circulo es el conjunto de todos los puntos en un plano que son equidistantes de un punto dado en el plano; llamado centro. Cualquier segmento cuyos puntos terminales estan en el centro y en un punto en el circulo; constituye el radio del circulo.
Ecuacion del circulo:
la ecuacion de un circulo con centro en (h,k) y radio r unidades es:


(x-h)+ (y-k)2=r2

Hallar la ecuación de la circunferencia cuyo centro es C(2;6) y con radio r = 4


(x - 2)² + (y - 6)² = 4²




¿Que es y como desarrollar un elipse?


Una elipse es el conjunto de puntos en un plano,tales que la suma de las distancias de los focos sea constante.
la Elipse con centro en h,k con el eje horizontal tiene ecuacion.


(x-h)2 + (y-k)2 =  1
   a2          b2


dibujo





http://prof-gonzales-trigonometria.blogspot.mx/2007/07/blog-post_5225.html

lunes, 16 de abril de 2012

Reporte GluLookAt

La funcion GluLookAt sirve para tener en especifico una toma de una imagen en OpenGL.Esta se especifica por 9 variables.gluLookAt(eyeX, eyeY, eyeZ, atX, atY, atZ, upX, upY, upZ);Como se muestra en el ejemplo son 3 secciones que interactuan con las coordenadas graficas xx, yy y zz,
Una manera mas sencilla de explicar esto, es como un zoom, suponiendo que utilizaramos una camara para grabar una pelicula y en alguna escena quisieramos hacer una toma de la protagonista desde un angulo aero o con alguna forma en especifico.




DIFERENCIA ENTRE GLULOOKAT() Y GLTRANSLATE()
La difirencia entre el glTranslatef y GlutAt() es m uy simple, ya que una como su nombre lo dice la funcion traslada el objeto que se este visualizando a otro lugar. Es decir, si se encuentras solo visualizandoce cierta parte del objeto con este se mueve sobre el eje deseado, mientras que el lookAt el objeto permanece en el mismo lugar.









CODIGO FUNCION LOOKAT

#include <GL/glut.h> // Once you include glut.h (you don't need gl.h or glu.h)   

GLfloat X = 0.0f; // Translate screen to x direction (left or right)
GLfloat Y = 0.0f; // Translate screen to y direction (up or down)
GLfloat Z = 0.0f; // Translate screen to z direction (zoom in or out)
GLfloat rotX = 0.0f; // Rotate screen on x axis 
GLfloat rotY = 0.0f; // Rotate screen on y axis
GLfloat rotZ = 0.0f; // Rotate screen on z axis
GLfloat rotLx = 0.0f; // Translate screen by using the glulookAt function (left or right)
GLfloat rotLy = 0.0f; // Translate screen by using the glulookAt function (up or down)
GLfloat rotLz = 0.0f; // Translate screen by using the glulookAt function (zoom in or out)
void glDisplayLines(void); // Did declare the function    // so I did not have to check for order of the functions
// Initialize the OpenGL window
void init(void)
{
    glClearColor (0.0, 0.0, 0.0, 0.0); // Clear the color 
   glShadeModel (GL_FLAT); // Set the shading model to GL_FLAT  
   glEnable (GL_LINE_SMOOTH);
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Set Line Antialiasing}
// Draw the lines (x,y,z)
void display(void)

    glClear (GL_COLOR_BUFFER_BIT); // Clear the Color Buffer   
 glPushMatrix();  // It is important to push the Matrix before calling    // glRotatef and glTranslatef    glRotatef(rotX,1.0,0.0,0.0); // 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;
}