domingo, 10 de noviembre de 2013

PROGRAMA 3D.



Para la visualización de un objeto 3D, se requieren 3 pasos:


En primer lugar se necesita una base de datos con las coordenadas (x,y,z) de los vértices y ademas los polígonos que forman el objeto.
En segundo lugar el objeto primero se rota y luego se traslada hasta la localización adecuada, con lo que se obtienen unas nuevas coordenadas (x,y,z) para los vértices.
Finalmente, se eliminan los polígonos que no son visibles por el observador, se aplica la perspectiva y se dibuja el objeto en la pantalla.

Base de Datos del Objeto 3D

Mi objeto esta compuesto por polígonos de tres lados, y cada poligono tiene 3 vértices cuyas coordenadas son (x,y,z).


Número máximo de vértices que puede tener el objeto

#define NUM_VERTICES

Cantidad máxima de polígonos que tiene el objeto


#define NUM_FACES


Definición de un vértice

typedef struct VTX


{
double x, y, z;
};

Definición de un polígono
typedef struct TRI
{
int a, b, c;
};


Estructura para el ordenamiento qsort, donde para cada polígono

almaceno la cordenada z y el indice del polígono
d=coordenada z del poligono, index=indice del polígono
typedef struct LSTR
{
int d;
int index;
};

Tabla que contiene los vértices originales
VTX points[NUM_VERTICES];
Tabla con los vértices transformados
VTX outpoints[NUM_VERTICES];
Tabla que contiene los polígonos
TRI faces[NUM_FACES];
Tabla de polígonos para aplicar el ordenamiento qsort
LSTRI ListFaces[NUM_FACES];
Número de vértices, y polígonos del objeto
int vertices, poligonos;

Vértices del objeto

V0 = points[0].x, points[0].y, points[0].z
V1 = points[1].x, points[1].y, points[1].z
V7 = points[7].x, points[7].y, points[7].z

Polígonos del objeto
faces[0].a = 0 faces[0].b = 2 faces[0].c = 1
faces[1].a = 2 faces[1].b = 3 faces[1].c = 1
faces[5].a = 6 faces[5].b = 7 faces[5].c = 5

Matrices de Transformación 3D
Sistema de Coordenadas


El sistema de coordenadas tridimensional utilizado es el llamado de la mano izquierda

Rotación en torno al eje X



Código en C

void matriz_rotacion_x(MATRIZ *m, double angulo)
{
double tmpsin, tmpcos;
tmpsin=sin(angulo);
tmpcos=cos(angulo);
*m = matriz_identidad;
m->v[1][1] = tmpcos;
m->v[1][2] = tmpsin;
m->v[2][1] = -tmpsin;
m->v[2][2] = tmpcos;
}

Ejemplo: matriz_rotacion_x(&Rx, 0.7)
Esto crea la matriz de rotación alrededor del eje X, donde Rx es una matriz 4x4 y 0.7 es el angulo de rotación, en radianes.

Rotación en torno al eje Y


Código en C.
void matriz_rotacion_y(MATRIZ *m, double angulo)
{
double tmpsin, tmpcos;
tmpsin=sin(angulo);
tmpcos=cos(angulo);
*m = matriz_identidad;
m->v[0][0] = tmpcos;
m->v[0][2] = -tmpsin;
m->v[2][0] = tmpsin;
m->v[2][2] = tmpcos;
}

Rotación en torno al eje Z


Código en C
void matriz_rotacion_z(MATRIZ *m, double angulo)
{
double tmpsin, tmpcos;
tmpsin=sin(angulo);
tmpcos=cos(angulo);
*m = matriz_identidad;
m->v[0][0] = tmpcos;
m->v[0][1] = tmpsin;
m->v[1][0] = -tmpsin;
m->v[1][1] = tmpcos;
}


Ejemplo : matriz_rotacion_z(&Rz, 0.7)
donde Rz es la matriz de 4x4, y 0.7 es el angulo de rotación en torno al eje Z.


Traslación


Código en C

void matriz_traslacion(MATRIZ *m, double Tx, double Ty, double Tz)
{
*m = matriz_identidad;
m->v[3][0] = Tx;
m->v[3][1] = Ty;
m->v[3][2] = Tz;
}


ESTRUCTURA DE TODO EL PROGRAMA.

#include <graphics.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include "svga256.h"

#define NUM_VERTICES 512
#define NUM_FACES 1024

typedef struct MATRIZ
{
double v[4][4];
};

typedef struct VTX
{
double x, y, z;
};

typedef struct TRI
{
int a, b, c;
};

typedef struct LSTRI
{
int d;
int index;
};

VTX points[NUM_VERTICES];
VTX outpoints[NUM_VERTICES];
TRI faces[NUM_FACES];
LSTRI ListFaces[NUM_FACES];
int vertices, poligonos;
//posicion de la fuente de luz
double xlight=1.0, ylight=-1.0, zlight=1.0;
unsigned char paleta[256][3];

