Вы находитесь на странице: 1из 7

PROYECTO:

POLÍGONO

|YESICA HERNÁNDEZ |COMPUTACIÓN GRAFICA

Dibujado de polígonos con implementación del algoritmo de Bresenham para unir los nodos del mismo prototipo de algoritmo de rellenado y funciones de detección de intersecciones con líneas.

Descripción del programa: el usuario puede generar polígonos de cualquier numero de lados con dar clic con el botón izquierdo del mouse, y los puntos se irán uniendo en la secuencia en que sean creados. Para indicar que se ha terminado de definir el polígono de hace clic con el botón derecho, lo que activa el proceso de pintado mediante el prototipo de algoritmo por barrido

Archivos contenidos:

Filename

Location

E:\Programacion\CompGrafica\Poligono\Ydata.h

E:\Programacion\CompGrafica\Poligono\main_poligono.c

E:\Programacion\CompGrafica\Poligono\poligono.h

E:\Programacion\CompGrafica\Poligono\Color.h

E:\Programacion\CompGrafica\Poligono\linea_bresenham.h

/*

YDATA.H:

CONTIENE FUNCIONES QUE ME PERMITEN DESPLEGAR MIS DATOS EN EL PROGRAMA Y UN BONITO ESCUDO DE LA FACULTAD DE INGENIERIA TODO ESTO POSIBLE GRACIAS A LAS RUTINAS DE ALLEGRO

*/

#include <allegro.h>

/* Función para mostrar en pantalla mis datos y el escudo de la facultad */

void titulo(const char *titulo){

BITMAP *escudo = load_bmp("fi.bmp",NULL); //GENERAMOS UN APUNTADOR AL ARCHIVO blit(escudo, screen, 0, 0, 0, 480-112, 90, 112); //COPIAMOS LOS DATOS DEL ARCHIVO

//A LA PANTALLA EN LA

POSICION INDICADA:

//INICIO EN EL ARCHIVO //INCIO EN LA PANTALLA //TAMAÑO X,Y DEL ARCHIVO textprintf(screen, font, 95, 400, makecol(0,197, 205), "YESICA HERNANDEZ

HERNANDEZ / Computacion Grafica"); textprintf(screen, font, 95, 415, makecol(72,209, 174), "-- %s --",titulo); textprintf(screen, font, 95, 430, makecol(202,255, 112), "Presione ESC para cerrar"); destroy_bitmap(escudo);

}

MAIN_POLIGONO:

//INCLUIMOS LAS FUNCIONES HECHAS:

#include "poligono.h" //RUTINAS CONCERNIENTES AL POLIGONOS #include "Ydata.h" //RUTINAS CONCERNIENTES A LA VISUALIZACION DE DATOS PERSONALES #include "Color.h" //RUTINAS DE DIBUJADO DE LINEAS POR BRESENHAM

//DECLARACION DE RUTINAS DE ALLEGRO void init(); void deinit();

//VARIABLES GLOBALES:

int t=0;

int main() { init();

//MOSTRAMOS DATOS PERSONALES E INSTRUCCIONES titulo("Algoritmo Rellenado Poligono"); textprintf(screen, font, 20, 30, makecol(202,255, 112), "[Mouse_izq] = pinta punto, [Mouse_der] = termina figura");

//INICIALIZAMOS VARIABLES int pos, xi=0,yi=0,x, y; //ESTAS VARIABLES GUARDAN LOS VALORES DADOS EN TIEPO REAL

//PÒR MEDIO DEL MOUSE Y QUE SIRVEN PARA GENERAR

LOS LADOS DEL POLIGONO int minx=640,miny=480,maxx=0,maxy=0; //SIRVEN PARA AHORRAR CALCULOS AL DELIMITAR EL AREA DE BARRIDO //CONTADORES Y BANDERAS:

int c=0;

//ESTA FUNCION DESPLIEGA LOS 8 COLORES DISPONIBLES DE MI TABLA DE COLORES int n;

for(n=0;n<=7;n++){

putpixel(screen, 20, 80 +10*n, color_val(n));

}

//INICIA RUTINA PARA DIBUJAR LADOS DEL POLIGONO while (!(mouse_b & 2)) {

//CAPTURAMOS LA POSICION X,Y DEL RATON EN ESTE MOMENTO:

pos = mouse_pos;

x = pos >> 16;

y = pos & 0x0000ffff;

//REPORTAMOS DICHOS VALORES:

textprintf_ex(screen, font, 20, 20,

color_val(amarillo),color_val(azulC), "

%d %d

",x, y);

//EVALUAMOS LOS PUNTOS PARA SABER SI TENEMOS DOS PARES PARA DIBUJAR

EL SIGUIENTE LADO if (mouse_b & 1){

if(c>0){

//TENEMOS DOS PARES, PODEMOS TRAZAR UNA LINEA; lineaX( xi, yi, x, y,line_color); //MI ALGOTIMO

DE LINEA

}

//EN CASO DE NO TENER DOS PARES, ALMACENAMOS LOS VALORES ACTUALES Y

ESPERAMOS NUEVO PUNTO:

putpixel(screen, x, y, color_val(rojo)); if(x<minx)minx=x; if(y<miny)miny=y; if(x>maxx)maxx=x; if(y>maxy)maxy=y;

c=1;

}

}

xi = x; yi = y;

//REPORTAMOS EL AREA RECTANGULAR MINIMA EN DONDE SE HAYA EL POLIGONO:

textprintf_ex(screen, font, 20, 45, makecol(56,197, 98),-1, "Area de barrido: %d %d %d %d",minx,miny,maxx, maxy); //EJECUTAMOS LA RUTINA DE RELLENO EN BASE A ESTOS LIMITES:

relleno(minx,miny,maxx, maxy);

while (!key[KEY_ESC]) {} //HACEMOS UNA PAUSA HASTA QUE NO SE PRESIONE ESC deinit(); //DEINICIALIZAMOS ALLEGRO return 0; //TERMIANMOS

}

