sábado, 10 de marzo de 2012

Viewport

Viewport

Una ventana es una región rectangular en la visualización de gráficos de computadora , o un término que se utiliza para los componentes ópticos. Cuenta con varias definiciones en diferentes contextos:


Informática

  • En los gráficos por ordenador en 3D que se refiere al rectángulo 2D utilizado para proyectar la escena 3D en la posición de una cámara virtual . Una ventana es una región de la pantalla se utiliza para mostrar una porción de la imagen total que se muestran.
  • Con respecto a los escritorios virtuales , el visor es la parte visible de un área 2D que es mayor que el dispositivo de visualización.
  • Con respecto a los navegadores web , la vista es la parte visible de la tela.
  • En el ASP.NET MVC patrón de diseño de software, la ventana gráfica representa una instantánea de la modelo en un momento dado, a través de un punto de vista, por lo general después de la lógica de dominio ha sido aplicada a ella.


Los componentes ópticos

En fabricación se refiere a componentes ópticos herméticamente cerrados que se usan típicamente para la transmisión de banda de energía visual o amplia dentro y fuera de los sistemas de vacío. Recubrimientos individuales y multi-capas se puede añadir a ventanas para optimizar el rendimiento de la transmisión. Ellos describen en la parte objeto seleccionado reside en el interior de una ventana.

Investigación

Proyección Ortogonal
lo importante del concepto es que las lineas que se proyectan sobre el plano en que estamos dibujando (papel o la ventana de nuestro programa) son perpendiculares a este mismo plano y por tanto paralelas entre si.



Esta proyeccion nos serviria, por ejemplo, para un juego en isometrica (un caso de proyeccion ortogonal) o para graficos en 2D en los que las cordenadas X e Y de los vertices coincidirian con los pixels de nuestra ventana Windows y la coordenada Z seria siempre la misma (en el caso de nuestro codigo ejemplo, 0 ).

Ahora modificamos nuestro programa.
El meollo del asunto sera en la funcion IniciaGL()

Usaremos algo de programacion Windows para ajustar bien el tamaño del viewport al de nuestra ventana: 


Y ahora la funcion glOrtho(...) correspondiente:
glOrtho(xwmin, xwmax, ywmin, ywmax, pcerca, plejos);

Despues viene una parte de codigo para poder ver el tamaño que tiene finalmente nuestro viewport y nuestra proyeccion (ya que los valores dependen del area cliente de la ventana):
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
.
.
.
// Definimos una cadena de caracteres para poner en
// el titulo de nuestra ventana el tamaño del area
// cliente (a mi me gusta saber el tamaño de mi 
// ventana de dibujo)
char cad[50]; // 50 seran suficientes caracteres.
// Relleno mi cadena con lo que voy a poner en la ventana.
sprintf(cad,"USW %i x %i",rect.right,rect.bottom);
// Modifico el titulo de mi ventana.
SetWindowTextA(IdVentana,cad);

Finalmente nos vamos a la funcion Pinta() y modificamos todas las coordenadas para ajustarlas a la nueva proyeccion.
Pongo de ejemplo solo el triangulo principal:

1
2
3
4
5
6
7
8
glBegin(GL_TRIANGLES); 
// Primer vertice de mi triangulo:
glVertex3f(0,350, 0); 
// El segundo vertice de mi triangulo:
glVertex3f(600,350 , 0); 
// El tercer vertice de mi triangulo:
glVertex3f(300, 0, 0);
glEnd();  

Notaras que la esquina derecha del triangulo se sale de la ventana. Esto es porque el lado inferior es de 600 pixels de longitud, lo mismo que la ventana, y el area cliente de la venana es un poco mas pequeña al ser la ventana menos el borde.

El programa se veria asi:




Ejemplo de traslación

Se llama traslación de una figura a la transformación en otra figura mediante un desplazamiento. Para definir una traslación es necesario conocer un vector y un punto.
Ejemplo de traslación de un vector

Ejemplo de rotación