MATRIZ matriz_identidad = {
{
{ 1.0, 0.0, 0.0, 0.0},
{ 0.0, 1.0, 0.0, 0.0},
{ 0.0, 0.0, 1.0, 0.0},
{ 0.0, 0.0, 0.0, 1.0}
}
};

double persp_xoffset;
double persp_yoffset;
double D;

int huge deteccion()
{
int modo;

clrscr();
printf("Selecciona un modo de video...\n");
printf(" 0) 320x200x256 VGA\n");
printf(" 1) 640x400x256 SVGA\n");
printf(" 2) 640x480x256 SVGA\n");
printf(" 3) 800x600x256 SVGA\n");
printf(" 4) 1024x768x256 SVGA\n\n>");
scanf("%d", &modo);
return modo;
}

void aplicar_matriz(MATRIZ *m, double x, double y, double z, double *xout, double *yout, double *zout)
{
*xout = x*m->v[0][0] + y*m->v[1][0] + z*m->v[2][0] + 1.0*m->v[3][0];
*yout = x*m->v[0][1] + y*m->v[1][1] + z*m->v[2][1] + 1.0*m->v[3][1];
*zout = x*m->v[0][2] + y*m->v[1][2] + z*m->v[2][2] + 1.0*m->v[3][2];
}

void matriz_multiplicacion(MATRIZ *m1, MATRIZ *m2, MATRIZ *out)
{
int i, j, k;

for (i=0; i<4; i++) {
for (j=0; j<4; j++) {
out->v[i][j] = 0.0;
for (k=0; k<4; k++)
out->v[i][j] = out->v[i][j] + m1->v[i][k]*m2->v[k][j];
}
}
}

void matriz_traslacion(MATRIZ *m, double Tx, double Ty, double Tz)
{
*m = matriz_identidad;
m->v[3][0] = Tx;
m->v[3][1] = Ty;
m->v[3][2] = Tz;
}

void matriz_escalamiento(MATRIZ *m, double Ex, double Ey, double Ez)
{
*m = matriz_identidad;
m->v[0][0] = Ex;
m->v[1][1] = Ey;
m->v[2][2] = Ez;
}

void matriz_rotacion_x(MATRIZ *m, double angulo)
{
double tmpsin, tmpcos;

tmpsin=sin(angulo);
tmpcos=cos(angulo);
*m = matriz_identidad;
m->v[1][1] = tmpcos;
m->v[1][2] = tmpsin;
m->v[2][1] = -tmpsin;
m->v[2][2] = tmpcos;
}

void matriz_rotacion_y(MATRIZ *m, double angulo)
{
double tmpsin, tmpcos;

tmpsin=sin(angulo);
tmpcos=cos(angulo);
*m = matriz_identidad;
m->v[0][0] = tmpcos;
m->v[0][2] = -tmpsin;
m->v[2][0] = tmpsin;
m->v[2][2] = tmpcos;
}

void matriz_rotacion_z(MATRIZ *m, double angulo)
{
double tmpsin, tmpcos;

tmpsin=sin(angulo);
tmpcos=cos(angulo);
*m = matriz_identidad;
m->v[0][0] = tmpcos;
m->v[0][1] = tmpsin;
m->v[1][0] = -tmpsin;
m->v[1][1] = tmpcos;
}

void persp_projeccion(double x, double y, double z, double *xout, double *yout)
{
double z1 = 1.0 / z;
*xout = ((x * z1) * D) + persp_xoffset;
*yout = ((y * z1) * D) + persp_yoffset;
}

void set_projeccion_viewport(int w, int h)
{
D = 800;
persp_xoffset = w/2;
persp_yoffset = h/2;
}

void ver_matriz(MATRIZ *m)
{
printf("%lf %lf %lf %lf\n", m->v[0][0], m->v[0][1], m->v[0][2], m->v[0][3]);
printf("%lf %lf %lf %lf\n", m->v[1][0], m->v[1][1], m->v[1][2], m->v[1][3]);
printf("%lf %lf %lf %lf\n", m->v[2][0], m->v[2][1], m->v[2][2], m->v[2][3]);
printf("%lf %lf %lf %lf\n", m->v[3][0], m->v[3][1], m->v[3][2], m->v[3][3]);
}

double producto_escalar(double x1, double y1, double z1, double x2, double y2, double z2)
{
return ((x1 * x2) + (y1 * y2) + (z1 * z2));
}

void producto_vectorial(VTX v1, VTX v2, VTX *out)
{
out->x = (v1.y * v2.z) - (v1.z * v2.y);
out->y = (v1.z * v2.x) - (v1.x * v2.z);
out->z = (v1.x * v2.y) - (v1.y * v2.x);
}

double modulo_vector(double x, double y, double z)
{
return sqrt(x*x + y*y + z*z);
}