END_OF_MAIN() //MACRO QUE NECESITA ALLEGRO

//AQUI INICIALIZAMOS LA VENTANA void init() { int depth, res; allegro_init(); depth = desktop_color_depth(); if (depth == 0) depth = 32; set_color_depth(depth); res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); if (res != 0) { allegro_message(allegro_error);

}

exit(-1);

//INICIALIZAMOS PERIFERICOS: TIMERS, TECLADO Y RATON:

install_timer(); install_keyboard(); install_mouse(); //enable_hardware_cursor(); //SELECCIONAMOS EL TIPO DE CURSOS QUE VEREMOS EN LA VENTANA DE ALLEGRO //MEDIANTE ESTA FUNCION PODRIAMOS ESTABLECER CUALQUIER IMAGEN COMO CURSOR

//POR EJEMPLO UN LAPIZ select_mouse_cursor(MOUSE_CURSOR_ARROW); show_mouse(screen);

//ESTABLECEMOS LOS COLORES DE LINEA Y RELLENO line_color= color_val(verde); fill_color= color_val(azulC);

}

void deinit() {

//

clear_keybuf(); free_nodes(); /* add other deinitializations here */

}

/*

POLIGONO.H:

CONTIENE TODAS LAS RUTINAS ESTABLECIDAS PARA GENERAR POLIGONOS

APARTIR

 

DE LOS PUNTOS DADOS EN PANTALLA, DEBIDO A LA DIFUCULTAD DE

CONTROLAR

 

LISTAS LIGADAS MEDIANTE EL RATON, POR LA VELOCIDAD A LA QUE SE

ACTUALIZA

SE HARA UN EXAMEN POSTERIOR A LA GENERACION DEL POLIGONO EN BASE AL COLOR DE CADA PIXEL EN EL BUFFER DE LA PANTALLA

*/ //INCLUIMOS LA LIBRERIA DE ALLEGRO #include "linea_bresenham.h"

//VARIABLES GLOBALES:

//VARIABLES PARA ENCONTRAT LOS PUNTOS DENTRO DEL POLIGONO int openl=0,lima=0,limb=0;

//FUNCION QUE HACE EL BARRIDO DEL AREA EN DONDE SE HAYA EL POLIGONO //va comparando pixel por pixel en líneas horizontales y decide si //se haya o no dentro del polígono mediante el estado de las banderas // openl, color y next //NOTA: ESA FUNCION AUN NO ESTA TERMINADA AL 100% AUN PRESENTA ERRORES

void test_p(BITMAP *bmp, int x, int y, int d){ int color= getpixel(screen, x, y); //obtenemos el color del pixel en pantalla int next=getpixel(screen, x+1, y); //obtenemos el color del siguiente pixel int up=getpixel(screen, x, y+1);

//closed=0;

//si encuentra un elemento de la línea y además el siguiente es un pixel sin //color, entonces enciende la bandera openl y tratara de buscar un par //cuando encuentre otro pixel perteneciente a la recta tomara los valores //que almaceno como x y y iniciales y hará una línea hasta ese punto en //donde encontró una intersección //se reiniciarán las banderas if(color==line_color && openl==0&& next!=line_color){

openl=1;

lima=x;

}

else if(color==line_color &&openl==1 && next!=line_color){

limb=x;

line(screen, lima, y, limb, y, fill_color);

openl=0;

// lima =x;

}

}

//FUNCION PARA RELLENAR EL POLIGONO void relleno(int mix, int miy,int max,int may){ int color;