Es por esto que debemos convertir las coordenadas del satélite a un sistema común para conocer cómo se movió en realida. En este ejemplo, si tenemos el tiempo transcurrido y conocemos la velocidad angular de rotación de la Tierra), sabremos el ángulo con el cual difieren ambos sistemas (note que la rotación sólo sucede alrededor del eje Z ).

Figura:Rotación alrededor del eje 
\begin{figure}\centerline{\epsfig{file=img/nulo.ps, width=1, height=1}}
\end{figure}
 Z
























jueves, 1 de marzo de 2012

Proyección ortogonal y proyección en perspectiva

Proyección ortogonal

Una proyección ortogonal es cuadrada en todas sus caras. Esto produce una proyección paralela, útil para aplicaciones de tipo CAD o dibujos arquitectónicos, o también para tomar medidas, ya que las dimensiones de lo que representan no se ven alteradas por la proyección.

Una aproximación menos técnica pero mas comprensible de esta proyección es imaginar que se tiene un objeto fabricado con un material deformable, y se aplasta literalmente como una pared. Se obtendría el mismo objeto, pero plano, liso. Pues eso es lo que se vería por pantalla.

Para definir la matriz de proyección ortográfica y multiplicarla por la matriz activa (que debería ser en ese momento la de proyección, GL_PROJECTION), se utiliza la función glOrtho, que se define de la siguiente forma:

glOrtho(limiteIzquierdo, limiteDerecho, limiteAbajo, limiteArriba, znear, zfar)

siendo todos flotantes. Los valores de znear y zfar no son las posiciones de esos planos en el espacio 3D. Representan la distancia desde el centro de proyección, con valor positivo hacia delante y negativo hacia atrás. Con esto simplemente se acota lo que será el volumen de visualización (un cubo).

Por ejemplo, la ilustración 4.5 es un render de un coche con proyección ortográfica, visto desde delante.


Ilustración 4 .5

  El código utilizado para esta proyección ha sido