void vector_normalizado(double *x, double *y, double *z)
{
double length = 1.0 / modulo_vector(*x, *y, *z);

*x *= length;
*y *= length;
*z *= length;
}

//Esta funcion permite conocer si un poligono esta de cara
//o de espaldas al observador, segun devuelva un valor mayor
//o menor que cero
double Hidden(VTX v1, VTX v2, VTX v3)
{
VTX u, v;
VTX out;
double xout, yout, zout;
double temp;

u.x = v2.x - v1.x;
u.y = v2.y - v1.y;
u.z = v2.z - v1.z;
v.x = v3.x - v1.x;
v.y = v3.y - v1.y;
v.z = v3.z - v1.z;
producto_vectorial(u, v, &out);
temp = producto_escalar(out.x, out.y, out.z, 0.0, 0.0, -1.0);
return temp;
}

//funcion usada para calcular el nivel de intensidad de la
//luz que recibe un poligono
int Light(VTX v1, VTX v2, VTX v3)
{
VTX u, v, out;
double temp;

u.x = v2.x - v1.x;
u.y = v2.y - v1.y;
u.z = v2.z - v1.z;
v.x = v3.x - v1.x;
v.y = v3.y - v1.y;
v.z = v3.z - v1.z;
//out es el vector normal al poligono
producto_vectorial(u, v, &out);
vector_normalizado(&out.x, &out.y, &out.z);
vector_normalizado(&xlight, &ylight, &zlight);
//El resultado de todas estas operaciones dar un valor comprendido
//entre 0.0 (m¡nima luz) y 1.0f (m xima luz)
temp = producto_escalar(out.x, out.y, out.z, xlight, ylight, zlight);
temp = 256.0*temp;
if (temp<0.0)
temp=0.0;
else
if (temp>255.0)
temp=255.0;
return (int) (temp);
}

//me dibuja un poligono solido, el color lo determino
//de acuerdo al nivel de luz que recibe.
void DibujarPoligono(int num)
{
int A, B, C;
int poly[6];
int i, color;

i=ListFaces[num].index;
A=faces[i].a;
B=faces[i].b;
C=faces[i].c;
//verifico si el poligono es visible o no
if (Hidden(outpoints[A], outpoints[B], outpoints[C])<0.0)
{
//se llama a la funci¢n que calcula la luz de un pol¡gono
color = Light(outpoints[A], outpoints[B], outpoints[C]);
poly[0]=(int) outpoints[A].x;
poly[1]=(int) outpoints[A].y;
poly[2]=(int) outpoints[B].x;
poly[3]=(int) outpoints[B].y;
poly[4]=(int) outpoints[C].x;
poly[5]=(int) outpoints[C].y;
setfillstyle(SOLID_FILL, color);
setcolor(color);
fillpoly(3, poly);
}
}

int comparar(const void * e1, const void * e2)
{
int d1, d2;

LSTRI *q1 = (LSTRI *)e1;
LSTRI *q2 = (LSTRI *)e2;

d1=q1->d;
d2=q2->d;
return (d2-d1);
}

void setvgapalette256(DacPalette256 *PalBuf)
{
struct REGPACK reg;

reg.r_ax = 0x1012;
reg.r_bx = 0;
reg.r_cx = 256;
reg.r_es = FP_SEG(PalBuf);
reg.r_dx = FP_OFF(PalBuf);
intr(0x10,®);
}

void LeerObjeto(char *nombre)
{
int i;

FILE *in = fopen(nombre, "r");
if (!in)
return;
fscanf(in, "%d\n", &vertices);
//printf("%d\n", vertices);
for (i = 0; i<vertices; i++)
{
fscanf(in, "%lf %lf %lf\n", &points[i].x, &points[i].y, &points[i].z);
//printf("%lf %lf %lf\n", points[i].x, points[i].y, points[i].z);
};
fscanf(in, "%d\n", &poligonos);
//printf("%d\n", poligonos);
for (i = 0; i<poligonos; i++)
{
fscanf(in, "%d %d %d\n", &faces[i].a, &faces[i].b, &faces[i].c);
//printf("%d %d %d\n", faces[i].a, faces[i].b, faces[i].c);
}
//printf("Presionar una tecla para continuar...");
//getch();
fclose(in);
}

