Sunteți pe pagina 1din 7

PROYECTO:

POLÍGONO
|Y E S IC A H E R N Á N D E Z |C O M P U TA C IÓ N G R A F IC A

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

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

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

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

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

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

/*

YDA TA .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);
}

MA I N_POLI GONO:

//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 */
}

/*

POL IGONO.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

COL OR.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

L INE A_B RES ENHAM:


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 control_ciclo; //variable para generar los puntos pertenecientes a
la linea

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; dx = dy; dy = p;
}else Pmayor45 =0;

//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;
}
}
}

S-ar putea să vă placă și