glOrtho(-0.5f, 0.5f, -0.5f, 0.5f, 0.01f, 20.0f


  Proyecciones perspectivas

Una proyección en perspectiva reduce y estirar los objetos más alejados del observador. Es importante saber que las medidas de la proyección de un objeto no tienen por qué coincidir con las del objeto real, ya que han sido deformadas.
El volumen de visualización creado por una perspectiva se llama frustum. Un frustum es una sección piramidal, vista desde la parte afilada hasta la base (ilustración 4.6).

Ilustración 4 .6
Se puede definir esta proyección utilizando la función glFrustum. Pero existe otra función de la librería GLU llamada gluPerspective que hace el proceso más sencillo. Se define de la siguiente forma:
Void gluPerspective(angulo, aspecto, znear, zfar);
Los parámetros de gluPerspective son flotantes y definen las características mostradas en la ilustración 4.7, el ángulo para el campo de visión en sentido vertical, el aspecto que es la relación entre la altura (h) y la anchura (w) y las distancias znear y zfar de los planos que acotan el fustrum al observador. Los valores de znear y zfar no son las posiciones de esos planos en el espacio 3D, representan la distancia desde el centro de proyección, con valor positivo hacia delante y negativo hacia atrás.

Ilustración 4 .7
La ilustración 4.8 muestra la escena del coche de la sección anterior, esta vez con una proyección en perspectiva:

Ilustración 4 .8
El código utilizado para definir la proyección ha sido:
gluPerspective(45.0f,(GLfloat)(width/height),0.01f,100.0f);
Se usan 45º de ángulo, la relación entre el ancho y alto de la pantalla (width y height son el ancho y alto actual de la ventana) y las distancias a los planos de corte znear y zfar son 0.01 y 100 respectivamente.
 CODIGOS
La escena consiste en un cubo de colores girando sobre si mismo y una esfera blanca de alambre

#include <GL/glut.h>
 
GLfloat anguloCuboX = 0.0f;GLfloat anguloCuboY = 0.0f;GLfloat anguloEsfera = 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 drawCube(void){    glColor3f(1.0f, 0.0f, 0.0f);    glBegin(GL_QUADS);       //cara frontal    glVertex3f(-1.0f, -1.0f,  1.0f);    glVertex3f( 1.0f, -1.0f,  1.0f);    glVertex3f( 1.0f,  1.0f,  1.0f);    glVertex3f(-1.0f,  1.0f,  1.0f);

    glEnd();    glColor3f(0.0f, 1.0f, 0.0f);

    glBegin(GL_QUADS);       //cara trasera
    glVertex3f( 1.0f, -1.0f, -1.0f);
    glVertex3f(-1.0f, -1.0f, -1.0f);    glVertex3f(-1.0f,  1.0f, -1.0f);    glVertex3f( 1.0f,  1.0f, -1.0f);

    glEnd();    glColor3f(0.0f, 0.0f, 1.0f);    glBegin(GL_QUADS);       //cara lateral izq    glVertex3f(-1.0f,-1.0f, -1.0f);    glVertex3f(-1.0f,-1.0f,  1.0f);    glVertex3f(-1.0f, 1.0f,  1.0f);    glVertex3f(-1.0f, 1.0f, -1.0f);    glEnd();    glColor3f(1.0f, 1.0f, 0.0f);    glBegin(GL_QUADS);       //cara lateral dcha    glVertex3f(1.0f, -1.0f,  1.0f);    glVertex3f(1.0f, -1.0f, -1.0f);    glVertex3f(1.0f,  1.0f, -1.0f);    glVertex3f(1.0f,  1.0f,  1.0f);    glEnd(); 
    glColor3f(0.0f,      1.0f, 1.0f);    glBegin(GL_QUADS);       //cara arriba    glVertex3f(-1.0f, 1.0f,  1.0f);    glVertex3f( 1.0f, 1.0f,  1.0f);    glVertex3f( 1.0f, 1.0f, -1.0f);    glVertex3f(-1.0f, 1.0f, -1.0f);    glEnd();     glColor3f(1.0f, 0.0f, 1.0f);    glBegin(GL_QUADS);       //cara abajo
    glVertex3f( 1.0f,-1.0f, -1.0f);
    glVertex3f( 1.0f,-1.0f,  1.0f);    glVertex3f(-1.0f,-1.0f,  1.0f);    glVertex3f(-1.0f,-1.0f, -1.0f);    glEnd();}void display(){    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     glLoadIdentity();     glTranslatef(0.0f, 0.0f, -5.0f);     glRotatef(anguloCuboX, 1.0f, 0.0f, 0.0f);    glRotatef(anguloCuboY, 0.0f, 1.0f, 0.0f);     drawCube();     glLoadIdentity();     glTranslatef(0.0f, 0.0f, -5.0f);    glRotatef(anguloEsfera, 0.0f, 1.0f, 0.0f);    glTranslatef(3.0f, 0.0f, 0.0f);     glColor3f(1.0f, 1.0f, 1.0f);    glutWireSphere(0.5f, 8, 8);     glFlush();    glutSwapBuffers();     anguloCuboX+=0.1f;    anguloCuboY+=0.1f;    anguloEsfera+=0.2f;}void init(){    glClearColor(0,0,0,0);    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 27:   // escape      exit(0);      break;    }} int main(int argc, char **argv){    glutInit(&argc, argv);    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);    glutInitWindowPosition(100, 100);    glutInitWindowSize(ancho, alto);    glutCreateWindow("Cubo 1");    init();    glutDisplayFunc(display);    glutReshapeFunc(reshape);    glutIdleFunc(idle);    glutKeyboardFunc(keyboard);    glutMainLoop();    return 0;
}

Segundo codigo

// Le digo a OpenGL que voy a cambiar la matriz de proyeccion
glMatrixMode(GL_PROJECTION);
// Le digo a OpenGL que use proyeccion perspectiva. Uso el ancho
// y alto de mi viewport para calcular el segundo parametro
gluPerspective(60.0f, (float)rect.right/(float)rect.bottom, 0.5f, 50.0f);

// Muevo para atras el objeto. El punto de vista esta 
// en la posicion 0,0,0 porque no lo he cambiado, asi que 
// alejo el objeto para poder verlo.
glTranslatef(0,0,-4.0f);
// Giro el objeto 30 grados en el eje x, luego otros
// 30 en el eje y. Es para que quede bonito.
glRotatef(30,1,0,0);
glRotatef(30,0,1,0);
// y pinto el objeto con coordenadas genericas alrededor
// del eje de coordenadas. Estas coordenadas que pongo
// ahora son modificadas por las modificaciones que
// hemos hecho en la matriz modelview (glTranslate, glRotate).
 
// Le digo a OpenGL que voy a pintar y con cuadrados:
glBegin(GL_QUADS); 
// Cara de arriba
glColor3f(1,0,0); // rojo
glVertex3f( 1.0f, 1.0f,-1.0f);    
glVertex3f(-1.0f, 1.0f,-1.0f);    
glVertex3f(-1.0f, 1.0f, 1.0f);    
glVertex3f( 1.0f, 1.0f, 1.0f);    
// Cara de abajo
glColor3f(1,0,0); // rojo
glVertex3f( 1.0f,-1.0f, 1.0f);    
glVertex3f(-1.0f,-1.0f, 1.0f);    
glVertex3f(-1.0f,-1.0f,-1.0f);    
glVertex3f( 1.0f,-1.0f,-1.0f);    
// Cara frontal
glColor3f(0,0,1); // azul
glVertex3f( 1.0f, 1.0f, 1.0f);    
glVertex3f(-1.0f, 1.0f, 1.0f);    
glVertex3f(-1.0f,-1.0f, 1.0f);    
glVertex3f( 1.0f,-1.0f, 1.0f); 
// Cara trasera
glColor3f(0,0,1); // azul
glVertex3f( 1.0f,-1.0f,-1.0f);    
glVertex3f(-1.0f,-1.0f,-1.0f);    
glVertex3f(-1.0f, 1.0f,-1.0f);    
glVertex3f( 1.0f, 1.0f,-1.0f);
// Cara izquierda
glColor3f(0,1,0); // verde
glVertex3f(-1.0f, 1.0f, 1.0f);    
glVertex3f(-1.0f, 1.0f,-1.0f);    
glVertex3f(-1.0f,-1.0f,-1.0f);    
glVertex3f(-1.0f,-1.0f, 1.0f); 
// Cara derecha
glColor3f(0,1,0); // verde
glVertex3f( 1.0f, 1.0f,-1.0f);    
glVertex3f( 1.0f, 1.0f, 1.0f);    
glVertex3f( 1.0f,-1.0f, 1.0f);    
glVertex3f( 1.0f,-1.0f,-1.0f); 
glEnd();
Compilamos, ejecutamos y si tenemos suerte veremos esto: Como siempre sugiero cambiar parametros, funciones, ... para experimentar.


jueves, 23 de febrero de 2012

Transformaciones geometricas

Transformaciones geométricas
Habitualmente, un paquete grafico permite al usuario especificar que parte de una imagen definida se debe visualizar y donde esta parte se debe colocar en el dispositivo de visualización. Cualquier sistema de coordenadas que sea conveniente, referido al sistema de referencia de coordenadas del mundo, se puede usar para definir la imagen.
Transformaciones bidimensionales
Traslación
Se aplica una traslación en un objeto para cambiar su posición a lo largo de la trayectoria de una línea recta de una dirección de coordenadas a otra. Convertimos un punto bidimensional al agregar las distancias de traslación. En ocasiones, las ecuaciones de transformación matricial se expresan en términos de vectores de renglón de coordenadas en vez de vectores de columna.
La traslación es una transformación de cuerpo rígido que mueve objetos sin deformarlos, es decir, se traslada cada punto del objeto la misma distancia.
Rotación
Se aplica una rotación bidimensional en un objeto al cambiar su posición a lo largo de la trayectoria de una  en el plano circunferencia en el plano xy, para generar una rotación, especificamos un ángulo de rotación θ y la posición (x,y) del punto de rotación( o punto pivote) en torno al cual se gira el objeto.


Coordenadas homogéneas


En matemáticas, y más concretamente en geometría proyectiva, las coordenadas homogéneas son un instrumento usado para describir un punto en el espacio proyectivo. Fueron introducidas por el matemático alemán August Ferdinand Möbius en el año 1837.
También pueden usarse como un sistema alternativo de coordenadas para trabajar en el espacio euclídeo, pues éste puede verse como un subconjunto del espacio proyectivo. De ese modo, las coordenadas homogéneas son ampliamente usadas en infografía para la representación de escenas en tres dimensiones. Su notación en forma matricial se emplea en bibliotecas de programación gráfica en 3D como OpenGL y Direct3D.

En coordenadas homogéneas, todo punto bidimensional está definido por tres coordenadas. De tal modo que un punto de dimensiones xy, se lo representa por la terna: x / wy / ww.
Matemáticamente, las coordenadas x y y se hallan dividiendo los dos primeros números entre el tercero, respectivamente.
En dos dimensiones, su valor se puede encontrar más fácilmente si w = 1, por simplificación. En tres dimensiones, suele ocurrir lo mismo w = 1.
Básicamente, se trata de ampliar el plano euclídeo (en el caso bidimensional) al plano proyectivo, es decir, incluirle los puntos impropios o del infinito.
Así, un punto impropio es aquel donde w = 0.
Una consecuencia de esta escritura es que un punto propio tiene infinitas formas de escribirlo, todo dependerá de los cocientes x / w y y / w (con w distinto de 0).
Pila
Una pila (stack en inglés) es una lista ordinal o estructura de datos en la que el modo de acceso a sus elementos es de tipo LIFO (del inglés Last In First Out, último en entrar, primero en salir) que permite almacenar y recuperar datos. Esta estructura se aplica en multitud de ocasiones en el área de informática debido a su simplicidad y ordenación implícita de la propia estructura.
Para el manejo de los datos se cuenta con dos operaciones básicas: apilar (push), que coloca un objeto en la pila, y su operación inversa, retirar (o desapilar, pop), que retira el último elemento apilado.
En cada momento sólo se tiene acceso a la parte superior de la pila, es decir, al último objeto apilado (denominado TOS, Top of Stacken inglés). La operación retirar permite la obtención de este elemento, que es retirado de la pila permitiendo el acceso al siguiente (apilado con anterioridad), que pasa a ser el nuevo TOS.
Por analogía con objetos cotidianos, una operación apilar equivaldría a colocar un plato sobre una pila de platos, y una operación retirara retirarlo.
Las pilas suelen emplearse en los siguientes contextos:
  • Evaluación de expresiones en notación postfija (notación polaca inversa).
  • Reconocedores sintácticos de lenguajes independientes del contexto
  • Implementación de recursividad.

Operaciones

Una pila cuenta con 2 operaciones imprescindibles: apilar y desapilar, a las que en las implementaciones modernas de las pilas se suelen añadir más de uso habitual.
  • Crear: se crea la pila vacía (size).
  • Apilar: se añade un elemento a la pila.(push)
  • Desapilar: se elimina el elemento frontal de la pila.(pop)
  • Cima: devuelve el elemento que esta en la cima de la pila. (top o peek)
  • Vacía: devuelve cierto si la pila está vacía o falso en caso contrario (empty).



martes, 21 de febrero de 2012

CUBO 2D

#include <GL/glut.h>
void display(void)
{       
  typedef GLfloat point2[2];
  point2 vertice[8] = {
  {50.0,50.0},   
  {150.0,50.0},   
  {150.0,150.0},   
  {50.0,150.0},   
  {200.0,100.0},   
  {200.0,200.0},   
  {100.0,200.0},   
  {100.0,100.0}};  
 
         glColor3f(1.0,0.0,0.0);
                gluOrtho2D(0.0, 500.0, 0.0, 500.0);
 glClear(GL_COLOR_BUFFER_BIT);
  glBegin(GL_LINES);
  glVertex2fv(vertice[0]);
  glVertex2fv(vertice[1]);
  glVertex2fv(vertice[1]);
  glVertex2fv(vertice[2]);
  glVertex2fv(vertice[2]);
  glVertex2fv(vertice[3]);
  glVertex2fv(vertice[3]);
  glVertex2fv(vertice[0]);
  glVertex2fv(vertice[1]);
  glVertex2fv(vertice[4]);
  glVertex2fv(vertice[2]);
  glVertex2fv(vertice[5]);
  glVertex2fv(vertice[5]);
  glVertex2fv(vertice[4]);
  glVertex2fv(vertice[5]);
  glVertex2fv(vertice[6]);
  glVertex2fv(vertice[6]);
  glVertex2fv(vertice[3]);
  glVertex2fv(vertice[0]);
  glVertex2fv(vertice[7]);
  glVertex2fv(vertice[4]);
  glVertex2fv(vertice[7]);
  glVertex2fv(vertice[6]);
  glVertex2fv(vertice[7]);
  glEnd();
        glFlush();
}
void main(int argc, char** argv)
{
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
        glutInitWindowSize(500, 500);
     
        glutCreateWindow("Cubo en 2D");
        glutDisplayFunc(display);
 
        glutMainLoop();      
}
Algoritmo DDA para generación de líneas
Como todos saben Open GL es una herramienta que nos facilita mucho la generación de gráficos por computadora. Aqui aplicamos conocimientos matemáticos, usando Open GL para generar rectas, corcunferencias, elipses, etc.
1.1 DDA:
El Algoritmo DDA es un algoritmo de línea de conversión de rastreo que se basa en el cálculo ya sea en el incremento de X o en el incremento de Y. La finalidad de este algoritmo es determinar los valores enteros correspondientes más próximos a la trayectoria de la línea para la otra coordenada.

Código:
void DDA(int x0,int y0,int xFin,int yFin)
{
int dx = xFin - x0, dy = yFin - y0, steps, k;
float xIncremento, yIncremento;
float x = x0, y = y0;
if (fabs (dx) > fabs (dy))
steps = fabs (dx); /* |m|<1>
else
steps = fabs (dy); /* |m|>=1 */
xIncremento=float(dx)/float (steps);
yIncrement = float (dy) / float (steps);
setPixel (round (x), round (y));
for (k = 0; k <>
{
x += xIncremento;
y += yIncremento;
setPixel (round (x), round (y));
}
}
BRESENHAM:

El algoritmo de Bresenham sirve para trazar una línea entre dos puntos.


Código:

void Bres(int x0,int y0,int xFin,int yFin)
{
int dx = fabs(xFin - x0),
dy = fabs(yFin - y0);
int p = 2 * dy - dx;
int dosDy = 2 * dy,
dosDyMenosDx = 2 * (dy - dx);
int x, y;
/* Determinamos que punto usamos como inicio. */
if (x0 > xFin) {
x = xFin;
y = yFin;
xFin = x0;
}
else {
x = x0;
y = y0;
}
setPixel (x, y);
while (x <>
x++;
if (p <>
p += dosDy;
else {
y++;
p += dosDyMenosDx;
}
setPixel (x, y);
}
}

miércoles, 15 de febrero de 2012

Ejecutables

Este ejemplo muestra un fractal que dibuja un árbol con la letra T




Este ejemplo muestra un fractal que dibuja un helecho.



Este ejemplo dibuja un fractal por medio de triangulos.


Este ejemplo dibuja un fractal llamado Hilbert.



Este ejemplo dibuja un fractal por medio de cuadrados.


Este ejemplo dibuja un fractal por medio de curvas.



Este ejemplo dibuja un Fractal llamado Galactic, utiliza MFC.


Este ejemplo dibuja un fractal llamado Julia, utiliza MFC.


Este ejemplo dibuja el fractal de Mandelbrot, utiliza MFC.