int main(void)
{
MATRIZ Rx, Ry, Rz, Rot;
MATRIZ Tr, Mat;
MATRIZ temp;
int i;


//Carga el modelo en memoria
LeerObjeto("toro.dat");

//Inicializa el modo grafico
int driver = DETECT, modo = DETECT;
installuserdriver("Svga256", deteccion);
initgraph(&driver, &modo, "");

for (i=0; i<256; i++)
{
paleta[i][0]=i/4;
paleta[i][1]=i/4;
paleta[i][2]=i/4;
}

//me cambia la paleta de colores a una escala de 64 tonos de grises
setvgapalette256(&paleta);

for (i=0; i<256; i++)
{
setcolor(i);
line(i,0,i,20);
};

set_projeccion_viewport(getmaxx(), getmaxy());

//Inicializa las matrices de rotacion y
//traslacion.
matriz_rotacion_x(&Rx, -0.785);
matriz_rotacion_y(&Ry, 0.523);
matriz_rotacion_z(&Rz, 0.0);
matriz_traslacion(&Tr, 0.0, 0.0, -350.0);
//multiplica las matrices
//Mat=Rx*Ry*Rz*Tr (matriz de transformacion)
matriz_multiplicacion(&Rx, &Ry, &temp);
matriz_multiplicacion(&temp, &Rz, &Rot);
matriz_multiplicacion(&Rot, &Tr, &Mat);
//aplica la matriz de transformacion a cada uno
//de los vertices del modelo.
for (i=0; i<vertices; i++)
{
aplicar_matriz(&Mat, points[i].x, points[i].y, points[i].z,
&outpoints[i].x, &outpoints[i].y, &outpoints[i].z);
persp_projeccion(outpoints[i].x, outpoints[i].y, outpoints[i].z,
&outpoints[i].x, &outpoints[i].y);
};
//construyo una tabla con las coordenadas z, de cada uno
//de los poligonos.
for (i=0; i<poligonos; i++)
{
ListFaces[i].d = (int) fabs(outpoints[faces[i].a].z + outpoints[faces[i].b].z + outpoints[faces[i].c].z);
ListFaces[i].index=i;
}
//ordeno los poligonos de acuerdo a z.
qsort(ListFaces, poligonos, sizeof(ListFaces[0]), comparar);

//dibujo los poligonos
for (i=0; i<poligonos; i++)
DibujarPoligono(i);

getch();
closegraph();
return 0;
}





CONCLUSIÓN.

Gracias a las diferentes técnicas que vimos con respecto a los polígonos nosotros podemos lograr a través de estos que nuestros gráficos adquieran un mayor efecto de realismo. Y vemos que la iluminación y sombreado toman como características principales de la visibilidad, pero por otra parte hay otras características que influyen como el acabado del objeto, la transmisión de luz. Distintas combinaciones de estos factores pueden dar lugar a una infinita variedad de distintos enfoques, que harán que nuestros objetos se vean mejor.

2 DE NOVIEMBRE.


La Conmemoración de los Fieles Difuntos, popularmente llamada Día de Muertos o Día de Difuntos, es una celebración que tiene lugar el día  2 de noviembre, cuyo objetivo es orar por aquellos fieles que han acabado su vida terrenal y, especialmente, por aquellos que se encuentran aún en estado de purificación en el purgatorio.

En México más que una festividad Cristiana es una celebración donde se mezclan tanto la cultura prehispánica como la religión católica, donde el pueblo Mexicano logró mantener sus antiguas tradiciones vivas.

Los mexicanos somos una cultura que se diferencia de las demás porque transformamos a la muerte en algo familiar y cotidiano. En la celebración del Día de Muertos jugamos con la muerte, se la hacen corridos y se le demuestra un profundo respeto.

Los días 1 y 2 de noviembre, la gran mayoría de los habitantes del país realizan altares a sus muertos, comparten con ellos alimentos, adornan las tumbas, queman copal, entre muchas otras cosas.

Antiguamente se creía que los muertos necesitaban comida para llegar a su destino final, por lo que al morir se dejaba junto a ellos alimentos, agua, ofrendas y diversos objetos.

Esta tradición se mezcló y adaptó al calendario cristiano en los días 1 y 2 de noviembre.

El 1 de noviembre es Todos los Santos dedicado a los niños difuntos y el día 2 a los difuntos mayores. Se cree que en estos días los difuntos regresan a visitar a sus seres queridos.

Para el día 1º de noviembre se ponen ofrendas y altares a los “angelitos”, o muertos chiquitos que han dejado el mundo de los vivos.

 
Conclusión:

Hoy, al igual que en tiempos prehispánicos, se lleva a cabo esta celebración de manera festiva, es muy tradicional porque toda la gente lo hace para un ser querido que haya perdido, así le pones un altar y lo recuerdas de una manera muy bonita.

 



Bibliografía.



http://www.presidencia.gob.mx/elfuturodemexico/sabes-que-se-celebra-el-1-y-2-de-noviembre/

http://es.wikipedia.org/wiki/Conmemoraci%C3%B3n_de_los_Fieles_Difuntos

http://www.sanmiguelguide.com/dia-de-muertos.htm

 


TÉCNICAS DE SOMBREADO.

Sombreado constante.
 
Aplica una sola vez un modelo de iluminación para todo el polígono. Está simplificación sirve si: 
 
  •  La fuente luminosa está en el infinito, por tanto nl es constante.
  • El observador está en el infinito, por tanto nv es constante en toda la cara del polígono.
  • El polígono representa la superficie real que se modela y no es una aproximación a una superficie curva.
  • Si las suposiciones son incorrectas, entonces hay un método para determinar l y v.
 