do{ //se barre el area en donde se hayan los puntos del poligon de //arriba hacia abajo y en linea horizontal

openl=0;

//no usamos nuestra propia función de Bresenham porque la //función do_line implementada por allegro, traza la línea indicada //pero no la dibuja, si no le pasa como argumento cada uno de los puntos //que va calculando a la función indicada en sus argumentos, esa función //es la que realiza alguna acción con dicho pixel, en este caso //es la función test_p la que decide si se colorea o no el pixel do_line(screen, mix-1, miy, max+1, miy ,1, test_p); miy++; rest(100); //se hace una pausa para animar lentamente el proceso de pintado }while(miy<=may);

}

/* YESICA HERNANDEZ HERNANDEZ

COLOR.H

MI PROPIA TABLA DE 8 COLORES:

TABLA DE COLOR BASADA EN EQUIVALENCIAS RGB TRIPLETA -> DECIMAL

*/

//000000 negro #define negro 0 //0000FF azul marino #define azulM 1 //00CCFF azul claro #define azulC 2 //00FF00 verde lima #define verde 3 //663300 cafe #define cafe 4 //FFFF00 amarillo #define amarillo 5 //FF0000 rojo #define rojo 6 //FFFFFF blanco #define blanco 7

int Tcolor[8]={0,255,52479,65280,6697728,16776960,16711680,16777215};

int color_val(int cual){ return Tcolor[cual];

}

/*

YESICA HERNANDEZ HERNANDEZ

LINEA_BRESENHAM:

CONTIENE RUTINAS QUE SE RELACIONAN CON LA CREACION DE LINEAS A BASE DEL ALGORTIMO DE BRESENHAM

*/

#include <allegro.h>

//VARIABLES GLOBALES int loop=0; //NOS AVISA QUE SE HA ENCONTRADO UN LOOP CERRADO AL HACER

INTERSECCION

//DOS LINEAS //INDICA EL COLOR ACTUAL ESTABLECIDO int line_color; int fill_color;

/*

Función para dibujar un eje coordenado de referencia, no se implementa en el programa de poligono ya que tenemos un eje con referencia absoluta en la

esquina superior izquierda. */ void coords(){

hline(screen, 0, 480/2, 640, makecol(123,85, 112)); vline(screen, 640/2, 0, 480, makecol(123,85, 112));

}

/*

Funcion que implementa el algoritmo de Bresenham para dibujar lineas */ void lineaX(float x1, float y1, float x2, float y2, int color){ float x, y; //variables para guardar el punto que actualmente de esta

evaluando

float dx, dy; //almacenar los incrementos en x y y de la coordenadas dadas float incX, incY; //variable auxiliar para calcular cual es el incremento en x y y float incMayor, incMenor;//variables auxiliares para calcular el aumento de

p

float p; //parámetro de selección del pixel según la distancia con el mismo

int Pmayor45; //bandera para elegir configuración para curvas mayores a 45º

int

la linea

control_ciclo; //variable para generar los puntos pertenecientes a

int colorP,A,B;

dx = (x2 >= x1) ? (x2 - x1) : (x1 - x2); //hacemos el valor dx sea

absoluto

dy = (y2 >= y1) ? (y2 - y1) : (y1 - y2); //hacemos el valor de dy

sea absoluto

if ((dx < dy)) // discernimos si la pendiente es mayor a 45 grados

{

Pmayor45 = 1;

// Si la pendiente es mayor a 45 grados:

//usamos por un instante a p como una variable para hacer //intercambio de valores:

p

= x1; x1 = y1; y1 = p;

p

= x2;

x2 = y2;

y2 = p;

p = dx;

}else Pmayor45 =0;

dx = dy; dy = p;

//inicializamos las variables:

incMayor = (-2 * dx) + (2 * dy); incMenor = (2 * dy); //establecemos según el caso, definido por la posición de los puntos //sobre la recta si el incremento debe ser positivo o negativo incX = (x1 <= x2) ? 1 : -1; incY = (y1 <= y2) ? 1 : -1; //inicializamos p, para efectuar el barrido de los puntos

p = (2 * dy) - dx;

//establecemos el valor desde donde comenzamos a generar los puntos

x = x1;

y = y1;

control_ciclo = (int)dx + 1;

// ciclo de dibujado, aqui se puede inicializar llamado a otra función while (control_ciclo--)

{

//ajustamos los valores de x,y respecto al caso de la pendiente //mayor a 45 grados, en cuyo caso, se calculan los valores //invertidos, pero se deben dibujar intercambiados para no //afectar la recta original

if (Pmayor45) {A=(int)y;B=(int)x;} else {A=(int)x; B=(int)y;}

colorP= getpixel(screen, A, B); if(colorP==line_color){

loop=1;

textprintf(screen, font, 20, 60, makecol(202,255, 112), "Loop Cerrado!!");

}

else putpixel(screen, A,B, line_color); //efectuamos los incrementos establecidos, según la pendiente y los casos del //parámetro p:

x += incX;

if (p > 0)

{

p

+= incMayor;

// caso 1: p > 0;

y

+= incY;

}

else

{

p

+= incMenor;

// caso 2: p <= 0;

}

}

}