Sombreado interpolado.
 
En lugar de evaluar la ecuación de iluminación para cada pixel, esta se interpola linealmente sobre un triángulo a partir de los valores determinados para sus vértices. Se puede generalizar para otro tipo de polígonos.
 
A su vez, en lugar de realizar la interpolación para cada píxel, se puede hallar una ecuación de diferencia.
 
Esta interpolación no evita la apariencia facetada. Según el objeto a modelar, esto es positivo o no.
 
Sombreado de malla poligonal.
 
Una superficie curva se puede aproximar a otra facetada (malla poligonal) no se logran buenos resultados en la interpolación, aunque se trabaje con una densidad alta de polígonos.
 
 
 
 
Sombreado de malla poligonal.
 
Los problemas en la visualización de una superficie curva a través de una aproximación facetada, tienen su origen en el efecto de banda de mach.
 
 
 
 
 
Esquema de las intensidades reales y las percibidas.
 
  
 
 
Sombreado de Gouraud.
 
Este esquema de interpolación de intensidad, creado por gouraud, elimina discontinuidades en intensidades entre planos adyacentes de la representación de una superficie variando en forma lineal la intensidad sobre cada plano de manera que lo valores de la intensidad concuerden en las fronteras del plano. en este método los valores de la intensidad a lo largo de cada línea de rastreo que atraviesan una superficie se interpolan a partir de las intensidades en los puntos de intersección de con la superficie.
 
 
 
 
Sombreado de Phong.
 
En lugar de interpolar la intensidad del vértice (gouraud), se interpola y normaliza la normal a los vértices.
 
Si se utiliza sombreado de phong con n alto, la diferencia entre phong y gouraud puede llegar a ser notable. Normalizar un vector es costoso, y aplicar un modelo de iluminación a cada pixel también puede serlo.
 
 
 
 
 
 
 
 
 
 
 
 
 
Algoritmo de trazo de rayas.
 
Puesto que podría generarse un número infinito de puntos de intensidad sobre las diversas superficies de una escena, un buen método para determinar las intensidades especulares en posiciones visibles de la superficie consiste en trazar rayas hacia atrás desde la posición de visión hasta la fuente de luz. Comenzando desde la posición de visión, la raya que atraviesa cada pixel en el plano de visión se traza hacia atrás a una superficie de la escena tridimensional. Esta técnica, conocida como trazo de rayas, se ilustra en la siguiente figura.
 
 
 
 
 
Cuando se encuentran objetos transparentes en el proceso del trazo de rayas, las contribuciones de intensidad de la reflexión especular se toman en cuenta. En una superficie transparente, la raya se divide en los dos componentes que se muestran en la siguiente figura. Cada raya se traza después en forma individual hacia su fuente.
 
 
 
 
Después que se ha procesado una raya para determinar todas las contribuciones de intensidad especular, se fija la intensidad del pixel correspondiente. La figura siguiente muestra dos vistas de una escena generada con técnicas de trazo de rayas.
 
 
 
 
Superficies fractales.
 
Para determinar niveles de intensidad para los diversos puntos de la superficie de un objeto fractal se necesita algún método para determinar las normales a la superficie. Un método para realizar esto consiste en representar a un fractal como un número de planos pequeños con un conjunto de normales a la superficie para cada plano.
 
Fronteras de superficies con anti seudónimos.
 
Las líneas y las aristas de polígonos pueden aliarse con técnicas de anti seudónimos que ajustan posiciones de pixeles o bien fija las intensidades de los pixeles de acuerdo con el porcentaje de área-pixel cubierta en cada punto. Pueden aplicarse métodos de anti seudónimos semejantes para alisar las fronteras de una escena que contiene un conjunto de superficies.
 
 
Bibliografía.
 
 
 
 
 
 

MODELOS BÁSICOS DE ILUMINACIÓN.


Modelo de iluminación simple.

Sólo influyen la superficie en cuestión, las luces y la posición del observador (cálculos simples).





Modelos de iluminación complejos.

Las sombras, las interreflexiones y la difusión de la luz en otros medios se calculan por otros algoritmos (implican cálculos complejos).









Modelo de iluminación simple.
Pero igualmente, con un modelo de iluminación simple + trucos se puede dar ilusión de realismo.
 
Reflexión difusa.
Un reflector difuso perfecto esparce la luz que refleja de manera igual en todas las direcciones, viéndose igual para todos los observadores. Sin embargo, la cantidad de luz reflejada depende del material, dado que parte de la luz es absorbida, y de la posición de la fuente de luz relativa a la superficie. Reflexiones difusas son caracterizadas por superficies rugosas, como se ve en la siguiente figura (corte trasversal):
Se considera una superficie plana difusa iluminada por el sol, como se muestra en la siguiente figura:
 
La superficie se vuelve más brillante al mediodía, y menos durante la madrugada y la puesta, dado que, según la ley de Lambert, solo se ve el componente vertical de la luz entrante. 
Reflexión de Lambert:
Las superficies que muestran reflexión difusa, aparecen igual de brillantes desde cualquier ángulo de vista ya que cualquier punto de estas superficies refleja la luz con igual intensidad en todas direcciones. Es decir, un punto de la superficie del objeto parece igual de brillante desde cualquier lugar desde el que se observe y al variar la posición de la vista, esta intensidad sigue sin variar.
 
En las imágenes inferiores, el brillo del polígono señalado con una flecha roja es el mismo, a pesar de que el ángulo de vista es distinto.
 
 
Esto se explica debido a que en este modelo de iluminación, para una superficie dada, el brillo de la misma depende únicamente del ángulo (θ) entre la dirección de la luz (L) y el vector normal a la superficie (N) y no depende para nada del ángulo de vista.
 
Matemáticamente, hay dos factores que hacen que esto ocurra:
 
  • Por un lado, esto es así porque, en un principio, un rayo que intercepta una superficie cubre un área que es inversamente proporcional al coseno del ángulo entre este rayo y el vector normal a la superficie. Por ejemplo, si consideramos que el rayo posee una sección transversal diferencial dA infinitamente pequeña, entonces la superficie que intercepta el rayo equivaldría a dA / cos θ. Entonces obtenemos que para un rayo cualquiera, la cantidad de energía que incide en dA es proporcional al cos θ.
  • Por otro, debemos conocer una propiedad de este modelo de sombreado, por el cual consideramos que la cantidad de luz reflejada hacia el observador, es directamente proporcional al coseno entre observador y la normal de la superficie que refleja la luz. Pero como hemos visto en el punto 1, la cantidad de superficie visible es inversamente proporcional a este coseno, por lo que estos dos factores se anulan.
 
 
Reflexión especular.
 
La denominada reflexión especular se puede contemplar en cualquier tipo de superficie brillante. Si se emplea solo reflexiones ambiente y difusas, las imágenes serán sombreadas y aparecerán tridimensionales, pero todas las superficies se verán sin vida. Lo que hace falta son la reflexión de secciones más brillantes en los objetos. Esto ocasiona un color diferente del color del ambiente reflejado y luz difusa. Una esfera roja, bajo luz blanca, tendrá un resplandecer blanco que es la reflexión de parte de la luz de la fuente en la dirección del observador.
 
Mientras que una superficie difusa es rugosa, una superficie especular es suave. Mientras mas lisa se la superficie, mas se parece a un espejo, como se ve en la siguiente figura.
 
Según la superficie se hace mas lisa, la luz reflejada se concentra en un rango mas pequeño de ángulos, centrado alrededor del ángulo de un reflector perfecto: un espejo o una superficie especular perfecta. Modelar superficies especulares realísticas puede ser complejo, ya que el patrón por el cual se esparce no es simétrico, dependiendo de el largo de onda de la luz incidente y cambia con el ángulo de reflexión
 
Modelo de iluminación de Phong.
 
Phong Bui-Tuong desarrollo un modelo de iluminación muy popular para reflectores no perfectos, como la manzana. Asume que, como se observó antes, el máximo reflejo especular ocurre cuando α es 0, disminuyendo a medida que aumenta α. Esta caída es aproximada mediante la siguiente función:
 
cosn α
 
n = exponente de reflexión especular. Constante propia del materia del objeto. Los valores de n suelen variar entre 1 y varios cientos, dependiendo del material que se quiere simular. Para obtener un reflector perfecto, n debería tender a infinito.
 
Al igual que en el modelo de reflexión de Lambert, tomamos valores negativos de este coseno como 0.
 
El modelo de iluminación de Phong está basado en otros trabajos anteriores, sin embargo, este fue el primero en construir un modelo de reflexión especular para observador y luces que se encuentran en posiciones arbitrarias del universo.
 
La cantidad de luz incidente reflejada de forma especular depende del ángulo de incidencia θ.
 
 
Si W(θ) es la fracción de luz especular reflejada, el modelo de Phong es:
 
Iλ = Iaλ · ka · Odλ + ƒatt · Ipλ · [kd · Odλ · cos θ + W(θ) · cosn α]
 
Aquí se muestran diferentes valores de cosn α usados habitualmente en el modelo de iluminación de Phong:
 
Si la dirección del vector reflejo R, y la dirección del punto de vista están normalizados, entonces cos α = R · V. Además, W(θ) se transforma en una constante ks, que es el coeficiente de reflexión especular del material, con un valor acotado entre 0 y 1. El valor de ks, se obtiene experimentalmente para obtener resultados estéticamente correctos. Con esto, la función puede ser reescrita de la siguiente forma:
 
Iλ = Iaλ · ka · Odλ + ƒatt · Ipλ · [kd · Odλ · (N · L)] + ks · (R · V)n]
 
Se puede ver que el color de la componente especular en el modelo de Phong no depende de ninguna propiedad del material, por este modelo en concreto obtiene muy buenos resultados al simular superficies plásticas, las cuales poseen la misma propiedad.
Pero como se mostró anteriormente, a la reflexión especular le afectan las propiedades del material del objeto y, en general, el reflejo especular tendrá un color diferente al reflejo difuso cuando la superficie está compuesta de varios materiales. Se puede obtener este efecto con esta nueva variación de la ecuación anterior:
 
Iλ = Iaλ · ka · Odλ + ƒatt · Ipλ · [kd · Odλ · (N · L)] + ks · Osλ · (R · V)n]
 
Donde Osλ es el color especular del objeto.
 
Atenuación de la intensidad.
Si tenemos una escena formada por dos superficies paralelas de idéntico material que se solapan y que están iluminadas desde nuestro punto de vista, no podremos distinguir donde termina un plano y donde comienza el otro, como se ve en esta escena iluminada con una luz direccional.
 
 
Para obtener el resultado requerido, introducimos un factor de atenuación ƒatt de la siguiente forma en nuestra función de reflexión difusa: 
I = Ia · ka + ƒatt · Ip · kp · (N · L)
 
La explicación del uso de este factor ƒatt lo obtenemos del hecho físico de que la energía desde el origen de la fuente de luz cae como el inverso del cuadrado de dL, que es la distancia que viaja la luz desde el punto de luz hasta la superficie dada. En este caso:
 
ƒatt = 1 / dL2
 
Un ejemplo de este tipo de iluminación, es la misma escena de antes, iluminada con el mismo tipo de luz direccional, con la excepción de que ahora se emplea atenuación de la intensidad de la luz (con el parámetro ƒatt = 1 / dL2):
 
Sin embargo, en la práctica, esto no funciona demasiado bien. Si la fuente luz está demasiado lejos, 1 / dL2 no varía demasiado, y si la fuente de luz está demasiado cerca, 1 / dL2 varía muy rápido, dando como resultado sombras considerablemente diferentes para el mismo ángulo θ entre N y L. Un ejemplo de escena excesivamente oscura por una atenuación 1 / dL2 sería:
 
 
Así que, aunque este comportamiento es correcto para fuentes de luz puntuales, los objetos que vemos en la vida real no están iluminados por fuente de luz puntuales, ni usan modelos simplificados de iluminación.
 
Lo que se espera de este modelo es que aproxime algunos de los efectos de la atenuación atmosférica entre el observador y el objeto. Un compromiso que nos permite acercarnos a esta aproximación de forma más simple que la ley de atenuación del cuadrado de la distancia es:
 
ƒatt = min(1 / (c1 + c2 · dL + c3 · dL2), 1)
 
Donde c1, c2 y c3 son constantes definidas por el usuario asociadas con la fuente de luz. c1 evita que el denominador se vuelva demasiado pequeño cuando la luz esta cerca, y la expresión es ajustada a un valor máximo de 1 para asegurar que siempre se atenúa.
 
Bibliografía.
 
 
 



RELLENO DE POLÍGONOS.

Polígono es una figura básica dentro de las representaciones y tratamiento de imágenes bidimensionales y su utilización es muy interesante para modelar objetos del mundo real.
 
En un sentido amplio, se define como una región del espacio delimitada por un conjunto de líneas (aristas) y cuyo interior puede estar rellenado por un color o patrón dado.
  
Casos de relleno según su complejidad.
 
El caso más sencillo de relleno es el triángulo. Luego sigue el relleno de polígonos convexos deN-lados.
 
Relleno de polígonos cóncavos.
 
 
Método de relleno de polígonos con color.
 
  •  Scan-line: Fila a fila van trazando líneas de color entre aristas. Para scan-line que cruce el polígono se busca en la intersección entre las líneas de barrido y las aristas del polígono. Dichas intersecciones se ordenan y se rellenan a pares.
 
 
  •  Línea de barrido: Es válido para polígonos cóncavos como convexos. Incluso para si el objeto tiene huecos interiores. Funcionan en el trozo de líneas horizontales, denominadas líneas de barridos, que intersectan un número de veces, permitiendo a partir de ella identificar los puntos que se consideran interiores al polígono.
 
 
  •  Inundación: Empieza en un interior y pinta hasta encontrar la frontera del objeto. Partimos de un punto inicial (x,y), un color de relleno y un color de frontera. El algoritmo va testeando los píxeles vecinos a los ya pintados, viendo si son frontera o no. No solo sirven para polígonos, sino para cualquier área curva para cualquier imagen se usan los programas de dibujo.
 
 
 
  •  Fuerza bruta: Calcula una caja contenedora del objeto. Hace un barrido interno de la caja para comprobar c/pixel este dentro del polígono. Con polígonos simétricos basta con que hagamos un solo barrido en una sección y replicar los demás pixeles. Requiere aritmética punto-flotante, esto lo hace preciso y costoso.
 
 
  •  Relleno mediante un patrón: Un patrón viene definido por el área rectangular en el que cada punto tiene determinado color o novel de gris. Este patrón debe repetirse de modo periódico dentro de la región a rellenar. Para ello debemos establecer una relación entre los puntos del patrón y los pixeles de la figura. En definitiva debemos determinar la situación inicial del patrón respecto a la figura de tal forma que podamos establecer una correspondencia entre los pixeles interiores al polígono y los puntos del patrón.
 
 
 
Bibliografía.
 
 

ILUMINACIÓN Y SOMBREADO.

Desde una perspectiva física, una superficie puede emitir luz por su propia emisión, como focos de luz, o reflejar luz de otras superficies que la iluminan. Algunas superficies pueden reflejar y emitir luz. El color que se ve en un punto de un objeto está determinado por las múltiples interacciones entre las fuentes de luz y superficies refractivas. Este es un proceso recursivo.
 
El problema consiste de dos aspectos:
 
 
1. Modelar las fuentes de luz en una escena.
2. Construir un modelo de reflexión que trate con las interacciones entre materiales y luz.
 
Para comprender el proceso de iluminación, se puede comenzar siguiendo los rayos de luz de un punto fuente, donde el observador ve solamente la luz que emite la fuente y que llega a los ojos; probablemente a lo largo de complejos caminos y múltiples interacciones con objetos en la escena, como se muestra en la siguiente figura:
 
 
                                                    
 
  • Si un rayo de luz entra al ojo directamente de la fuente, se verá el color de la fuente.
  • Si un rayo de luz pega en una superficie que es visible al observador, el color visto se basará en la interacción entre la fuente y el material de la superficie: se verá el color de la luz reflejado de la superficie a los ojos.
 
En término de gráfica por computadora, se reemplaza el observador por el plano de proyección, como se ve en la siguiente figura:
 
                                          
 
La ventana de recorte en este plano se mapea a la pantalla. El recorte del plano de proyección y su mapeo a la pantalla significa un número particular de pixeles de despliegue. El color de la fuente de luz y las superficies determina el color de uno o más pixeles en el frame buffer.
 
La naturaleza de interacción entre los rayos y las superficies determina si un objeto aparece rojo o rosado, claro u obscuro, reluciente o no. Cuando la luz da en una superficie, parte se absorbe, y parte se refleja.
 
• Si la superficie es opaca, reflexión y absorción significará de toda la luz que dé en la superficie.
 
• Si la superficie es translucida, parte de la luz será transmitida a través del material y podrá luego interactuar con otros objetos.
 
Un objeto iluminado por luz blanca se ve rojo porque absorbe la mayoría de la luz incidente pero refleja luz en el rango rojo de frecuencias.
 
Un objeto relumbrante se ve así porque su superficie es regular, al contrario de las superficies irregulares.
 
El sombreado de los objetos también depende de la orientación de las superficies, caracterizado por el vector normal a cada punto. Las interacciones entre luz y materiales se pueden clasificar en tres grupos, como se ve en la siguiente figura:
 
                         
 
1. Superficies especulares (espejos) - se ven relumbrantes porque la mayoría de la luz reflejada ocurre en un rango de ángulos cercanos al ángulo de reflexión. Espejos son superficies especulares perfectas. La luz del rayo de luz entrante puede absorberse parcialmente, pero toda la luz reflejada aparece en un solo ángulo, obedeciendo la regla que el ángulo de incidencia es igual al ángulo de reflexión.
 
2. Superficies Difusas - se caracterizan por reflejar la luz en todas las direcciones. Paredes pintadas con mate son reflectores difusos. Superficies difusas perfectas dispersan luz de manera igual en todas las direcciones y tienen la misma apariencia a todos los observadores.
 
3. Superficies translucidas - permiten que parte de la luz penetre la superficie y emerja de otra ubicación del objeto. El proceso de refracción caracteriza al vidrio y el agua. Cierta luz incidente puede también reflejarse en la superficie.
 
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. Este aspecto no será tomado en cuenta en los modelos más sencillos.
 
Si se considera una fuente como en la siguiente figura, se le puede ver como un objeto con una superficie.
 
                                                
 
Cada punto (x,y,z) en la superficie puede emitir luz que se caracteriza por su dirección de emisión (θ,φ) y la intensidad de energía emitida en cada frecuencia λ. Por lo tanto, una fuente de luz general se puede caracterizar por la función de iluminación I(x, y, z, θ, φ, λ) de seis variables. Nótese que se requiere dos ángulos para especificar una dirección, y que se asume que cada frecuencia puede considerarse de manera independiente. Desde la perspectiva de una superficie iluminada por esta fuente, se puede obtener la contribución total de la fuente al integrar sobre la superficie de la fuente, un proceso que considera los ángulos de emisión que llegan a la superficie bajo consideración y que debe considerar también la distancia entre la fuente y la superficie.
 
                                       
 
Bibliografía.