Sunteți pe pagina 1din 224

Bismarck Salvador Traa Lpez__________________________________________ UNI

Introduccin a la Programacin grafica en C.


Para la mejor comprensin de este tutor hemos realizado un anlisis de las Funciones que se suelen utilizar con mucha frecuencia al programar en el modo grafico de C, dando como resultado la librera conio.h, dos.h, stdlib.h, y evidentemente graphics.h. En este pequeo tutor solo haremos nfasis en estas libreras, puesto que al final del libro se encuentran las dems libreras que comnmente encontramos con frecuencia en el programa. Muchos libros nos marean dndonos conceptos los cuales se aprenden conforme programando; esto no significa, que no sean importan tantees los ejercicios que aqu te enseamos te ayudaran a darte todo el conocimiento as como tambin te los daremos conforme avancemos as que dejemos de hablar y aventurmonos en el mundo de la programacin grafica. Lo primero que debemos saber al realizar una grafica son las dimensiones del ordenador (Monitor) en modo texto las dimensiones de este es 25X80 esto dependiendo de la versin de video instalada. En el modo grafico estas dimensiones cambian dependiendo del tipo de macro de inicializacin se realice(ver Macro modos). Quedando la mas comn de 640X480 modo VGA.

A la hora de desarrollar un programa grfico se debe tener en cuenta los siguientes cuatro puntos: 1. Especificar el fichero o librera graphics.h # include<graphics.h>

2. Inicializar el modo grafico correspondiente mediante la Funcin initgraph;


Initgraph(&adaptador,&modo,direccin de los archivos bgi);

3. Crear y manipular las figuras graficas.


/*Desarrollo del programa*/ 4. Restaurar el modo de video antes de salir del programa(restaurar el modo texto) closegraph() o restorecrtmode()

Juan Carlos Gutirrez Barquero____________________________________________

Bismarck Salvador Traa Lpez__________________________________________ UNI


Otra de las cosas importantes que debemos saber es que Funciones contiene graphics.h

Funciones de Graphics.h
Esta librera se encuentra los prototipos de las Funciones que manipulan la parte grfica en el entorno de MS-DOS. Arc bar bar3d circle cleardevice clearviewport closegraph detectgraph drawpoly ellipse fillellipse fillpoly floodfill getarccoords getaspectratio getbkcolor getcolor getdefaultpalette getdrivername getfillpattern getfillsettings getgraphmode getimage getlinesettings getmaxcolor getmaxmode getmaxx getmaxy getmodename getmoderange getpalette getpalettesize getpixel gettextsettings getviewsettings getx gety graphdefaults grapherrormsg graphfreemem graphgetmem graphresult imagesize initgraph installuserdriver installuserfont line linerel lineto moverel moveto outtext outtextxy pieslice putimage putpixel rectangle registerbgidriver registerbgifont restorecrtmode sector setactivepage setallpalette setaspectratio setbkcolor setfillpattern setfillstyle setgraphbufsize setgraphmode setlinestyle setpalette setrgbpalette settextjustify settextstyle setusercharsize setviewport setvisualpage setwritemode textheight textwidth

Es necesario conocer hacerca de los macros y estructuras, entre las estructuras tenemos: arccoordstype fillsettingstype Entre los macros se encuentran: colores drivers enlazar errores fuentes lnea modos put_op trama linesettingstype palettetype textsettingstype viewporttype

Antes de comenzar a programar en modo grafico debemos estudiar lo que son los macros, que son instrucciones que nos ayudaran a realizar de una manera ms efectiva nuestros grficos.

Juan Carlos Gutirrez Barquero____________________________________________

Bismarck Salvador Traa Lpez__________________________________________ UNI

Colores :
Colores de Fondo
Constante BLACK BLUE GREEN CYAN RED MAGENTA BROWN LIGHTGRAY DARKGRAY LIGHTBLUE LIGHTGREEN LIGHTCYAN LIGHTRED LIGHTMAGENTA YELLOW WHITE Valor 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Significado Negro Azul Verde Can Rojo Magenta Marrn Gris Claro Gris Oscuro Azul Claro Verde Claro Can Claro Rojo Claro Magenta Claro Amarillo Blanco

Modo de 16 Colores
Constante BLACK BLUE GREEN CYAN RED MAGENTA BROWN LIGHTGRAY DARKGRAY LIGHTBLUE LIGHTGREEN LIGHTCYAN LIGHTRED LIGHTMAGENTA YELLOW WHITE 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Valor Significado Negro Azul Verde Can Rojo Magenta Marrn Gris Claro Gris Oscuro Azul Claro Verde Claro Can Claro Rojo Claro Magenta Claro Amarillo Blanco

Color del modo CGA Juan Carlos Gutirrez Barquero____________________________________________ 3

Bismarck Salvador Traa Lpez__________________________________________ UNI

Nmero Paleta 0 1 2 3

Color 1 CGA_LIGHT GREEN CGA_LIGHT CYAN CGA_GREEN CGA_CYAN

Significado Verde Claro Can Claro Verde Can

Color 2 CGA_LIGHTRED CGA_LIGHTMAGENTA CGA_RED CGA_MAGENTA

Significado Rojo Claro Magenta Claro Rojo Magenta

Color 3 CGA_YELLOW CGA_WHITE CGA_BROWN CGA_LIGHTGRAY

Significado Amarillo Blanco Marrn Gris Claro

Valor asignado: 1 2 3 Nota: Color 0 se reserva para el color de fondo y se asigna con lo funcin setbkcolor, pero los dems colores son fijos. Estas constantes se usan con setcolor.

Colores para las paletas.


Constante (CGA) BLACK BLUE GREEN CYAN RED MAGENTA BROWN LIGHTGRAY DARKGRAY LIGHTBLUE LIGHTGREEN LIGHTCYAN LIGHTRED LIGHTMAGENTA YELLOW WHITE Valor 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Constante (EGA/VGA) EGA_BLACK EGA_BLUE EGA_GREEEN EGA_CYAN EGA_RED EGA_MAGENTA EGA_LIGHTGRAY EGA_BROWN EGA_DARKGRAY EGA_LIGHTBLUE EGA_LIGHTGREEN EGA_LIGHTCYAN EGA_LIGHTRED EGA_LIGHTMAGENTA EGA_YELLOW EGA_WHITE Valor 0 1 2 3 4 5 7 20 56 57 58 59 60 61 62 63

Nota: Estas constantes se usan con las Funciones setpalette y setallpalette.el cual veremos en captulos posteriores

Fuentes:

Juan Carlos Gutirrez Barquero____________________________________________

Bismarck Salvador Traa Lpez__________________________________________ UNI Fuentes para Texto


Constante DEFAULT_FONT TRIPLEX_FONT SMALL_FONT SANS_SERIF_FONT GOTHIC_FONT SCRIPT_FONT SIMPLEX_FONT TRIPLEX_SCR_FONT COMPLEX_FONT EUROPEAN_FONT BOLD_FONT Valor 0 1 2 3 4 5 6 7 8 9 10 Valor Fuente bitmap de 8x8 Fuente escalable de tipo triple Fuente escalable pequea Fuente escalable de tipo sans serif Fuente escalable de tipo gtico Fuente escalable de tipo manuscrito Fuente escalable de tipo manuscrito simple Fuente escalable de tipo manuscrito triple Fuente escalable de tipo complejo Fuente escalable de tipo europeo Fuente escalable en negrita

Direccin del Texto


Constante HORIZ_DIR VERT_DIR Valor 0 1 Significado Texto horizontal Texto vertical

Justificacin de Texto en la Horizontal


Constante LEFT_TEXT CENTER_TEXT RIGHT_TEXT Valor 0 1 2 Significado Justificar a la izquierda Centrar el texto Justificar a la derecha

Justificacin de Texto en la Vertical


Constante BOTTOM_TEXT CENTER_TEXT TOP_TEXT Valor 0 1 2 Significado Justificar debajo Centrar el texto Justificar arriba

Tramas:
Tramas predefinidas

Juan Carlos Gutirrez Barquero____________________________________________

Bismarck Salvador Traa Lpez__________________________________________ UNI


Constante EMPTY_FILL SOLID_FILL LINE_FILL LTSLASH_FILL SLASH_FILL BKSLASH_FILL LTBKSLASH_FILL HATCH_FILL XHATCH_FILL INTERLEAVE_FILL WIDE_DOT_FILL CLOSE_DOT_FILL USER_FILL Valor 0 1 2 3 4 5 6 7 8 9 10 11 12 Significado Rellena con el color de fondo Rellena enteramente Rellena con lneas horizontales: --Rellena con rayas finas: /// Rellena con rayas gruesas: /// Rellena con rayas inversas y finas: \\\ Rellena con rayas inversas y gruesas: \\\ Rellena con lneas cruzadas cuadriculadamente: +++ Rellena con lneas cruzadas diagonalmente: XXXX Rellena con lneas entrelazadas Rellena con lunares bastante distanciados Rellena con lunares poco distanciados Rellena con la trama definida por el usuario

Nota: Todos los tipos de tramas menos EMPTY_FILL usan el color de relleno seleccionado; EMPTY_FILL usa el color de fondo para rellenar.

Driver:
Dispositivos Grficos
Dispositivo/Constante DETECT CGA MCGA EGA EGA64 EGAMONO IBM8514 HERCMONO ATT400 VGA PC3270 Valor 0 1 2 3 4 5 6 7 8 9 10

Lneas:
Estilos de Lneas
Constante SOLID_LINE DOTTED_LINE CENTER_LINE DASHED_LINE USERBIT_LINE Valor 0 1 2 3 4 Significado Lnea continua _______ Lnea hecha con puntos .. Lnea centrada Lnea discontinua _._._._. Lnea definida por el usuario

Nota: El grosor es definido escribiendo NORM_WIDTH para rallas normales y THICK_WIDTH para lneas mas gruesos

Grosores para Lneas

Modos de Escritura

Juan Carlos Gutirrez Barquero____________________________________________

Bismarck Salvador Traa Lpez__________________________________________ UNI


Constante Grosor NORM_THICK THICK_WIDTH Valor 1 3 Significado Grosor es de 1 pxel Grosor es de 3 pxeles

Constantes COPY_PUT XOR_PUT

Valor 0 1

Significado Pxeles de la lnea sobrescriben los pxeles existentes Pxel de la pantalla son el Resulta do de la operacin OR de los pxeles existentes y los de la lnea

Modos:
Modos Grficos
Dispositivo CGA Modo/Constante CGAC0 CGAC1 CGAC2 CGAC3 CGAHI MCGAC0 MCGAC1 MCGAC2 MCGAC3 MCGAMED MCGAHI EGALO EGAHI A64LO EGA64HI AMONOHI VGALO VGAMED VGAHI ATT400C0 ATT400C1 ATT400C2 ATT400C3 ATT400MED ATT400HI HERCMONOHI PC3270HI IBM8514LO IBM8514HI Cdigo 0 1 2 3 4 0 1 2 3 4 5 0 1 0 1 3 0 1 2 0 1 2 3 4 5 0 0 0 1 Resolucin 320X200 320X200 320X200 320X200 640X200 320X200 320X200 320X200 320X200 640X200 640X480 640X200 640x350 640X200 640X350 640x200 640X200 640x350 640X480 320x200 320x200 320x200 320x200 640x400 640x400 720X348 720X350 640X480 1024X768 Paleta 4 Clores 4 Clores 4 Clores 4 Clores 2 Clores 4 Clores 4 Clores 4 Clores 4 Clores 2 Clores 2 Clores 16 Colores 16 Colores 16 Colores 4 Colores 2 Colores 16 Colores 16 Colores 16 Colores 4 Colores 4 Colores 4 Colores 4 Colores 2 Colores 2 Colores 2 Colores 2 Colores 256 Colores 256 Colores Pagina 1 1 1 1 1 1 1 1 1 1 1 4 2 1 1

MCGA

EGA EGA64 EGAMONO VGA ATT400

1* / 2**
2 2 1 1 1 1 1 1 1 2 1

HERC

Si la tarjeta es de 64 K o la tarjeta es de 256 K

Errores:

Juan Carlos Gutirrez Barquero____________________________________________

Bismarck Salvador Traa Lpez__________________________________________ UNI Cdigos de Errores


Constante grOk grNoInitGraph grNotDetected grFileNotFound grInvalidDriver grNoLoadMem grNoScanMem grNoFloodMem grFontNotFound grNoFontMem grInvalidMode grError grIOerror grInvalidFont grInvalidFontNum grInvalidDeviceNum grInvalidVersion Cdigo 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -18 Significado Ningn error Grficos no iniciados Ningn adaptador grfico detectado Fichero de dispositivo no encontrado Fichero de dispositivo no vlido No hay memoria para cargar dispositivo No hay memoria para rellenar No hay memoria para usar floodfill Fichero de fuente no encontrado No hay memoria para cargar la fuente Modo grfico no vlido Error grfico Error grfico de Entrada/Salida Fichero de fuente no vlido Nmero de fuente no vlido Nmero de dispositivo no vlido Nmero de versin no vlido

Put_op:
Operaciones con putimage
Constante COPY_PUT XOR_PUT OR_PUT AND_PUT NOT_PUT Valor 0 1 2 3 4 Significado Sobrescribir los pxeles existentes Operacin OR Exclusivo con los pxeles Operacin OR Inclusivo con los pxeles Operacin AND con los pxels Invertir la imagen

Nota: Estas operaciones se usan exclusivamente con la funcin putimage. El cual veremos en captulos posteriores.

Mtodos de Inicializacin del modo grafico.

Juan Carlos Gutirrez Barquero____________________________________________

Bismarck Salvador Traa Lpez__________________________________________ UNI


Antes de conocer los mtodos de inicializacin debemos conocer la funcin initgraph la cual nos permitir realizar grficos. Funcin initgraph void far initgraph(int far *driver, int far *modo, int far *path); Esta funcin es usada para cargar o validar un dispositivo grfico y cambiar el sistema de vdeo a modo grfico. La funcin initgraph debe ser llamada antes de cualesquier Funcines que generan una salida grfica sean usadas. Existen varios valores a ser usados para el argumento *driver. Si *driver es asignado a DETECT, 0, la funcin detectgraph es llamada, y un dispositivo y modo grfico apropiados son seleccionados. Asignando a *driver cualquier otro valor predefinido inicia la carga del dispositivo grfico correspondiente. Existen varios valores a ser usados para el argumento *modo. Estos valores deberan corresponder al dispositivo especificado en el argumento *driver. El argumento *path especificad el directorio donde los dispositivos grficos estn localizados. La funcin initgraph buscar el dispositivo primeramente en este directorio. Si no es encontrado, la funcin buscar en el directorio de inicio. Cuando el argumento *path es NULL, solamente el directorio de inicio es buscado. Otra forma para evitar cargando el dispositivo desde el disco cada vez que el programa es ejecutado es ligarlo o enlazarlo al dispositivo apropiado en un programa ejecutable. La funcin initgraph no retorna ningn valor. Sin embargo, cuando la funcin initgraph es llamada, el cdigo de error interno es activado. Si la funcin initgraph termina con xito, el cdigo es asignado un 0. Si no, el cdigo es asignado as: -2 grNotDetected La tarjeta grfica no se encontr -3 grFileNotFound El fichero del dispositivo no se encontr -4 grInvalidDriver El fichero del dispositivo es invlido -5 grNoLoadMem No hay suficiente memoria para cargar el dispositivo Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA; int modo = EGAHI; initgraph( &driver, &modo, C:\\TC20\\BIN ); circle( 300, 200, 80 ); getch(); /* Pausa */ closegraph(); getch(); } Existen diferentes mtodos de inicializacin pero en este pequeo tutorial trataremos dos que suelen ser los ms utilizados hoy en da.

1. Mtodo de inicializacin del modo grafico a prueba de errores. Juan Carlos Gutirrez Barquero____________________________________________ 9

Bismarck Salvador Traa Lpez__________________________________________ UNI

#include <graphics.h> # include<process.h> # include <conio.h> void main() { int driver = VGA; int modo = VGAHI; int resultado; initgraph(&driver,&modo,"c:\\tc20\\bin"); resultado=graphresult(); if(resultado!=grOk) { getch(); exit(0); } getch(); } cuerpo del programa

2. Mtodo de inicializacin rpido del modo grafico.


#include <graphics.h> void main() { int driver = DETECT,modo; initgraph(&driver,modo, c:\\tc20\\bin); cuerpo del programa driver: Es la direccin de la variable que contiene el cdigo del tipo de de driver o adaptador que tiene la computadora. modo: Es la direccin de la variable que contiene el cdigo del modo en que se podr adaptar. c:\\tc20\\bin: Es el directorio donde se encuentra el cdigo del manejador, puede ser camino relativo o absoluto. graphresult():Regresa el cdigo error de la ultima llamada a una funcin grafica de turbo c un valor de 0 significa que no hubo error. grOk : regresa el cdigo de error de la funcin graphresult(). DETECT: Dispositivo grafico de auto deteccin del la tarjeta de video y del modo grafico.

Qu son los primitivos grficos?


Juan Carlos Gutirrez Barquero____________________________________________ 10

Bismarck Salvador Traa Lpez__________________________________________ UNI


Definicin. Un primitivo grfico es un elemento fundamental de dibujo en un paquete grafico tal como un punto, lnea, o circulo; puede ser un carcter, o puede ser una operacin tal como relleno, coloreado o trasferido de la imagen. C cuenta con 5 grupos de primitivos grficos.

Figuras geomtricas: Dibujan las figuras de la geometra clsica: lneas,


crculos, rectngulos, arcos, polgonos etc.

Relleno: tiene dos formas de realizarse. El primero es con polgonos, donde se


definen los vrtices del polgono a ser rellenado segunda es una operacin grafica que busca algortmicamente las fronteras de la regin del relleno.

Rasterop: Es una operacin grafica que copia el rea de una imagen para luego
dibujarla en cualquier regin de la pantalla.

Grficas Matemticas: Dibujan los primitivos barras y sectores para conseguir


dibujar las herramientas del sector.

Texto Grfico: Sirve para escribir texto en modo grafico, utilizando diferentes
fuentes. Figuras geomtricas: LINEAS. void far line(int x1, int y1, int x2, int y2); Esta funcin es usada para conectar dos puntos con una lnea recta. El primer punto es especificado por los argumentos x1 e y1. El segundo punto es especificado por los argumentos x2 e y2. La lnea se dibuja usando el estilo de lnea actual, el grosor, y el color actual. La posicin del cursor grfico no es afectada por la funcin line.

La funcin line() no retorna ningn valor.

Ejemplo:

Juan Carlos Gutirrez Barquero____________________________________________

11

Bismarck Salvador Traa Lpez__________________________________________ UNI

#include <graphics.h> #include <conio.h> void main() { int driver = EGA,modo = EGAHI; initgraph( &driver, &modo, "c:\\tc20\\bin" ); line( 20, 40, 350, 100 ); line( 400, 30, 50, 250 ); getch(); closegraph(); } CIRCULOS. void far circle(int x, int y, int radio); Esta funcin se utiliza para dibujar un crculo. Los argumentos x e y definen el centro del crculo, mientras que el argumento radio define el radio del crculo. El crculo no es rellenado pero es dibujado usando el color actual.

El grosor de la circunferencia puede ser establecido por la funcin setlinestyle; sin embargo, el estilo de la lnea es ignorado por la funcin circle. La funcin circle no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA; int modo = EGAHI; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); circle( 300, 200, 80 ); getch(); /* Pausa */ closegraph(); }

Juan Carlos Gutirrez Barquero____________________________________________

12

Bismarck Salvador Traa Lpez__________________________________________ UNI

RECTANGULOS.
void far rectangle(int izquierda,int superior, int derecha, int inferior); Esta funcin dibujar un rectngulo sin rellenar su interior usando el color actual. La esquina superior izquierda del rectngulo est definida por los argumentos izquierdos y superiores. Estos argumentos corresponden a los valores x e y de la esquina superior izquierda. Similarmente, los argumentos derecha e inferior definen la esquina inferior derecha del rectngulo. El permetro del rectngulo es dibujado usando el estilo y grosor de lnea actuales.

La funcin rectangle() no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA,modo = EGAHI; initgraph( &driver, &modo, "C:\\tc20\\bin" ); rectangle( 20, 20, 400, 300 ); getch(); /* Pausa */ closegraph(); }

ARCOS
void far arc(int x, int y,int comienzo_angulo, int final_angulo, int radio); Esta funcin crear un arco circular. El arco tiene como centro el punto especificado por los argumentos x e y, y es dibujado con el radio especificado: radio. El arco no est rellanado, pero es dibujado usando el color actual. El arco comienza al ngulo especificado por el argumento comienzo_angulo y es dibujado en la direccin contraria al de las agujas del reloj hasta llegar al ngulo especificado por el argumento final_angulo. La funcin arc usa el este (extendindose hacia la derecha del centro del arco en la direccin horizontal) como su punto de 0 grados. La funcin setlinestyle puede usarse para establecer el grosor del arco. La funcin arc, sin embargo, ignorar el argumento trama de la funcin setlinestyle.

Juan Carlos Gutirrez Barquero____________________________________________

13

Bismarck Salvador Traa Lpez__________________________________________ UNI

La funcin arc no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA,modo = EGAHI,radio; initgraph( &driver, &modo, "C:\\tc20\\bin" ); for( radio = 25; radio < 175; radio += 25 ) arc( 320, 175, 45, 135, radio ); getch(); /* Pausa */ closegraph(); }

PIXELES.
void far putpixel(int x, int y, int color); Esta funcin es usada para colocar a un pxel en una posicin en particular la cual es cuestionada por los argumentos x e y. El argumento color especfico el valor del color del pxel. La funcin putpixel no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA,modo = EGAHI,t; initgraph( &driver, &modo, c:\\tc20\\bin ); for( t=0; t<200; t++ ) putpixel( 100+t, 50+t, t%16 ); getch(); closegraph(); }

ELIPSES.

Juan Carlos Gutirrez Barquero____________________________________________

14

Bismarck Salvador Traa Lpez__________________________________________ UNI

void far ellipse(int x, int y, int comienzo_angulo, int final_angulo, int x_radio, int y_radio); Esta funcin es usada para dibujar un arco elptico en el color actual. El arco elptico est centrado en el punto especificado por los argumentos x e y. Ya que el arco es elptico el argumento x_radio especifica el radio horizontal y el argumento y_radio especifica el radio vertical. El arco elptico comienza con el ngulo especificado por el argumento comienzo_angulo y se extiende en un sentido contrario a las agujas del reloj al ngulo especificado por el argumento final_angulo. La funcin ellipse considera este - el eje horizontal a la derecha del centro del elipse - ser 0 grados. El arco elptico es dibujado con el grosor de lnea actual como es establecido por la funcin setlinestyle. Sin embargo, el estilo de lnea es ignorado por la funcin ellipse. La funcin ellipse no retorna ningn valor. Ejemplo:

#include <graphics.h> #include <conio.h> void main() { int driver = EGA,modo = EGAHI; initgraph( &driver, &modo, "C:\\tc20\\bin" ); ellipse( 300, 150, 45, 225, 100, 50 ); getch(); /* Pausa */ closegraph();

} Funciones bsicas de graphics.h.


Funcin setbkcolor void far setbkcolor(int color); Esta funcin es usada para asignar el color de fondo al valor del color de fondo especificado por el argumento color. Existen varios valores para ciertos colores de fondo. La funcin setbkcolor no retorna ningn valor. Ejemplo:

Juan Carlos Gutirrez Barquero____________________________________________

15

Bismarck Salvador Traa Lpez__________________________________________ UNI

#include <graphics.h> #include <conio.h> void main() { int driver = EGA; int modo = EGAHI; initgraph( &driver, &modo, C:\\TC20\\BIN ); setbkcolor( 4 ); circle( 300, 150, 50 ); getch(); /* Pausa */ closegraph(); getch(); } Funcin getbkcolor. int far getbkcolor(void); Esta funcin es usada para obtener el valor del color de fondo actual. El color de fondo, por defecto, es el color 0. Sin embargo, este valor puede cambiar con una llamada a la funcin setbkcolor. Existen varios valores para ciertos colores de fondo. La funcin getbkcolor retorna el valor del color de fondo actual. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA,modo = EGAHI,color; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); setbkcolor( 4 ); circle( 300, 150, 50 ); color = getbkcolor(); getch(); /* Pausa */ closegraph(); printf( "Color de fondo: %d\n", color ); getch(); } void far setcolor(int color) Esta funcin coloca el atributo color es decir escoge un color entre 0 y 15 o su equivalente en ingls (ver pagina 3 Modo de 16 colores) todo lo que se dibuje despus de esta instruccin tendr el color establecido por la funcin setcolor el valor de esta es funcin es WHITE. Esta funcin no devuelve ningn valor.

Juan Carlos Gutirrez Barquero____________________________________________

16

Bismarck Salvador Traa Lpez__________________________________________ UNI


Ejemplo. # include <graphics.h> # include <dos.h> # include <stdlib.h> # include <conio.h> void main(){ int driver=DETECT,modo,i; initgraph(&driver,&modo,"c:\\tc20\\BIN"); i=0; do { setcolor(i); circle(random(639),random(479),random(i+8));/*Random definida en stdlib*/ delay(30000); /*Detiene la ejecucin del programa durante 30000 milisegundos*/ i=(i<16)?i:0; i++; }while(!kbhit()); } Funcin cleardevices void far cleardevice(void); Esta funcin es usada para despejar una pantalla grfica. La funcin cleardevice usa el color de fondo actual, como es establecido por la funcin setbkcolor, para rellenar la pantalla. La posicin del cursor grfico es la esquina superior izquierda de la pantalla posicin (0,0) - despus de que la pantalla haya sido borrado. La funcin cleardevice no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA; int modo = EGAHI; int relleno, color; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); relleno = 1; color = 1; setlinestyle( SOLID_LINE, relleno, THICK_WIDTH ); circle( 300, 200, 80 ); getch(); /* Pausa */ setbkcolor( color ); cleardevice(); setlinestyle( SOLID_LINE, relleno, THICK_WIDTH ); circle( 400, 200, 20 ); getch(); /* Pausa */ closegraph();

Juan Carlos Gutirrez Barquero____________________________________________

17

Bismarck Salvador Traa Lpez__________________________________________ UNI


getch(); } Funcin getmaxx int far getmaxx(void); Esta funcin es usada para obtener la coordenada mxima de la pantalla en la direccin horizontal. Este valor suele ser la resolucin horizontal mxima menos 1. La funcin getmaxx retorna la coordenada mxima de la pantalla en la direccin horizontal. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA,modo = EGAHI,x_max; initgraph( &driver, &modo, "C:\\TC20\\BIN" ); x_max = getmaxx(); closegraph(); printf( "X mxima: %d\n", x_max ); getch(); } Funcin getmaxy int far getmaxy(void); Esta funcin es usada para obtener la coordenada mxima de la pantalla en la direccin vertical. Este valor suele ser la resolucin vertical mxima menos 1. La funcin getmaxy retorna la coordenada mxima de la pantalla en la direccin vertical. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = VGA; int modo = EGAHI; int x_max, y_max; initgraph( &driver, &modo, C:\\TC20\\BIN ); x_max = getmaxx(); y_max = getmaxy(); closegraph(); printf( "X mxima: %d\tY mxima: %d\n", x_max, y_max ); getch(); }

Juan Carlos Gutirrez Barquero____________________________________________

18

Bismarck Salvador Traa Lpez__________________________________________ UNI

Rellenos
Es el proceso de rellenar una regin de la pantalla con un patrn o color. Turbo C utiliza dos mtodos para definir la regin de rellenos. El primero relleno de polgonos, usa la lista de vrtices del polgono para calcular la geometra del interior, El segundo relleno es por el mtodo de inundacin, busca desde un punto inicial llamado la semilla en todas las direcciones para encontrar una frontera que encierre la regio. La frontera se reconoce como el valor del pxel que tiene. Antes de estudiar los dos mtodos estudiaremos la funcin setfillstyle que ser de gran importancia a la hora de realizar los dos tipos de rellenado y bar que es una funcin similar a rectangle.

Funcin bar
void far bar(int izquierda, int superior, int derecha, int inferior); Esta funcin dibujar una barra rectangular y rellenada de dos dimensiones. La esquina superior izquierda de la barra rectangular est definida por los argumentos izquierdos y superiores. Estos argumentos corresponden a los valores x e y de la esquina superior izquierda. Similarmente, los argumentos derecha e inferior definen la esquina inferior derecha de la barra. La barra no tiene borde, pero es rellenada con la trama de relleno actual y el color de relleno como es establecido por la funcin setlinestyle. La funcin bar no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA,modo = EGAHI, x, y, color,fill; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); x = 20; y = 20; color = 1; fill = 1; do { setfillstyle( fill, color ); bar( x, y, x+40, 320 ); x += 40; y += 10; color = (color+1) % 16; fill = (fill+1) % 12; } while( x < 620 ); getch(); /* Pausa */ closegraph(); } El patrn de relleno se define con las Funcines setfillstyle y setfillpattern

Juan Carlos Gutirrez Barquero____________________________________________

19

Bismarck Salvador Traa Lpez__________________________________________ UNI Funcin setfillstyle


void far setfillstyle(int trama, int color);

Esta funcin es usada para seleccionar una trama predefinida y un color de relleno. El argumento trama especifica la trama predefinida, mientras que el argumento color especifica el color de relleno. Existen trece valores ya definidos para tramas. Sin embargo, la trama USER_FILL (valor 12) no debera usarse para asignar una trama definida por el usuario. En su lugar, se debera usar la funcin setfillpattern. La funcin setfillstyle no retorna ningn valor.
Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA,modo = EGAHI; initgraph( &driver, &modo, "c:\\tc20\\bin" ); setfillstyle( LTSLASH_FILL, 6 ); bar( 50, 50, 350, 300 ); getch(); /* Pausa */ closegraph(); } LTSLASH_FILL es un estilo de relleno si desea estudiarlos se encuentran en el libro(Ver pagina # 5 ).

Funcin setfillpattern
void far setfillpattern(char far *trama, int color); Esta funcin es usada para seleccionar una trama de relleno definido por el usuario. El argumento *trama apunta a una serie de ocho bytes que representa una trama de relleno de bits de 8 x 8. Cada byte representa una fila de ocho bits, donde cada bit est encendido o no (1 0). Un bit de 0 indica que el pxel correspondiente ser asignado el color de relleno actual. Un bit de 0 indica que el pxel correspondiente no ser alterado. El argumento color especifica el color de relleno que ser usado para la trama.

La funcin setfillpattern no retorna ningn valor.


Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA,modo = EGAHI; char trama1[8] = { 0x33, 0xEE, 0x33, 0xEE, 0x33, 0xEE, 0x33, 0xEE }; char trama2[8] = { 0x0A, 0xF0, 0xF0, 0x0A, 0x0A, 0xF0, 0xF0, 0x0A };

Juan Carlos Gutirrez Barquero____________________________________________

20

Bismarck Salvador Traa Lpez__________________________________________ UNI


initgraph( &driver, &modo, "C:\\tc20\\bin" ); bar( 50, 50, 150, 150 ); setfillpattern( trama1, 9 ); bar( 160, 50, 260, 150 ); setfillpattern( trama2, 4 ); bar( 105, 160, 205, 260 ); getch(); /* Pausa */ closegraph(); }

1. Relleno por medio de un polgonos.


void far fillpoly(int numpuntos, int far *puntos); Esta funcin es usada para crear un polgono rellenado. El argumento numpuntos es usado para definir el nmero de puntos en el polgono. Al contrario que la funcin drawpoly, la funcin automticamente cierra el polgono. El argumento *puntos apunta a un array de nmeros de longitud numpuntos multiplicado por 2. Los dos primeros miembros del array identifica las coordenadas x e y del primer punto, respectivamente, mientras que los dos siguientes especifican el siguiente punto, y as sucesivamente. La funcin fillpoly dibuja el permetro del polgono con el estilo de lnea y color actuales. Luego, el polgono es rellenado con la trama de relleno y color de relleno actuales. La funcin fillpoly no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA,modo = EGAHI,trama, color; int puntos[6] = { 300, 50, 500, 300, 100, 300 }; initgraph( &driver, &modo, "C:\\tc20\\bin" ); trama = SLASH_FILL; for(color=0;color<=15;color++) { setfillstyle( trama, color ); fillpoly( 3, puntos ); getch(); } getch(); /* Pausa */ closegraph(); }

/*Este programa te muestra los diferentes colores con una misma trama trata de modificarlo para que obtengas todas las tramas con todos los colores*/

Juan Carlos Gutirrez Barquero____________________________________________

21

Bismarck Salvador Traa Lpez__________________________________________ UNI 2. Relleno por el mtodo de inundacin.


void far floodfill(int x, int y, int borde);
Esta funcin es usada para rellenar un rea cerrado con el color de relleno y trama de relleno actuales. Los argumentos x e y especifican el punto de comienzo para el algoritmo de relleno. El argumento borde especifica el valor del color del borde del rea. Para que la funcin fillpoly Funcione como es esperado, el rea a ser rellenado debe estar rodeada por el color especificado por el argumento borde. Cuando el punto especificado por los argumentos x e y se encuentra dentro del rea a ser rellenada, el interior ser rellenado. Si se encuentra fuera del rea, el exterior ser rellenado. Nota: Esta funcin no Funciona con el driver IBM-8514.La funcin floodfill no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA,modo = EGAHI,trama, color; int puntos[8] = { 300, 50, 500, 300, 100, 300, 300, 50 }; initgraph( &driver, &modo, "C:\\tc20\\bin" ); setcolor( 10 ); /*verde*/ drawpoly( 4, puntos ); trama = SLASH_FILL; for(color = 0;color<=15;color++) { setfillstyle( trama, color ); floodfill( 400, 250, 10 ); getch(); } getch(); /* Pausa */ closegraph(); }

Funcines de coordenadas relativas


Entre ellas tenemos las Funcines moveto, moverel, lineto, linerel, getx, gety. Estudiaremos cada una de ellas para afianzar mas conocimientos. Funcin moveto. void far moveto(int x, int y); Esta funcin es usada para colocar el cursor grfico al punto especificado por los argumentos x e y. Ya que el cursor es movido desde su posicin anterior al punto especificado por los argumentos x e y, no hay dibujo alguno.

Juan Carlos Gutirrez Barquero____________________________________________

22

Bismarck Salvador Traa Lpez__________________________________________ UNI


La funcin moveto no retorna ningn valor.
Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA,modo = EGAHI; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); moveto( 20, 20 ); lineto( 40, 60 ); lineto( 80, 90 ); getch(); closegraph(); } Funcin lineto. void far lineto(int x, int y); Esta funcin es usada para dibujar una lnea recta desde la posicin actual del cursor grfico hasta el punto especificado por los argumentos x e y. La lnea se dibuja usando el estilo de lnea actual, el grosor, y el color actual. Despus de que la lnea recta haya sido dibujado, la posicin del cursor grfico es actualizado a la posicin especificado por los argumentos x e y (el punto final de la lnea). La funcin lineto no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA, modo = EGAHI; initgraph( &driver, &modo, "C:\\tc20\\bin" ); moveto( 20, 20 ); lineto( 40, 60 ); lineto( 80, 90 ); getch(); closegraph(); } Funcin moverel. void far moverel(int dx, int dy); Esta funcin es usada para mover la posicin del cursor grfico a una distancia relativa como los argumentos dx y dy. El argumento dx define la distancia relativa a moverse en la direccin horizontal. El argumento dy define la distancia relativa a moverse en la direccin vertical. Estos valores pueden ser positivos o negativos. No se dibuja ya que el cursor es mudado.

Juan Carlos Gutirrez Barquero____________________________________________

23

Bismarck Salvador Traa Lpez__________________________________________ UNI

La funcin moverel no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA,modo = EGAHI; initgraph( &driver, &modo, "C:\\tc20\\bin" ); moveto( 20, 20 ); linerel( 20, 40 ); moverel( 50, 50 ); linerel( 40, 30 ); getch(); closegraph(); } Funcin linerel. void far linerel(int dx, int dy); Esta funcin es usada para dibujar una lnea recta a una distancia y direccin predeterminadas desde la posicin actual del cursor grfico. El argumento dx especifica el nmero relativo de pxels para atravesar en la direccin horizontal. El argumento dy especifica el nmero relativo de pxels para atravesar en la direccin vertical. Estos argumentos pueden ser tanto valores positivos como negativos. La lnea se dibuja usando el estilo de lnea actual, el grosor, y el color actual desde la posicin actual del cursor grfico a travs de la distancia relativa especificada. Cuando la lnea est terminada, la posicin del cursor grfico es actualizado al ltimo punto de la lnea. La funcin linerel no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA,modo = EGAHI; initgraph( &driver, &modo, "C:\\tc20\\bin" ); moveto( 20, 20 ); linerel( 20, 40 ); linerel( 40, 30 ); getch(); closegraph(); } Funcin getx.

Juan Carlos Gutirrez Barquero____________________________________________

24

Bismarck Salvador Traa Lpez__________________________________________ UNI


int far getx(void); Esta funcin es usada para obtener la posicin, en la direccin horizontal, del cursor grfico. El valor retornado especifica el lugar del pxel horizontal del cursor grfico (la coordenada x), relativo a la pantalla del usuario actual. La funcin getx retorna la coordenada x del cursor grfico. Ejemplo: #include <graphics.h> #include <stdio.h> void main() { int driver = EGA,modo = EGAHI, x, y; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); moveto( 300, 150 ); x = getx(); y = gety(); closegraph(); printf( "Cursor grfico\n\nX: %d\tY: %d\n", x, y ); } Funcin gety. int far gety(void); Esta funcin es usada para obtener la posicin, en la direccin vertical, del cursor grfico. El valor retornado especifica el lugar del pxel vertical del cursor grfico (la coordenada y), relativo a la pantalla del usuario actual. La funcin gety retorna la coordenada y del cursor grfico. Ejemplo: #include <graphics.h> #include <stdio.h> void main() { int driver = EGA,modo = EGAHI, x, y; initgraph( &driver, &modo, C:\\TC20\\BIN ); moveto( 300, 150 ); x = getx(); y = gety(); closegraph(); printf( "Cursor grfico\n\nX: %d\tY: %d\n", x, y ); }

Otras funciones de la librera graphics.h.

Juan Carlos Gutirrez Barquero____________________________________________

25

Bismarck Salvador Traa Lpez__________________________________________ UNI


En este capitulo describimos una a una las libreras de la librera graphics.h. Las funciones sern explicadas mediante un orden. Cuando sabemos como dibujar lneas, crculos, rectngulos, y otras figuras es hora de que empieces a conocer otro tipo de funciones en las cuales no hacen mucho nfasis los profesores como lo son las funciones bar3d, palette y otras que presentan una gran gama de tareas de gran calidad grafica. Dejemos de hablar y comencemos ya que los puedo aburrir.

Funcin bar3d
void far bar3d(int izquierda, int superior,int derecha, int inferior, int profundidad, int banderin_tapa);

Esta funcin crear una barra rectangular y rellenada de tres dimensiones. La esquina superior izquierda de la barra rectangular ms frontal est definida por los argumentos izquierdos y superiores. Estos argumentos corresponden a los valores x e y de la esquina superior izquierda del rectngulo ms frontal. Similarmente, los argumentos derecha e inferior definen la esquina inferior derecha del rectngulo ms frontal. La barra tiene borde, en todas las tres dimensiones, rellenada con el color y estilo de lnea actuales. El rectngulo ms frontal es rellenado usando la trama de relleno actual y el color de relleno como es establecido por la funcin setlinestyle. El argumento banderin_tapa es usado para especificar si es o no es posible apilar varias barras encima de cada una. Si banderin_tapa tiene un valor distinto a cero, entonces la barra est "tapada". Si banderin_tapa tiene un valor de cero, entonces la barra no est "tapada", permitiendo otras barras ser apiladas encima de sta. La funcin bar3d no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA,modo = EGAHI,color, relleno; color = 10; relleno = 11; initgraph(&driver,&modo,"c:\\tc20\\bin"); setfillstyle( relleno, color ); bar3d( 100, 50, 300, 150, 25, 1 ); getch(); /* Pausa */ closegraph(); getch(); }

Funcin clearviewport void far clearviewport(void);

Juan Carlos Gutirrez Barquero____________________________________________

26

Bismarck Salvador Traa Lpez__________________________________________ UNI

Esta funcin es usada para rellenar la pantalla actual del usuario con el color de fondo actual. El color de fondo puede ser establecido con la funcin setbkcolor. La posicin del cursor grfico es la esquina superior izquierda de la pantalla actual del usuario. Esta posicin es (0,0) segn la pantalla actual del usuario. La funcin clearviewport no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int a = EGA,b = EGAHI,color; initgraph( &a, &b, "C:\\tc20\\BIN" ); setviewport( 150, 150, 350, 350, 0 ); for( color = 0; color<16; color++ ) { circle( 100, 100, 60 ); getch(); setbkcolor( color ); clearviewport(); } getch(); /* Pausa */ closegraph(); } Funcin closegraph void far closegraph(void); Esta funcin es usada para cerrar el sistema grfico como es iniciada por la funcin initgraph. La funcin closegraph libera toda la memoria usada por el sistema grfico y luego restaura el modo de vdeo al modo de texto que estaba en uso anteriormente a la llamada a la funcin initgraph. La funcin closegraph no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA,modo = EGAHI; initgraph( &driver, &modo, "C:\\tc20\\BIN); circle( 300, 200, 80 ); getch(); /* Pausa */ closegraph(); getch(); } Funcin detectgraph

Juan Carlos Gutirrez Barquero____________________________________________

27

Bismarck Salvador Traa Lpez__________________________________________ UNI


void far detectgraph(int far *driver, int far *modo); Esta funcin es usada para detectar el adaptador grfico y el modo ptimo para usar con el sistema en uso. Si la funcin detectgraph no puede detectar ningn dispositivo grfico, el argumento *driver es asignado grNotDetected (-2). Una llamada a graphresult resultar en un valor de retorno de -2, o grNotDetected. Existen varios valores que indican los diferentes dispositivos grficos que pueden ser usados por el argumento *driver. Un valor de 0, o DETECT, inicia la Funcinalidad de auto deteccin, el cual determina el driver ptimo a usar. Para cada dispositivo existen varios valores que indican los diferentes modos grficos que pueden ser usados por el argumento *modo. Sin embargo, si el argumento *driver es asignado el valor de 0, o DETECT, el argumento *modo es automticamente establecido al modo de resolucin mas alto para el driver. La funcin detectgraph no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver, modo; detectgraph( &driver, &modo, ); initgraph( &driver, &modo, "C:\\tc20\\BIN" ); circle( 300, 200, 80 ); getch(); /* Pausa */ closegraph(); printf( "Driver: %d\tModo: %d\n\n", driver, modo ); getch(); } Funcin drawpoly void far drawpoly(int numpuntos, int far *puntos); Esta funcin es usada para crear un polgono con un nmero especificado de puntos. El argumento numpuntos es usado para definir el nmero de puntos en el polgono. Para la funcin drawpoly, el nmero de puntos debe ser el nmero actual de puntos ms 1 para poder crear un polgono cerrado. En otras palabras, el primer punto debe ser igual al ltimo punto. El argumento *puntos apunta a un array de nmeros de longitud numpuntos multiplicado por 2. Los dos primeros miembros del array identifica las coordenadas x e y del primer punto, respectivamente, mientras que los dos siguientes especifican el siguiente punto, y as sucesivamente. La funcin drawpoly dibuja el permetro del polgono con el estilo de lnea y color actuales, pero no rellena el polgono. La funcin drawpoly no retorna ningn valor. Ejemplo: #include <graphics.h>

Juan Carlos Gutirrez Barquero____________________________________________

28

Bismarck Salvador Traa Lpez__________________________________________ UNI


#include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; int puntos[8] = { 300, 50, 500, 300, 100, 300, 300, 50 }; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); drawpoly( 4, puntos ); getch(); /* Pausa */ closegraph(); getch(); } Funcin fillellipse void far fillellipse(int x, int y,int x_radio, int y_radio); Esta funcin es usada para dibujar y rellenar una elipse. El centro de la elipse es especificado por los argumentos x e y. El argumento x_radio especifica el radio horizontal y el argumento y_radio especifica el radio vertical de la elipse. La elipse es dibujado con el permetro en el color actual y rellenada con el color de relleno y la trama de relleno actuales. La funcin fillellipse no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void inicializar(void); void main() { int trama, color; inicializar(); trama = SOLID_FILL; color = 4; setfillstyle( trama, color ); fillellipse( 300, 150, 100, 50 ); getch(); /* Pausa */ closegraph(); } void inicializar(void) { int driver = EGA,modo = EGAHI; initgraph( &driver, &modo, "C:\\tc20\\BIn" ); } Funcin getarccords void far getarccoords(struct arccoordstype far *coordenadas_arco);

Juan Carlos Gutirrez Barquero____________________________________________

29

Bismarck Salvador Traa Lpez__________________________________________ UNI

Esta funcin es usada para recoger las coordenadas del centro, y los puntos del comienzo y final de la ltima llamada con xito a la funcin arc. El argumento *coordenadas_arco apunta a la estructura de tipo arccoordstype que guarda la informacin recogida. La sintaxis de la estructura arccoordstype es: struct arccoordstype { int x, y; int xstart, ystart; int xend, yend; }; Los miembros x e y definen el centro del arco. Los miembros xstart e ystart definen las coordenadas x e y del punto de comienzo del arco. Similarmente, los miembros xend e yend definen las coordenadas x e y del punto de final del arco. La funcin getarccoords no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA; int modo = EGAHI,radio; struct arccoordstype info_arco; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); for( radio=25; radio<=100; radio+=25 ) { arc( 300, 150, 45, 315, radio ); getarccoords( &info_arco ); moveto( info_arco.xstart, info_arco.ystart ); lineto( info_arco.xend, info_arco.yend ); } getch(); /* Pausa */ closegraph(); getch(); } Funcin getaspectratio void far getaspectratio(int far *x_proporcion,int far *y_proporcion); Esta funcin es usada para obtener la proporcin anchura-altura del modo grfico actual. La proporcin anchura-altura puede definirse como la proporcin de la anchura del pxel del modo grfico y la altura del pxel. Esta proporcin, usando los modos grficos existentes, es siempre menor o igual que 1. El valor para determinar la proporcin anchura-altura con respecto al eje horizontal es retornado en el argumento *x_proporcion. Similarmente, el valor para el eje vertical es retornado en el argumento *y_proporcion. El argumento *y_proporcion es asignado 10000, el cual es retornado cuando se llama a la funcin getaspectratio. El argumento *x_proporcion es casi siempre menor que el valor de *y_proporcion. Esto es debido al hecho de que la mayora de los

Juan Carlos Gutirrez Barquero____________________________________________

30

Bismarck Salvador Traa Lpez__________________________________________ UNI


modos grficos tiene pxeles ms altos que anchos. La nica excepcin es en los modos de VGA que produce pxeles cuadrados; es decir, x_proporcion = y_proporcion. La funcin getaspectratio no retorna ningn valor, directamente. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA, modo = EGAHI; int x_proporcion, y_proporcion; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); getaspectratio( &x_proporcion, &y_proporcion ); circle( 300, 150, 50 ); getch(); /* Pausa */ closegraph(); printf( "Proporcin anchura-altura.\nFactor x: %d\tFactor y: %d\n", x_proporcion, y_proporcion ); getch(); } Funcin getcolor int far getcolor(void); Esta funcin obtiene el valor del color actual. El color actual es el color usado para dibujar lneas, arcos, etc.. Este color no es el mismo que el color de relleno. El valor del color obtenido es interpretado segn el modo que est en uso. Existen varios valores para ciertos colores de fondo. La funcin getcolor retorna el valor del color actual. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI,color; initgraph( &driver, &modo, "C:\\Tc20\\BIN" ); setcolor( 4 ); circle( 300, 150, 50 ); color = getcolor(); getch(); /* Pausa */ closegraph(); printf( "Color del permetro: %d\n", color ); getch(); }

Juan Carlos Gutirrez Barquero____________________________________________

31

Bismarck Salvador Traa Lpez__________________________________________ UNI

Funcin getdefaultpalette struct palettetype far *getdefaultpalette(void); Esta funcin es usada para obtener una estructura que define la paleta segn el dispositivo en la inicializacin - esto es, cuando se llama a initgraph. La estructura palettetype se define de la siguiente manera: #define MAXCOLORS 15 struct palettetype { unsigned char size; signed char colors[MAXCOLORS+1]; } El campo size indica el tamao de la paleta. El campo colors contiene los valores numricos que representan los colores que ofrece el dispositivo en su paleta de colores. La funcin getdefaultpalette retorna un puntero a una estructura del tipo palettetype. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; struct palettetype *palette = NULL; int i; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); palette = getpalettetype(); circle( 300, 150, 50 ); getch(); /* Pausa */ closegraph(); printf( "Paleta\n\nTamao: %d\nColores: %d", palette->size, palette->colors[0] ); for( i=1; i<palette->size; i++ ) printf( ", %d", palette->colors[i] ); printf( "\n" ); getch(); }

Funcin getdrivename char *far getdrivername(void);

Juan Carlos Gutirrez Barquero____________________________________________

32

Bismarck Salvador Traa Lpez__________________________________________ UNI

Esta funcin es usada para obtener una cadena de caracteres que contiene el nombre del dispositivo grfico actual. Esta funcin debera ser llamada despus de que un dispositivo haya sido definido e inicializado esto es, despus de llamar a initgraph. La funcin getdrivername retorna una cadena de caracteres conteniendo el nombre del dispositivo grfico. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> #include <string.h> void main() { int driver = EGA, modo = EGAHI; char *nombre; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); strcpy( nombre, getdrivername() ); circle( 300, 150, 50 ); getch(); /* Pausa */ closegraph(); printf( "Nombre del dispositivo grfico: %s\n", nombre ); getch();} Funcin getfillpattern void far getfillpattern(char far *trama); Esta funcin es usada para obtener una trama de relleno definido por el usuario, como es definida por la funcin setfillpattern, y la guarda en memoria. El argumento *trama es un puntero a una serie de ocho bytes que representa una trama de relleno de bits de 8 x 8. Cada byte representa una fila de ocho bits, donde cada bit est encendido o no (1 0). Un bit de 0 indica que el pxel correspondiente ser asignado el color de relleno actual. Un bit de 0 indica que el pxel correspondiente no ser alterado. La funcin getfillpattern no retorna ningn valor, directamente. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA; int modo = EGAHI; char trama1[8] = { 0x33, 0xEE, 0x33, 0xEE, 0x33, 0xEE, 0x33, 0xEE }; char trama2[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; initgraph( &driver, &modo, "C:\\tc20\\bin" ); getfillpattern( trama2 ); bar( 50, 50, 150, 150 ); setfillpattern( trama1, 9 );

Juan Carlos Gutirrez Barquero____________________________________________

33

Bismarck Salvador Traa Lpez__________________________________________ UNI


bar( 160, 50, 260, 150 ); setfillpattern( trama2, 4 ); bar( 105, 160, 205, 260 ); getch(); /* Pausa */ closegraph(); getch(); } Funcin getfillsettings void far getfillsettings(struct fillsettingstype far *info); Esta funcin es usada para obtener la informacin de tramas de relleno. El argumento *info apunta a una estructura de tipo fillsettingstype, el cual es actualizado cuando se llama a la funcin getfillsettings. La estructura es: struct fillsettingstype { int pattern; int color; }; El campo pattern es la trama y el campo color es el color de relleno de la trama. Existen trece valores ya definidos para tramas. La funcin getfillsettings no retorna ningn valor, directamente. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; struct fillsettingstype info; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); getfillsettings( &info ); bar( 50, 50, 350, 300 ); getch(); /* Pausa */ closegraph(); printf( "Trama de relleno: %d\tColor de relleno: %d\n", info.pattern, info.color ); getch(); }

Funcin getgraphmode int far getgraphmode(void);

Juan Carlos Gutirrez Barquero____________________________________________

34

Bismarck Salvador Traa Lpez__________________________________________ UNI

Esta funcin es usada para obtener el valor del modo grfico actual. El dispositivo actual debe ser considerado cuando se interprete el valor de retorno. Esta funcin slo debera ser llamada despus de que el sistema grfico haya sido inicializado con la funcin initgraph. Existen varios valores para los modos de cada dispositivo. La funcin getgraphmode retorna el modo grfico como es establecido por initgraph o setgraphmode. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA, modo = EGAHI,modo; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); modo = getgraphmode(); bar( 50, 50, 350, 300 ); getch(); /* Pausa */ closegraph(); printf( "Modo grfico: %d\n", modo ); getch(); } Funcin getlinesettings void far getlinesettings(struct linesettingstype far *info); Esta funcin obtiene la informacin actual para las lneas. Esta informacin es guardada en una estructura de tipo linesettingstype que es apuntado por el argumento *info. El estilo de lnea, trama, y grosor actuales son guardados en esta estructura. La sintaxis para la estructura linesettingstype: struct linesettingstype { int linestyle; unsigned upattern; int thickness; } El campo linestyle es el estilo de la lnea recta. El campo upattern es la trama de la lnea del usuario solamente cuando el campo linestyle es igual a USERBIT_LINE, 4. Cuando esto sea el caso, el miembro upattern contiene una trama de lnea definido por el usuario de 16 bits. Un bit 1 en esta trama indica que el pxel correspondiente ser asignado el color actual. Un bit 0 indica que el pxel correspondiente no ser alterado. El campo thickness es el grosor de la lnea. Existen varios valores para los diferentes estilos y grosores de lneas rectas. La funcin getlinesettings no retorna ningn valor, directamente. Ejemplo:

Juan Carlos Gutirrez Barquero____________________________________________

35

Bismarck Salvador Traa Lpez__________________________________________ UNI

#include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; struct linesettingstype info; initgraph( &driver, &modo, "C:\\tc20\\bin" ); setlinestyle( DOTTED_LINE, 0xFF33, THICK_WIDTH ); circle( 350, 250, 50 ); getlinesettings( &info ); getch(); /* Pausa */ closegraph(); printf( "Lneas rectas.\nEstilo: %d\tTrama: %X\tGrosor: %d\n", info.linestyle, info.upattern, info.thickness ); getch(); } Funcin getmaxcolor int far getmaxcolor(void); Esta funcin es usada para obtener el valor ms alto de color en la paleta actual. La paleta en uso depende del dispositivo y modo inicializados. Para los modos de 16 colores, el valor de retorno es 15. Similarmente, para los modos de dos colores, el valor de retorno es 1. La funcin getmaxcolor retorna el valor mximo del color en la paleta en uso. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver =EGA,modo =EGAH,color_max; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); color_max = getmaxcolor(); closegraph(); printf( "Color m ximo: %d\n", color_max ); getch(); }

Funcin getmodename char *far getmodename(int num_modo);

Juan Carlos Gutirrez Barquero____________________________________________

36

Bismarck Salvador Traa Lpez__________________________________________ UNI

Esta funcin es usada para obtener el nombre del modo grfico especificado por el argumento num_modo. La funcin getmodename retorna el nombre del modo grfico que est contenido en todos los dispositivos grficos. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> #include <string.h> void main() { int driver = IBM8514; int modo = IBM8514HI,i; char *nombre; int num_modo; initgraph( &driver, &modo,"C:\\TC20\\BIN"); num_modo = getgraphmode(); strcpy(nombre,getmodename(num_modo)); closegraph(); for(i=0;nombre[i];i++) printf("%c",nombre[i]); getch(); } Funcin getmoderange void far getmoderange(int driver, int far *modo_bajo, int far *modo_alto); Esta funcin es usada para obtener los valores altos y bajos del modo grfico del dispositivo especificado por el argumento driver. El valor ms bajo del modo es retornado en *modo_bajo, y el valor ms alto del modo es retornado en *modo_alto. Si el dispositivo especificado es invlido, el valor de -1 es retornado en ambos argumentos: *modo_bajo y *modo_alto. Sin embargo, si el argumento driver es asignado -1, los modos alto y bajo del dispositivo actual son retornados. La funcin getmoderange no retorna ningn valor, directamente. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; int modo_bajo, modo_alto; initgraph( &driver, &modo, C:\\TC20\\BIN ); getmoderange( driver, &modo_bajo, &modo_alto ); closegraph();

Juan Carlos Gutirrez Barquero____________________________________________

37

Bismarck Salvador Traa Lpez__________________________________________ UNI


printf( "Alcance de modos, de %d %d\n", modo_bajo, modo_alto ); getch(); } Funcin getpalette void far getpalette(struct palettetype far *paleta); Esta funcin es usada para obtener la informacin de la paleta actual. El argumento *paleta apunta a una estructura del tipo palettetype donde la informacin de la paleta es guardada. La estructura palettetype se define de la siguiente manera: #define MAXCOLORS 15 struct palettetype { unsigned char size; signed char colors[MAXCOLORS+1]; } El campo size indica el nmero de colores en la paleta. El campo colors contiene los valores numricos que representan los colores que ofrece el dispositivo en su paleta de colores. La funcin getpalette no retorna ningn valor, directamente. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI,i; struct palettetype palette; initgraph( &driver, &modo, "C:\\TC20\\BIN" ); getpalette( &palette ); closegraph(); printf( "\t\t\t\t\tPaleta\n\nTamao: %d\n",palette.size); printf("Colores: %d,",palette.colors[0] ); for( i=1; i<palette.size; i++ ) printf( "%d, ", palette.colors[i] ); printf( "\n" ); getch(); }

Funcin getpalettesize int far getpalettesize(void);

Juan Carlos Gutirrez Barquero____________________________________________

38

Bismarck Salvador Traa Lpez__________________________________________ UNI

Esta funcin es usada para obtener el nmero de entradas de paleta vlidas para la paleta actual, considerando el modo grfico en uso. La funcin getpalettesize retorna el nmero de colores en la paleta actual. Para modos de 16 colores, la funcin getpalettesize retorna 16. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; int num_colores; initgraph( &driver, &modo, C:\\TC20\\BIN ); num_colores = getpalettesize(); closegraph(); printf( "Paleta\n\nNmero de colores: %d\n", num_colores ); getch(); } Funcin getpixel unsigned far getpixel(int x, int y); Esta funcin es usada para obtener el valor del color del pxel especificado por los argumentos x e y. Estos argumentos especifican las coordenadas de la pantalla del pxel a ser evaluado. Cuando se evala el valor del color retornado, el modo grfico en uso debe ser considerado. Existen varios valores para describir colores. La funcin getpixel retorna el nmero del color del pxel especificado. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA, modo = EGAHI, x, y, color; initgraph( &driver, &modo, C:\\TC20\\BIN ); x = 300; y = 100; setfillstyle( SOLID_FILL, 2 ); fillellipse( 300, 160, 50, 150 ); color = getpixel( x, y ); getch(); closegraph(); printf( "Colores\n\nEl color del pxel (%d,%d): %d\n", x, y, color ); getch();

Juan Carlos Gutirrez Barquero____________________________________________

39

Bismarck Salvador Traa Lpez__________________________________________ UNI


} Funcin gettextsettings void far gettextsettings(struct textsettingstype far *info); Esta funcin es usada para obtener informacin acerca de la fuente grfica actual. Esta informacin es guardada en una estructura de tipo textsettingstype, la cual es apuntada por el argumento *info. Esta estructura contiene informacin de la fuente actual en uso, la orientacin del texto, el tamao del carcter, y la justificacin horizontal y vertical. La sntaxis de la estructura textsettingstype es la siguiente: struct textsettingstype { int font; int direction; int charsize; int horiz; int vert; }; Existen varios valores para describir el tipo, la orientacin, y justificacin de fuentes. La funcin gettextsettings no retorna ningn valor. Ejemplo: #include <graphics.h> # include<conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; struct textsettingstype info; initgraph( &driver, &modo, "C:\\TC20\\BIN" ); gettextsettings( &info ); closegraph(); printf( "Texto\n\nFuente: %d\tSentido: %d\tTamao: %d\n""Justificacin:\nHorizontal: %d, Vertical: %d\n", info.font, info.direction, info.charsize, info.horiz, info.vert); getch(); } Funcin getviewsettings void far getviewsettings(struct viewporttype far *info); Esta funcin es usada para obtener informacin acerca del rea grfica actual. Esta informacin es guardada en una estructura de tipo viewporttype, la cual es apuntada por el argumento *info. Esta estructura contiene informacin acerca de las esquinas superior izquierda e inferior derecha, tambin como el bandern de recorte del rea grfica. La sntaxis de la estructura viewporttype es la siguiente:

Juan Carlos Gutirrez Barquero____________________________________________

40

Bismarck Salvador Traa Lpez__________________________________________ UNI

struct viewporttype { int left, top; int right, bottom; int clip; }; La funcin getviewsettings no retorna ningn valor, directamente. Ejemplo: #include <graphics.h> # include<conio.h> #include <stdio.h> void main() { int driver = VGA, modo = VGAHI; struct viewporttype info; initgraph( &driver, &modo, "C:\\TC20\\BIN" ); getviewsettings( &info ); closegraph(); printf( "\t\t\t\tPantalla\n\nIzquierda: %d\tSuperior: %d\tDerecha: %d\t" "Inferior: %d\tBandern: %d\n", info.left, info.top, info.right, info.bottom, info.clip ); getch(); } Funcin graphdefaults void far graphdefaults(void); Esta funcin es usada para reiniciar todos los datos grficos a sus valores originales, o por defecto. La funcin graphdefaults reinicia la pantalla del usuario para que cubra la pantalla entera, mueve el cursor a la posicin (0,0), y reinicia la paleta actual a sus colores por defecto. Tambin reinicia el color de fondo y el actual a sus valores por defecto, reinicia el estilo y trama de relleno a sus valores por defecto, y reinicia la fuente y justificacin de texto. La funcin graphdefaults no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = VGA; int modo = VGAHI; initgraph( &driver, &modo, "C:\\TC20\\BIN" ); setcolor( 4 ); setviewport( 250, 150, 350, 250, 1 ); graphdefaults(); circle( 300, 200, 50 );

Juan Carlos Gutirrez Barquero____________________________________________

41

Bismarck Salvador Traa Lpez__________________________________________ UNI


getch(); closegraph(); getch(); } Funcin grapherrormsg char *far grapherrormsg(int codigo_error); Esta funcin es usada para obtener una cadena de caracteres conteniendo el mensaje de error para un cdigo de error especificado. El argumento codigo_error especfica el valor del cdigo de error. La funcin graphresult debe ser usada para obtener el cdigo de error usado para el argumento codigo_error. La funcin grapherrormsg retorna una cadena de caracteres. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; int codigo_error; char *mensaje_error; initgraph( &driver, &modo, C:\\TC20\\BIN ); setgraphmode( 40 ); /* Creamos un ERROR */ codigo_error = graphresult(); strcpy( mensaje_error, grapherrormsg( codigo_error ) ); closegraph(); printf( "ERROR: \"%s\" (%d)\n", mensaje_error, codigo_error ); getch(); } Funcin graphfreemem void far _graphfreemem(void far *ptr, unsigned tamanyo); Esta funcin es usada por la librera grfica para desadjudicar memoria previamente reservada mediante una llamada a la funcin _graphgetmem. Esta funcin es llamada por la librera grfica cuando se quiere liberar memoria. Por defecto, la funcin simplemente llama a free, pero se puede controlar la administracin de memoria de la librera grfica. La forma de hacer esto es simplemente creando la definicin de la funcin, con el mismo prototipo mostrado aqu. La funcin _graphfreemem no retorna ningn valor. Ejemplo: #include <graphics.h>

Juan Carlos Gutirrez Barquero____________________________________________

42

Bismarck Salvador Traa Lpez__________________________________________ UNI


#include <conio.h> #include <stdio.h> #include <stdlib.h> void far _graphfreemem( void far *ptr, unsigned tamanyo ) { printf( "__graphfreemem ha sido llamado para " "desadjudicar %d bytes en memoria\n" ); printf( "para el montn (heap) interno\n", tamanyo ); printf( "Pulse cualquier tecla...\n\n" ); getch(); free( ptr ); } void far * far _graphgetmem( unsigned tamanyo ) { printf( "__graphgetmem ha sido llamado para " "adjudicar %d bytes en memoria\n" ); printf( "para el montn (heap) interno\n", tamanyo ); printf( "Pulse cualquier tecla...\n\n" ); getch(); return malloc( tamanyo ); } void main() { int driver = EGA,modo = EGAHI; initgraph( &driver, &modo, C:\\TC20\\BIN ); circle( 200, 100, 50 ); getch(); closegraph(); getch(); } Funcin graphgetmem void far * far _graphgetmem(unsigned tamanyo); Esta funcin es usada por la librera grfica para adjudicar memoria grfica para bferes internos, dispositivos grficos, y fuentes. Esta funcin tiene como intencin ser llamada por la librera grfica cuando se quiere adjudicar memoria. Por defecto, la funcin simplemente llama a malloc, pero se puede controlar la administracin de memoria de la librera grfica. La forma de hacer esto es simplemente creando la definicin de la funcin, con el mismo prototipo mostrado aqu. La funcin _graphgetmem no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> #include <stdlib.h> void far _graphfreemem( void far *ptr, unsigned tamanyo ) { printf( "__graphfreemem ha sido llamado para " "desadjudicar %d bytes en memoria\n" ); printf( "para el montn (heap) interno\n", tamanyo );

Juan Carlos Gutirrez Barquero____________________________________________

43

Bismarck Salvador Traa Lpez__________________________________________ UNI


printf( "Pulse cualquier tecla...\n\n" ); getch(); free( ptr ); } void far * far _graphgetmem( unsigned tamanyo ) { printf( "__graphgetmem ha sido llamado para " "adjudicar %d bytes en memoria\n" ); printf( "para el montn (heap) interno\n", tamanyo ); printf( "Pulse cualquier tecla...\n\n" ); getch(); return malloc( tamanyo ); } void main() { int driver = EGA, modo = EGAHI; initgraph( &driver, &modo, C:\\TC20\\BIN ); circle( 200, 100, 50 ); getch(); closegraph(); getch(); } Funcin graphresult int far graphresult(void); Esta funcin obtiene y retorna el cdigo de error para la ltima llamada sin xito. Adems, reinicia el nivel de error a 0, o grOk. Existen varios valores de cdigos de error. La funcin graphresult retorna el cdigo de error de la ltima llamada grfica sin xito. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; int codigo_error; char *mensaje_error; initgraph( &driver, &modo, "C:\\TC20\\BIN" ); setgraphmode( 40 ); /* Creamos un ERROR debe de ser 0 o 1*/ codigo_error = graphresult(); strcpy( mensaje_error, grapherrormsg( codigo_error ) ); closegraph(); printf( "ERROR: \"%s\" (%d)\n", mensaje_error, codigo_error ); getch(); } Funcin installuserdriver

Juan Carlos Gutirrez Barquero____________________________________________

44

Bismarck Salvador Traa Lpez__________________________________________ UNI


int far installuserdriver(char far *nombre, int huge (*detectar)(void)); Esta funcin permite al usuario aadir dispositivos adicionales de otras compaas o grupos a la tabla interna BGI de los dispositivos. El argumento *nombre define el nombre del fichero nuevo del dispositivo .BGI. El parmetro *detectar es un puntero a una funcin opcional para autodetectar que puede ser o no ser provisto con el dispositivo nuevo. La funcin de autodetectacin espera no recibir ningn parmetro y retorna un valor entero. La funcin installuserdriver retorna el parmetro del nmero del dispositivo que hubiese sido pasado a la funcin initgraph para seleccionar un dispositivo nuevo. Ejemplo: /* Este programa no Funcionar, ya que se necesitara otra tarjeta grfica desconocida por las libreras grficas de BGI. Esto slo es para poner un ejemplo.*/ #include <graphics.h> #include <conio.h> int huge detectarSMGGA( void ) { int driver, modo, modo_sugerirdo=0; detectgraph( &driver, &modo ); if( SMGGA == driver ) return modo_sugerido; return grError; } void main() { int driver, modo; /* Intentamos instalar nuestra tarjeta grfica: ** Sper Mega Guay Graphics Array (SMGGA) ** Ya s que suena muy cursi, pero esto slo es un ejemplo :) */ driver = installuserdriver( "SMGGA", detectarSMGGA ); /* Forzamos a que use nuestra funcin para autodetectar */ driver = DETECT; initgraph( &driver, &modo, C:\\TC20\\BIN ); closegraph(); getch(); } Funcin installuserfont int far installuserfont(char far *nombre); Esta funcin carga un fichero de fuente escalable que no est provisto con el sistema BGI. El parmetro *nombre especifica el nombre del fichero fuente a cargar, en el directorio de inicio. El sistema grfico puede tener hasta veinte fuentes instaladas a la vez.

Juan Carlos Gutirrez Barquero____________________________________________

45

Bismarck Salvador Traa Lpez__________________________________________ UNI


La funcin installuserfont retorna el nmero de identificacin de la fuente que es usada para seccionar la fuente nueva a travs de la funcin settextstyle. Si la tabla interna de fuentes est llena, un valor de -11 (grError) es retornado, indicando un error. Ejemplo /* Este programa no Funcionar, ya que se * necesitara tener una fuente nueva * y desconocida por las libreras grficas de BGI. * Esto slo es para poner un ejemplo. */ #include <graphics.h> #include<stdio.h> # include<conio.h> void main() { int driver = EGA; int modo = EGAHI; int fuente_SMCF; initgraph( &driver, &modo,"C:\\TC20\\BIN" ); /* Intentamos instalar nuestra fuente nueva: ** Sper Mega Chula Fuente (SMCF) ** Ya s que suena muy cursi, pero esto slo es un ejemplo :) */ if( (fuente_SMGF = installuserfont( "SMGF.CHR" )) != grError ){ settextstyle( fuente_SMGF, HORIZ_DIR, 4 ); printf("Instalacin completada");getch();} else{ settextstyle( DEFAULT_FONT, HORIZ_DIR, 4 ); printf("Error de al instalar la aplicacin");getch();} closegraph(); getch(); } Funcin kbhit int kbhit(void); Revisa si se ha presionado una tecla. Cualesquier pulsadas disponibles pueden ser recogidas con las Funciones getch o getche. La funcin kbhit retorna 0 si no se ha registrado una pulsada de tecla; si lo fue, entonces el valor retornado es distinto a cero. Veremos el uso de esta funcin en el modo grafico; para utilizar esta funcin se tiene que declarar la cabecera conio.h

Ejemplo:

Juan Carlos Gutirrez Barquero____________________________________________

46

Bismarck Salvador Traa Lpez__________________________________________ UNI

#include <graphics.h> #include <conio.h> # include <dos.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI,i; initgraph( &driver, &modo, "C:\\TC20\\BIN" ); setcolor(BLUE); i=1; do{ delay(30000); rectangle(10+i,10,100+i,100); setfillstyle(i,BLUE); floodfill(20,20,BLUE); i++; }while(!kbhit()); } Funcin outtext void far outtext(char far *cadena_texto); Esta funcin es usada para mostrar una cadena de caracteres. El argumento *cadena_texto define la cadena de texto a ser mostrado. La cadena es mostrado donde est el cursor grfico actualmente usando el color actual y fuente, direccin, valores, y justificaciones de texto. La posicin del cursor permanece sin ser cambiado al menos que la justificacin horizontal actual es LEFT_TEXT y la orientacin del texto es HORIZ_DIR. Cuando esto sea el caso, la posicin del cursor es colocada horizontalmente a la anchura del pxel de la cadena de texto. Adems, cuando se use la fuente por defecto, cualquier texto que se extiende a fuera del rea grfica actual es truncado. Aunque la funcin outtext est diseada para texto sin formato, texto con formato puede ser mostrada a travs del uso de un bfer de caracteres y la funcin sprintf. La funcin outtext no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; char mensaje[40]; char nombre[25]; printf( "Escribe tu nombre: " ); scanf( "%s", nombre ); sprintf( mensaje, "Hola %s!", nombre ); initgraph( &driver, &modo, C:\\TC20\\BIN ); outtext( mensaje );

Juan Carlos Gutirrez Barquero____________________________________________

47

Bismarck Salvador Traa Lpez__________________________________________ UNI


outtextxy( 300, 150, mensaje ); getch(); closegraph(); getch(); } Funcin outtextxy void far outtextxy(int x, int y, char far *cadena_texto); Esta funcin es usada para mostrar una cadena de caracteres. El argumento *cadena_texto define la cadena de texto a ser mostrado. La cadena es mostrada en la posicin descrita por los argumentos x e y usando el color actual y fuente, direccin, valores, y justificaciones de texto. Cuando se use la fuente por defecto, cualquier texto que se extiende fuera del rea grfica actual es truncado. Aunque la funcin outtextxy est diseada para texto sin formato, texto con formato puede ser mostrada a travs del uso de un bfer de caracteres y la funcin sprintf. La funcin outtextxy no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; char mensaje[40]; char nombre[25]; printf( "Escribe tu nombre: " ); scanf( "%s", nombre ); sprintf( mensaje, "Hola %s!", nombre ); initgraph( &driver, &modo, C:\\TC20\\BIN ); outtext( mensaje ); outtextxy( 300, 150, mensaje ); getch(); closegraph(); getch(); } Funcin pieslice void far pieslice(int x, int y,int comienzo_angulo, int final_angulo, int radio); Esta funcin es usada para dibujar y rellenar un una cua circular. La cua circular est centrada en el punto especificado por los argumentos x e y. La porcin circular de la cua comienza con el ngulo especificado por el argumento comienzo_angulo y se extiende en un sentido contrario a las agujas del reloj al ngulo especificado por el argumento final_angulo. La funcin pieslice considera este el eje horizontal a la derecha del centro

Juan Carlos Gutirrez Barquero____________________________________________

48

Bismarck Salvador Traa Lpez__________________________________________ UNI


como su punto de referencia de 0 grados. El permetro de la cua es dibujado con el color actual y es rellenado con la trama y color de relleno actual. La funcin pieslice no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA; int modo = EGAHI; initgraph( &driver, &modo, C:\\TC20\\BIN ); pieslice( 300, 150, 45, 225, 50 ); getch(); /* Pausa */ closegraph(); getch(); } Funcin registerbgidriver int registerbgidriver(void (*driver)(void)); Esta funcin es usada para cargar y registrar un dispositivo grfico. El argumento *driver apunta a un dispositivo. Un fichero de dispositivo registrado puede ser tanto cargado desde el disco o convertido en un formato .OBJ y ligado (o enlazado) dentro del programa. Registrando el dispositivo de esta manera, el fichero .EXE no depende de un fichero externo de dispositivo para poder ejecutarse. La funcin registerbgidriver retorna nmero del dispositivo cuando tiene xito. Un cdigo de error, un nmero negativo, es retornado si el dispositivo especificado es invlido. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA; int modo = EGAHI; registerbgidriver(IBM8514LO); initgraph( &driver, &modo, "C:\\TC20\\BIN" ); rectangle( 20, 20, 400, 300 ); getch(); /* Pausa */ closegraph(); getch(); }

Juan Carlos Gutirrez Barquero____________________________________________

49

Bismarck Salvador Traa Lpez__________________________________________ UNI


Funcin registerbgifont int registerbgifont(void (*fuente)(void)); Esta funcin es usada para informar al sistema que la fuente apuntada por el argumento *fuente fue incluida durante el enlazo. Un fichero de fuente registrado ha de ser convertido en un fichero objeto .OBJ y ligado (o enlazado) dentro del programa. Registrando la fuente de esta manera, el fichero .EXE no depende de un fichero externo de fuentes para poder ejecutarse. Nota: La fuente de defecto es la nica que est disponible en el programa, ya que forma parte del sistema grfico; no es necesario ligarlo al programa. La funcin registerbgifont retorna nmero del dispositivo cuando tiene xito. Un cdigo de error, un nmero negativo, es retornado si el dispositivo especificado es invlido. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA; int modo = EGAHI; registerbgifont(1); initgraph( &driver, &modo,"C:\\TC20\\BIN" ); outtext( "Esto es una prueba con la fuente \"Sans Serif\"" ); getch(); /* Pausa */ closegraph(); getch(); } Funcin restorecrtmode void far restorecrtmode(void); Esta funcin es usada para reiniciar el modo grfico del vdeo al modo en uso anterior a la inicializacin del sistema grfico. Esta funcin suele ser usada en conjuncin con la funcin setgraphmode para cambiar entre ambos modos de texto y de grficos. La funcin restorecrtmode no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; initgraph( &driver, &modo, C:\\TC20\\BIN ); outtext( "Esto es una prueba para cambiar entre modo grfico..." );

Juan Carlos Gutirrez Barquero____________________________________________

50

Bismarck Salvador Traa Lpez__________________________________________ UNI


getch(); restorecrtmode(); printf( "...y en modo texto.\nPulsa una tecla para volver\n" ); getch(); setgraphmode( modo ); rectangle( 200, 100, 400, 250 ); getch(); /* Pausa */ closegraph(); getch(); } Funcin sector void far sector(int x, int y, int comienzo_angulo, int final_angulo, int x_radio, int y_radio); Esta funcin es usada para dibujar y rellenar la parte de una elipse. El centro de la cua elptica es especificado por los argumentos x e y. El argumento x_radio especifica el radio horizontal y el argumento y_radio especifica el radio vertical de la cua elptica. La cua elptica comienza al ngulo especificado por el argumento comienzo_angulo y es dibujado en la direccin contraria al de las agujas del reloj hasta llegar al ngulo especificado por el argumento final_angulo. La cua elptica es dibujado con el permetro en el color actual y rellenada con el color de relleno y la trama de relleno actuales. La funcin sector no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA; int modo = EGAHI; initgraph( &driver, &modo, C:\\TC20\\BIN ); setfillstyle( SOLID_FILL, 6 ); sector( 300, 150, 45, -45, 150, 50 ); getch(); /* Pausa */ closegraph(); getch(); } Funcin setactivepage void far setactivepage(int pagina); Esta funcin es usada para especificar un nmero de pgina que representa una seccin de memoria del vdeo donde todos los datos grficos para mostrar son enviados. Est seccin de memoria se denomina una pgina activa. El argumento pagina especfica el nmero de la pgina activa. Para usar esta funcin con eficacia, el adaptador de vdeo usado debe ser EGA o VGA y tener suficiente memoria para soportar mltiples pginas para grficos. Esta funcin es usada con la funcin setvisualpage para dibujar pginas no visuales y para crear animacin.

Juan Carlos Gutirrez Barquero____________________________________________

51

Bismarck Salvador Traa Lpez__________________________________________ UNI


La funcin setactivepage no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; int visual=1; printf( "Instrucciones:\nPulsa el espacio para cambiar de " "pgina, cualquier otra tecla para salir\n" ); printf( "(Pulsa cualquier tecla para entrar en modo grfico)\n" ); getch(); initgraph( &driver, &modo, "C:\\TC20\\BIN" ); setactivepage( 0 ); setfillstyle( SOLID_FILL, 6 ); sector( 300, 150, 45, 315, 150, 50 ); setactivepage( 1 ); setfillstyle( SOLID_FILL, 6 ); sector( 300, 150, 90, 270, 150, 50 ); while( getch() == ' ' ) { setvisualpage( visual ); visual = 0==visual ? 1 : 0; } closegraph(); getch(); } Funcin setallpalette void far setallpalette(struct palettetype far *paleta); Esta funcin es usada para asignar la paleta actual a la paleta definida en la estructura del tipo palettetype que es apuntado por el argumento *paleta. Todos los colores de la paleta actual son asignados a aqullos definidos en la estructura palettetype. La sntaxis de la estructura palettetype es: #define MAXCOLORS 15 struct palettetype { unsigned char size; signed char colors[MAXCOLORS+1]; } El campo size indica el nmero de colores de la paleta actual. El campo colors es un array que contiene los valores numricos que representan los colores que ofrece el dispositivo en su paleta de colores. Si la entrada de cualquier elemento del array es -1, el valor del color de ese elemento no cambiar.

Juan Carlos Gutirrez Barquero____________________________________________

52

Bismarck Salvador Traa Lpez__________________________________________ UNI


Nota: Recuerda que todos los cambios hechos a la paleta tiene un efecto visual inmediato y que la funcin setallpalette no debera usarse con el dispositivo IBM-8514. La funcin setallpalette no retorna ningn valor; sin embargo, si los valores pasados son invlidos, entonces la funcin graphresult retorna grError (-11) y la paleta no es alterada. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA; int modo = EGAHI; struct palettetype palette; int size, temp, i, y=0; initgraph( &driver, &modo, C:\\TC20\\BIN ); getpalette( &palette ); size = palette.size; for( i=0; i<size; i++ ) { y += 30; setcolor( palette.colors[i] ); line( 20, y, 520, y ); } getch(); /* Pausa */ for( i=0; i<size/2; i++ ) { temp = palette.colors[i]; palette.colors[i] = palette.colors[size-1-i]; palette.colors[size-1-i] = temp; } setallpalette( &palette ); getch(); /* Pausa */ closegraph(); getch(); } Funcin setaspectratio void far setaspectratio(int x_proporcion, int y_proporcion); Esta funcin es usada para modificar la proporcin anchura-altura del modo grfico actual. La proporcin anchura-altura puede definirse como la proporcin de la anchura del pxel del modo grfico y la altura del pxel. Esta proporcin es usada por el sistema grfico para calcular crculos y arcos. Por ello, alterando la proporcin anchura-altura afectar la visualizacin de estas Funciones. La funcin getaspectratio puede ser usada para obtener las opciones por defecto del modo actual anteriormente a ser modificados. La funcin setaspectratio no retorna ningn valor. Ejemplo: #include <graphics.h>

Juan Carlos Gutirrez Barquero____________________________________________

53

Bismarck Salvador Traa Lpez__________________________________________ UNI


#include <conio.h> void main() { int driver = EGA, modo = EGAHI,x_proporcion, y_proporcion; initgraph( &driver, &modo, C:\\TC20\\BIN ); getaspectratio( &x_proporcion, &y_proporcion ); circle( 300, 150, 50 ); getch(); /* Pausa */ setaspectratio( 2*x_proporcion, y_proporcion ); circle( 300, 150, 50 ); getch(); /* Pausa */ closegraph(); getch(); } Funcin setgraphbufsize unsigned far setgraphbufsize(unsigned bufer_tam); Esta funcin es usada para cambiar el tamao del bfer grfico interno como es asignado por la funcin initgraph cuando el sistema grfico es inicializado. El bfer grfico es usado por varias Funciones grficos; por ello, se debera tener un mayor cuidado cuando se altera este bfer del tamao por defecto de 4096. La funcin setgraphbufsize se debera llamar antes de llamar a la funcin initgraph. La funcin setgraphbufsize retorna el tamao anterior del bfer grfico interno. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; int buf_inicial, buf_nuevo=10000; initgraph( &driver, &modo, C:\\TC20\\BIN ); buf_inicial = setgraphbufsize( buf_nuevo ); closegraph(); printf( "Bfer inicial: %d\tBfer nuevo: %d\n", buf_inicial, buf_nuevo ); getch(); } Funcin setgraphmode void far setgraphmode(int modo); Esta funcin es usada para seleccionar el modo grfico actual pero solamente cuando el sistema grfico haya sido inicializado con la funcin initgraph. El argumento modo define el modo a usar segn el dispositivo actual. Adems de seleccionar un nuevo modo, la funcin setgraphmode despeja la pantalla y reinicia todas las opciones grficas a sus valores por defecto. Esta funcin suele usarse conjuntamente con restorecrtmode para cambiar entre modos grficos y de texto.

Juan Carlos Gutirrez Barquero____________________________________________

54

Bismarck Salvador Traa Lpez__________________________________________ UNI


La funcin setgraphmode no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA, modo = EGAHI; initgraph( &driver, &modo, C:\\TC20\\BIN ); outtext( "Esto es una prueba para cambiar entre modo grfico..." ); getch(); restorecrtmode(); printf( "...y en modo texto.\nPulsa una tecla para volver\n" ); getch(); setgraphmode( modo ); rectangle( 200, 100, 400, 250 ); getch(); /* Pausa */ closegraph(); getch(); } Funcin setlinestyle void far setlinestyle(int estilo,unsigned trama, int grosor); Esta funcin es usada para definir las caractersticas de lneas para lneas rectas. El argumento estilo especfica la trama de lnea predefinida para su uso. El argumento trama es una trama de 16 bits que describe el estilo de lnea cuando el argumento estilo es USERBIT_LINE, 4. Un bit 1 en esta trama indica que el pxel correspondiente ser asignado el color actual. Un bit 0 indica que el pxel correspondiente no ser alterado. El argumento grosor define el grosor de la lnea. Existen varios valores para los diferentes estilos y grosores de lneas rectas. La funcin setlinestyle no retorna ningn valor; sin embargo, si un argumento es invlido, entonces la funcin graphresult retorna grError (11). Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA,modo = EGAHI; initgraph( &driver, &modo, C:\\TC20\\BIN ); setlinestyle( DOTTED_LINE, 0, THICK_WIDTH ); line( 200, 300, 400, 50 ); getch(); /* Pausa */ closegraph(); getch(); }

Juan Carlos Gutirrez Barquero____________________________________________

55

Bismarck Salvador Traa Lpez__________________________________________ UNI


Funcin setpalette void far setpalette(int num_paleta, int color); Esta funcin es usada para modificar una sola entrada en la paleta actual. El argumento num_paleta especifica el miembro de la paleta a cambiar. El argumento color especifica el nuevo valor de color para el miembro de la paleta. Existen varios valores para los colores dependiendo del dispositivo. Nota: Recuerda que todos los cambios hechos a la paleta tiene un efecto visual inmediato y que la funcin setpalette no debera usarse con el dispositivo IBM-8514. La funcin setpalette no retorna ningn valor; sin embargo, si los valores pasados son invlidos, entonces la funcin graphresult retorna grError (-11) y la paleta no es alterada. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA; int modo = EGAHI; struct palettetype palette; int size, temp, i, y=0; initgraph( &driver, &modo, C:\\TC20\\BIN ); getpalette( &palette ); size = palette.size; for( i=0; i<size; i++ ) { y += 30; setcolor( palette.colors[i] ); line( 20, y, 520, y ); } getch(); /* Pausa */ for( i=0; i<size/2; i++ ) { temp = palette.colors[i]; setpalette( i, palette.colors[size-1-i] ); setpalette( size-1-i, temp ); } getch(); /* Pausa */ closegraph(); getch(); } Funcin setrgbpalette void far setrgbpalette(int num_paleta,int rojo, int verde, int azul); Esta funcin es para usarse con los dispositivos de IBM 8514 y VGA. El argumento num_paleta especifica el miembro de la paleta a ser modificado. Para la IBM 8514 (y para el modo de 256K de la VGA), el intervalo de la paleta es de 0 255. Para los modos de VGA, el intervalo es de 0 15. Los argumentos rojo, verde, y azul especifican la intensidad del color para el miembro de la paleta. De cada byte (de cada argumento) slo

Juan Carlos Gutirrez Barquero____________________________________________

56

Bismarck Salvador Traa Lpez__________________________________________ UNI


los seis bits ms significativos son cargados en la paleta. Por razones de compatibilidad con otros adaptadores grficos de IBM, el dispositivo BGI define las primeras diecisis entradas a la paleta de la IBM 8514 a los colores por defecto de la EGA/VGA. Nota: Recuerda que todos los cambios hechos a la paleta tiene un efecto visual inmediato y que la funcin setrgbpalette no debera usarse con el dispositivo IBM-8514. La funcin setrgbpalette no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA; int modo = EGAHI; struct palettetype palette; int size, i, y=0; initgraph( &driver, &modo, C:\\TC20\\BIN ); getpalette( &palette ); size = palette.size; for( i=0; i<size; i++ ) { y += 30; setcolor( palette.colors[i] ); line( 20, y, 520, y ); } getch(); /* Pausa */ for( i=0; i<size; i++ ) setrgbpalette( i, 2*i+33, 42, 63-4*i ); /* Tonos de naranja y azul */ getch(); /* Pausa */ closegraph(); getch(); } Funcin settextjustify void far settextjustify(int horizontal, int vertical); Esta funcin es usada para especificar el mtodo en el cual el texto es colocado en la pantalla con relacin a la posicin del cursor. El argumento horizontal define la justificacin horizontal, mientras que el argumento vertical indica la justificacin vertical. Existen varios valores y constantes para las justificaciones. La funcin settextjustify no retorna ningn valor; sin embargo, si los valores pasados son invlidos, entonces la funcin graphresult retorna grError (-11) y la paleta no es alterada. Ejemplo: #include <graphics.h> #include <conio.h> void main() {

Juan Carlos Gutirrez Barquero____________________________________________

57

Bismarck Salvador Traa Lpez__________________________________________ UNI


int driver = EGA; int modo = EGAHI; initgraph( &driver, &modo, C:\\TC20\\BIN ); settextjustify( RIGHT_TEXT, BOTTOM_TEXT ); moveto(300, 200); outtext( "(RIGHT_TEXT, BOTTOM_TEXT)" ); settextjustify( RIGHT_TEXT, TOP_TEXT ); moveto(300, 200); outtext( "(RIGHT_TEXT, TOP_TEXT)" ); settextjustify( LEFT_TEXT, BOTTOM_TEXT ); moveto(300, 200); outtext( "(LEFT_TEXT, BOTTOM_TEXT)" ); settextjustify( LEFT_TEXT, TOP_TEXT ); moveto(300, 200); outtext( "(LEFT_TEXT, TOP_TEXT)" ); setcolor( 1 ); line( 300, 200, 300, 100 ); setcolor( 2 ); line( 300, 200, 300, 300 ); setcolor( 3 ); line( 300, 200, 100, 200 ); setcolor( 4 ); line( 300, 200, 500, 200 ); getch(); closegraph(); getch(); } Funcin settextstyle void far settextstyle(int fuente,int orientacion, int tam_caracter); Esta funcin es usada para especificar las caractersticas para la salida de texto con fuente. El argumento fuente especifica la fuente registrada a usar. La fuente ha de estar registrada para resultados predecibles; es decir, usa registerbgifont antes de usar esta funcin. El argumento orientacion especifica la orientacin en que el texto ha de ser mostrado. La orientacin por defecto es HORIZ_DIR. El argumento tam_caracter define l factor por el cual la fuente actual ser multiplicada. Un valor distinto a 0 para el argumento tam_caracter puede ser usado con fuentes escalables o de bitmap. Sin embargo, un valor distinto a 0 para el argumento tam_caracter, el cual selecciona el tamao del carcter definido por el usuario usando la funcin setusercharsize, solamente Funciona con fuentes escalables. El argumento tam_caracter puede agrandar el tamao de la fuente hasta 10 veces su tamao normal. Existen varios valores y constantes para las justificaciones. La funcin settextstyle no retorna ningn valor.

Juan Carlos Gutirrez Barquero____________________________________________

58

Bismarck Salvador Traa Lpez__________________________________________ UNI


Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; char mensaje[40]; char nombre[25]; printf( "Escribe tu nombre: " ); scanf( "%s", nombre ); sprintf( mensaje, "Hola %s!", nombre ); /* Esta fuente ha de ser enlazada antes de poder registrarla registerbgifont( sansserif_font ); */ initgraph( &driver, &modo, C:\\TC20\\BIN ); settextstyle( DEFAULT_FONT, 0, 2 ); outtextxy( 100, 50, mensaje ); settextstyle( DEFAULT_FONT, 1, 2 ); outtextxy( 200, 125, mensaje ); settextstyle( SANS_SERIF_FONT, 1, 3 ); outtextxy( 400, 150, mensaje ); getch(); closegraph(); getch(); } Funcin setusercharsize void far setusercharsize(int x_dividendo, int x_divisor,int y_dividendo, int y_divisor); Esta funcin extablece las caractersticas de fuentes escalables. Para que esta funcin afecte el tamao del carcter, el argumento tam_caracter de la funcin settextstyle debe ser 0. La anchura del carcter se establece con los argumentos x_dividendo y x_divisor que representan la proporcin. Similarmente, los argumentos y_dividendo e y_divisor especifican la altura del carcter. La funcin setusercharsize no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; char mensaje[40]; char nombre[25]; printf( "Escribe tu nombre: " ); scanf( "%s", nombre ); sprintf( mensaje, "Hola %s!", nombre );

Juan Carlos Gutirrez Barquero____________________________________________

59

Bismarck Salvador Traa Lpez__________________________________________ UNI


initgraph( &driver, &modo, C:\\TC20\\BIN ); settextstyle( SANS_SERIF_FONT, 0, 0 ); setusercharsize( 1, 4, 1, 2 ); /* 25% de ancho; 50% de alto */ outtextxy( 100, 50, mensaje ); settextstyle( SANS_SERIF_FONT, 0, 1 ); outtextxy( 100, 125, mensaje ); settextstyle( SANS_SERIF_FONT, 1, 0 ); setusercharsize( 1, 2, 3, 4 ); /* 50% de ancho; 75% de alto */ outtextxy( 400, 150, mensaje ); getch(); closegraph(); getch(); } Funcin setviewport void far setviewport(int izquierda, int superior,int derecha, int inferior, int recorte_banderin); Esta funcin es usada para definir el rea grfico. La esquina superior izquierda del rea grfica est definida por los argumentos izquierda y superior. Estos argumentos corresponden a los valores x e y de la esquina superior izquierda. Similarmente, los argumentos derecha e inferior definen la esquina inferior derecha del rea grfica. El argumento recorte_banderin define si los datos para la salida grfica sern recortados por el borde del rea grfico. Un valor de 0 para recorte_banderin indica que los datos de salida no sern recortados, mientras que un valor distinto a 0 indica que los datos sern recortados. Cuando el rea grfica es inicializada, la posicin del cursor ser mudado a la posicin (0,0) (la esquina superior izquierda). Todos los datos de salida despus de que el rea grfica haya sido inicializada sern con relacin a este punto. El rea grfica por defecto cubre la pantalla entera. La funcin setviewport no retorna ningn valor; sin embargo, si los valores pasados son invlidos, entonces la funcin graphresult retorna grError (-11) y el rea grfica no ser alterada. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA, modo = EGAHI; initgraph( &driver, &modo, "C:\\TC20\\BIN" ); lineto( 100, 100 ); outtextxy( 15, 5, "Inicial" ); getch(); setviewport( 250, 200, 450, 300, 0 ); setcolor( 9 ); lineto( 100, 100 ); outtextxy( 15, 5, "Nueva" ); moveto( 0, 0 ); lineto( -50, -20 ); /* Fuera del rea */ getch(); setviewport( 250, 200, 450, 300, 1 );

Juan Carlos Gutirrez Barquero____________________________________________

60

Bismarck Salvador Traa Lpez__________________________________________ UNI


setcolor( 4 ); moveto( 120, 40 ); lineto( 150, -20 ); /* Fuera del rea */ outtextxy( 25, 15, "Con recorte" ); getch(); /* Pausa */ closegraph(); getch(); } Funcin setvisualpage void far setvisualpage(int pagina); Esta funcin es usada para establecer la pgina visual como es especificado por el argumento pagina. Una pgina es una seccin de memoria donde se guarda la informacin del vdeo. Cuando se usa con un sistema (EGA o VGA) con suficiente memoria de vdeo para soportar mltiples pginas de grficos, la funcin setvisualpage (junto con la funcin setactivepage) permite al programador crear grficos en pginas escondidas y pasar de pgina entre las que se han definido con informacin grfica. Esto es la base para crear animacin. La funcin setvisualpage no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; int visual=1; printf( "Instrucciones:\nPulsa el espacio para cambiar de pgina, cualquier otra tecla para salir\n" ); printf( "(Pulsa cualquier tecla para entrar en modo grfico)\n" ); getch(); initgraph( &driver, &modo, "C:\\TC20\\BIN" ); setactivepage( 0 ); setfillstyle( SOLID_FILL, 6 ); sector( 300, 150, 45, 315, 150, 50 ); setactivepage( 1 ); setfillstyle( SOLID_FILL, 6 ); sector( 300, 150, 90, 270, 150, 50 ); while( getch() == ' ' ) { setvisualpage( visual ); visual = 0==visual ? 1 : 0; } closegraph(); getch(); }

Juan Carlos Gutirrez Barquero____________________________________________

61

Bismarck Salvador Traa Lpez__________________________________________ UNI


Funcin setwritemode void far setwritemode(int modo); Esta funcin es usada para establecer el modo lgico de escritura para lneas rectas. El argumento modo especifica el modo de escritura, el cual determina la interaccin entre valores de pxeles existentes y los valores de pxeles en la lnea. Existen dos valores para los modos de escritura. La funcin setwritemode no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA; int modo = EGAHI; initgraph( &driver, &modo, "C:\\TC20\\BIN" ); setfillstyle( SOLID_FILL, 1 ); bar( 50, 50, 500, 300 ); setwritemode( COPY_PUT ); setcolor( 10 ); line( 20, 60, 220, 100 ); setwritemode( XOR_PUT ); line( 20, 80, 220, 120 ); getch(); closegraph(); getch(); } Funcin textheight int far textheight(char far *texto); Esta funcin es usada para determinar la altura, en pxeles, de la cadena de texto especificada por el argumento *texto. La altura del texto se determina usando la fuente actual y el tamao del carcter. La funcin textheight retorna la altura, en pxeles, del texto especificado por el argumento. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; int anchura, altura; char mensaje[5] = "Hola";

Juan Carlos Gutirrez Barquero____________________________________________

62

Bismarck Salvador Traa Lpez__________________________________________ UNI

initgraph( &driver, &modo, "C:\\TC20\\BIN" ); outtextxy(10,10,mensaje); anchura = textwidth( mensaje ); altura = textheight( mensaje ); getch(); closegraph(); printf( "El mensaje: \"%s\" tiene de anchura: %d y altura: %d\n", mensaje, anchura, altura ); printf( "Pulsa una tecla para continuar...\n" ); getch(); } Funcin textwidth int far textwidth(char far *texto); Esta funcin es usada para determinar la anchura, en pxeles, de la cadena de texto especificada por el argumento *texto. La anchura del texto se determina usando la fuente actual y el tamao del carcter. La funcin textwidth retorna la anchura, en pxeles, del texto especificado por el argumento. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver = EGA; int modo = EGAHI; int anchura, altura; char mensaje[5] = "Hola"; initgraph( &driver, &modo, "C:\\TC20\\BIN" ); outtextxy(10,10,mensaje); anchura = textwidth( mensaje ); altura = textheight( mensaje ); getch(); closegraph(); printf( "El mensaje: \"%s\" tiene de anchura: %d y altura: %d\n", mensaje, anchura, altura ); printf( "Pulsa una tecla para continuar...\n" ); getch(); }

Juan Carlos Gutirrez Barquero____________________________________________

63

Bismarck Salvador Traa Lpez__________________________________________ UNI

Estructuras del modo grfico.


Estructura arccoordstype
struct arccoordstype { int x, y; int xstart, ystart; int xend, yend; };

Los miembros x e y definen el centro del arco. Los miembros xstart e ystart definen las coordenadas x e y del punto de comienzo del arco. Similarmente, los miembros xend e yend definen las coordenadas x e y del punto de final del arco. Esta estructura se usa como parmetro en la funcin getarccoords, que se usa para recoger las coordenadas del centro, y los puntos del comienzo y final de la ltima llamada con xito a la funcin arc.
Ejemplo: #include <graphics.h> #include <conio.h> void main() { int driver = EGA,modo = EGAHI,radio; struct arccoordstype info_arco; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); for( radio=25; radio<=100; radio+=25 ) { arc( 300, 150, 45, 315, radio ); getarccoords( &info_arco ); moveto( info_arco.xstart, info_arco.ystart ); lineto( info_arco.xend, info_arco.yend ); } getch(); /* Pausa */ closegraph(); } Estructura fillsettingstype struct fillsettingstype { int pattern; int color; };

Esta estructura se usa para obtener la informacin de tramas de relleno, mediante getfillsettings. El campo pattern es la trama y el campo color es el color de relleno de la trama. Existen trece valores ya definidos para tramas.

Juan Carlos Gutirrez Barquero____________________________________________

64

Bismarck Salvador Traa Lpez__________________________________________ UNI


Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int gdriver = EGA,gmodo = EGAHI; struct fillsettingstype info; initgraph( &gdriver, &gmodo, "C:\\tc20\\BIN" ); getfillsettings( &info ); bar( 50, 50, 350, 300 ); getch(); /* Pausa */ closegraph(); printf( "Trama de relleno: %d\tColor de relleno: %d\n", info.pattern, info.color ); getch(); } Estructura linesettingstype. struct linesettingstype { int linestyle; unsigned upattern; int thickness; }

Esta estructura se usa para obtener la informacin actual para las lneas mediante la funcin getlinesettings. El campo linestyle es el estilo de la lnea recta. El campo upattern es la trama de la lnea del usuario solamente cuando el campo linestyle es igual a USERBIT_LINE, 4. Cuando esto sea el caso, el miembro upattern contiene una trama de lnea definido por el usuario de 16 bits. Un bit 1 en esta trama indica que el pxel correspondiente ser asignado el color actual. Un bit 0 indica que el pxel correspondiente no ser alterado. El campo thickness es el grosor de la lnea. Existen varios valores para los diferentes estilos y grosores de lneas rectas.
Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int gdriver = EGA; int gmodo = EGAHI; struct linesettingstype info; initgraph( &gdriver, &gmodo, "C:\\tc20\\BIN" ); setlinestyle( DOTTED_LINE, 0xFF33, THICK_WIDTH ); circle( 350, 250, 50 ); getlinesettings( &info ); getch(); /* Pausa */

Juan Carlos Gutirrez Barquero____________________________________________

65

Bismarck Salvador Traa Lpez__________________________________________ UNI


closegraph(); printf( "Lneas rectas.\nEstilo: %d\tTrama: %X\tGrosor: %d\n",info.linestyle, info.upattern, info.thickness ); getch(); }

Estructura palettetype
#define MAXCOLORS 15 struct palettetype { unsigned char size; signed char colors[MAXCOLORS+1]; }; Esta estructura se usa para obtener una los datos que definen la paleta segn cada dispositivo. El campo size indica el tamao de la paleta. El campo colors contiene los valores numricos que representan los colores que ofrece el dispositivo en su paleta de colores.
Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h&t; void main() { int driver = EGA,modo = EGAHI,i; struct palettetype *palette = NULL; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); palette = getpalettetype(); circle( 300, 150, 50 ); getch(); /* Pausa */ closegraph(); printf( "Paleta\n\nTamao: %d\nColores: %d", palette->size, palette->colors[0] ); for( i=1; i<palette->size; i++ ) printf( ", %d", palette->colors[i] ); printf( "\n" ); getch(); } Estructura textsettingstype struct textsettingstype { int font; int direction; int charsize; int horiz; int vert; };

Juan Carlos Gutirrez Barquero____________________________________________

66

Bismarck Salvador Traa Lpez__________________________________________ UNI


Esta estructura se usa para obtener informacin acerca de la fuente grfica actual mediante la funcin getextsettings. Esta estructura contiene informacin de la fuente actual en uso, la orientacin del texto, el tamao del carcter, y la justificacin horizontal y vertical. Existen varios valores para describir el tipo, la orientacin, y justificacin de fuentes.

Ejemplo:
#include <graphics.h> #include <stdio.h> void main() { int driver = EGA,modo = EGAHI; struct textsettingstype info; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); gettextsettings( &info ); closegraph(); printf( "Texto\n\nFuente: %d\tSentido: %d\tTamao: %d\n" "Justificacin:\nHorizontal: %d, Vertical: %d\n", info.font, info.direction, info.charsize, info.horiz, info.vert); getch(); } Estructura viewporttype

struct viewporttype { int left, top; int right, bottom; int clip; }; Esta estructura se usa para obtener informacin acerca del rea grfica actual mediante la funcin getviewsettings. Esta estructura contiene informacin acerca de las esquinas superior izquierda e inferior derecha, tambin como el bandern de recorte del rea grfica.
Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver =IBM8514LO,modo=IBM8514HI; struct viewporttype info; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); getviewsettings( &info ); closegraph(); printf( "Pantalla\n\nIzquierda: %d\tSuperior: %d\tDerecha: %d\t" "Inferior: %d\tBandern: %d\n", info.left, info.top, info.right, info.bottom, info.clip); getch(); }

Juan Carlos Gutirrez Barquero____________________________________________

67

Bismarck Salvador Traa Lpez__________________________________________ UNI

Estructura time

struct viewporttype { int left, top; int right, bottom; int clip; }; Esta estructura se usa para obtener informacin acerca del rea grfica actual mediante la funcin getviewsettings. Esta estructura contiene informacin acerca de las esquinas superior izquierda e inferior derecha, tambin como el bandern de recorte del rea grfica.
Ejemplo: #include <graphics.h> #include <conio.h> #include <stdio.h> void main() { int driver =IBM8514LO,modo=IBM8514HI; struct viewporttype info; initgraph( &driver, &modo, "C:\\tc20\\BIN" ); getviewsettings( &info ); closegraph(); printf( "Pantalla\n\nIzquierda: %d\tSuperior: %d\tDerecha: %d\t" "Inferior: %d\tBandern: %d\n", info.left, info.top, info.right, info.bottom, info.clip); getch(); }

Funciones de Rasterop.
Las funciones del rasterop, son auellas que realizar la accion de mover una imagen ya sea transportando una imagen o copiandola. Las funciones pertenecientes al rasterop son: 1. 2. 3. 4. imagesize malloc getimage putimage

Las cuatro complementan la operacin de mover una imagen almacenndola en una variable temporal de tipo buffer. Procederemos a explicar cada una de ellas para realizar buestros ejercicios de movimiento.

Juan Carlos Gutirrez Barquero____________________________________________

68

Bismarck Salvador Traa Lpez__________________________________________ UNI


Funcin imagesize unsigned far imagesize(int izquierda,int superior, int derecha, int inferior); Esta funcin es usada para determinar el tamao del bfer necesitado para almacenar una imagen con la funcin getimage. Los argumentos izquierda y superior definen las coordenadas x e y de la esquina superior izquierda de la imagen rectangular. Similarmente, los argumentos derecha y inferior definen las coordenadas x e y de la esquina inferior derecha de la imagen rectangular. La funcin imagesize retorna el nmero actual de bytes necesarios, si el tamao requerido es menor que 64 Kb menos 1 byte. Si esto no es el caso, el valor retornado es 0xFFFF, -1. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdlib.h> void main() { int driver = EGA; int modo = EGAHI; void *imagen; int imagentam; initgraph( &driver, &modo, C:\\tc20\\BIN ); setfillstyle( SLASH_FILL, 5 ); bar( 50, 50, 350, 300 ); imagentam = imagesize( 50, 50, 100, 100 ); closegraph(); getch(); } /*En este ejercicio solo calculamos el tamao de la imagen*/ Funcin malloc void *malloc(size_t size) Funcin definida en conio.h. El tamao est en bytes. Regresa un puntero(indicador)al bloque recientemente asignado, o Nulo (NULL) si no existe suficiente espacio en nuevo bloque. Si el tamao==0, este regresa un Nulo(NULL) . Talvez no comprenda lo que quiera dar a entender pero ala hora del ejercicio lo entendern. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdlib.h> void main() {

Juan Carlos Gutirrez Barquero____________________________________________

69

Bismarck Salvador Traa Lpez__________________________________________ UNI


int driver = EGA; int modo = EGAHI; void *imagen; int imagentam; initgraph( &driver, &modo, C:\\tc20\\BIN ); setfillstyle( SLASH_FILL, 5 ); bar( 50, 50, 350, 300 ); imagentam = imagesize( 50, 50, 100, 100 ); imagen = malloc(imagesize( 50, 50, 100, 100 )); free( imagen ); closegraph(); getch(); } En este ejemplo calculamos en tamao de la imagen y el nmero de bytes necesarios para contenerla Funcin getimage void far getimage(int izquierda, int superior,int derecha, int inferior, void far *imagen); Esta funcin es usada para guardar una porcin rectangular de la pantalla para un uso posterior. La esquina superior izquierda del rea rectangular que ha de ser guardada est definida por los argumentos izquierda y superior. Estos argumentos representan las coordenades x e y de la esquina superior izquierda, respectivamente. Los argumentos derecha e inferior definen la esquina inferior derecha de la imagen rectangular. Estos argumentos definen las coordenades x e y de la esquina inferior derecha, respectivamente. El argumento *image apunta al bfer de memoria donde la imagen est guardada. La funcin getimage no retorna ningn valor, directamente. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdlib.h> void main() { int driver = EGA; int modo = EGAHI; void *imagen; int imagentam; initgraph( &driver, &modo, C:\\tc20\\BIN ); setfillstyle( SLASH_FILL, 5 ); bar( 50, 50, 350, 300 ); imagentam = imagesize( 50, 50, 100, 100 ); imagen = malloc( imagentam ); getimage( 50, 50, 100, 100, imagen ); free( imagen ); getch(); }

Juan Carlos Gutirrez Barquero____________________________________________

70

Bismarck Salvador Traa Lpez__________________________________________ UNI

/*En este ejemplo solo conseguimos el tamao de la imagen y guardamos la imagen en un buffer*/ Funcin putimage void far putimage(int izquierda , int superior, void far *image, int accin); Esta funcin coloca una imagen que fue previamente guardada con la funcin getimage en la pantalla. La esquina superior izquierda donde ser colocada la imagen est definida por los argumentos izquierda y superior. Estos argumentos representan las coordenadas x e y de la esquina superior izquierda, respectivamente. El argumento *image apunta al bfer de memoria donde la imagen est guardada. La imagen se coloca en la pantalla con la accin definida en el argumento accin. Los valores y consonantes usados por el argumento accion se describen a continuacin ya que pudieron haberlos olvidado: Constante COPY_PUT XOR_PUT OR_PUT AND_PUT NOT_PUT Valor 0 1 2 3 4 Significado Sobrescribir los pxeles existentes Operacin OR Exclusivo con los pxeles Operacin OR Inclusivo con los pxeles Operacin AND con los pxels Invertir la imagen

La funcin putimage no retorna ningn valor. Ejemplo: #include <graphics.h> #include <conio.h> #include <stdlib.h> void main() { int driver = EGA,modo = EGAHI, imagentam; void *imagen; initgraph( &driver, &modo, C:\\tc20\\BIN ); setfillstyle( SLASH_FILL, 5 ); bar( 50, 50, 350, 300 ); imagentam = imagesize( 50, 50, 100, 100 ); imagen = malloc( imagentam ); getimage( 50, 50, 100, 100, imagen ); putimage( 400, 50, imagen, COPY_PUT ); getch(); putimage( 400, 110, imagen, COPY_PUT ); getch(); /* Pausa */ closegraph(); free( imagen ); getch(); } Este es el pequeo ejemplo del rasterop

Juan Carlos Gutirrez Barquero____________________________________________

71

Bismarck Salvador Traa Lpez__________________________________________ UNI

Otros ejemplo de Rasterop. 1. Un crculo que realiza un movimiento iliptico. # include <conio.h> # include <graphics.h> # include <math.h> # include <dos.h> void inicializar(void); void cuerpo(void); void main(void) { inicializar(); cuerpo(); } void inicializar(void) { int drive=DETECT,modo; initgraph(&drive,&modo,"c:\\tc20\\bin"); } void cuerpo() { double x,y; while(!kbhit()) { x=-180; while(x<=180 && !kbhit()) { y=sqrt(15000*(1-((x*x)/32400))); circle(x+310,240-y,20); delay(15000); x+=1; cleardevice(); } x=180; while(x>=-180 && !kbhit()) { y=-1*sqrt(15000*(1-((x*x)/32400))); circle(x+310,240-y,20); delay(15000); x-=1; cleardevice(); } }

Juan Carlos Gutirrez Barquero____________________________________________

72

Bismarck Salvador Traa Lpez__________________________________________ UNI getch(); } Realice un programa que muestre el movimiento de la tierra alrededor de la tierra y que mustre los meses del ao conforme valla avanzando la image.
# include <conio.h> # include <stdio.h> # include <stdlib.h> # include <graphics.h> # include <math.h> # include <dos.h> # include <process.h> void inicializar(void); void main() { float y2,y1,x,x2; void far *buffer; system("cls"); inicializar(); buffer=malloc(imagesize(0,20,20,20)); do { outtextxy(150,50,"MOVIMIENTO DE ROTACION DE LA TIERRA al rededor del sol"); x2=-300; while(x2<=300 && !kbhit()) { putpixel(random(639),random(480),WHITE); putpixel(random(639),random(480),YELLOW); if((x2>=-300)&&(x2<-200)) { rectangle(480,440,600,460); setfillstyle(1,BLUE); floodfill(485,450,WHITE); outtextxy(500,450,"Enero"); } else { if((x2>=-200)&&(x2<-100)) { setcolor(BLUE);outtextxy(500,450,"Enero"); setcolor(RED); rectangle(480,440,600,460); setfillstyle(1,GREEN); floodfill(485,450,BLUE); outtextxy(500,450,"Febrero"); } else {

Juan Carlos Gutirrez Barquero____________________________________________

73

Bismarck Salvador Traa Lpez__________________________________________ UNI


if((x2>=-100)&&(x2<0)) { setcolor(YELLOW); rectangle(480,440,600,460); setfillstyle(1,BLUE); floodfill(485,450,YELLOW); outtextxy(500,450,"Marzo"); } else { if((x2>=0)&&(x2<100)) { setcolor(GREEN); rectangle(480,440,600,460); setfillstyle(1,BLUE); floodfill(485,450,GREEN); outtextxy(500,450,"Abril"); } else { if((x2>=100)&&(x2<200)) { setcolor(CYAN); rectangle(480,440,600,460); setfillstyle(1,BLUE); floodfill(485,450,CYAN); outtextxy(500,450,"Mayo"); } else { if((x2>=200)&&(x2<299)) { setcolor(MAGENTA); rectangle(480,440,600,460); setfillstyle(1,BLUE); floodfill(485,450,MAGENTA); outtextxy(500,450,"Junio"); } } } } } } setcolor(WHITE); y2=sqrt((1-((x2*x2)/90000.00))*23850.00); circle(310+x2,240-y2,10); getimage(310+x2-10,240-y2-10,310+x2+10,240-y2+10,buffer); delay(20000); putimage(310+x2-10,240-y2-10,buffer,XOR_PUT); circle(310,240,30); setfillstyle(1,YELLOW);

Juan Carlos Gutirrez Barquero____________________________________________

74

Bismarck Salvador Traa Lpez__________________________________________ UNI


floodfill(310,240,WHITE); setcolor(WHITE); x2+=2; } free(buffer); delay(30000); x=300; while(x>=-300 && !kbhit()) { putpixel(random(639),random(480),WHITE); putpixel(random(639),random(480),YELLOW); if((x<=300)&&(x>200)) { setcolor(RED); rectangle(480,440,600,460); setfillstyle(1,BLUE); floodfill(485,450,RED); outtextxy(500,450,"Julio"); } else { if((x2<=200)&&(x>100)) { setcolor(LIGHTGRAY); rectangle(480,440,600,460); setfillstyle(1,BLUE); floodfill(485,450,LIGHTGRAY); outtextxy(501,450,"Agosto"); } else { if((x<=100)&&(x>0)) { setcolor(YELLOW); rectangle(480,440,600,460); setfillstyle(1,BLUE); floodfill(485,450,YELLOW); outtextxy(500,450,"Septiembre"); } else { if((x<=0)&&(x>-100)) { setcolor(GREEN); rectangle(480,440,600,460); setfillstyle(1,BLUE); floodfill(485,450,GREEN); outtextxy(500,450,"Octubre"); } else {

Juan Carlos Gutirrez Barquero____________________________________________

75

Bismarck Salvador Traa Lpez__________________________________________ UNI


if((x<=-100)&&(x>-200)) { setcolor(CYAN); rectangle(480,440,600,460); setfillstyle(1,BLUE); floodfill(485,450,CYAN); outtextxy(500,450,"Noviembre"); } else { if((x<=-200)&&(x>-300)) { setcolor(MAGENTA); rectangle(480,440,600,460); setfillstyle(1,BLUE); floodfill(485,450,MAGENTA); outtextxy(500,450,"Diciembre"); } } } } } } setcolor(WHITE); y1=(sqrt((1-((x*x)/90000.00))*23850.00))*-1; circle(310+x,240-y1,10); getimage(310+x-10,240-y1-10,310+x+10,240-y1+10,buffer); delay(20000); putimage(310+x-10,240-y1-10,buffer,XOR_PUT); circle(310,240,30); setfillstyle(1,YELLOW); floodfill(310,240,WHITE); setcolor(WHITE); x-=2; } free(buffer); delay(2000); }while(!kbhit()); } /***********************INICIALIZAR***************************/ void inicializar(void) { int drive=DETECT,modo; initgraph(&drive,&modo,"c:\\tc20\\bin"); }

Juan Carlos Gutirrez Barquero____________________________________________

76

Bismarck Salvador Traa Lpez__________________________________________ UNI


Existen otras maneras mas sencillas de hacerlo, que te parece si te doy una idea??? Declara un arreglo unidimensional donde escribiras los meses y hay un for que inicie en 1 y termine en 12 dentro de ese for llama a una funcion que es bottom_fond donde dibujaras un rectangulo que se pintar siempre de azul pero su color frontera seran las i recomendacin (pasarle parmetros a la funcion para ahorrar cdigodentro de ese misno for llama al arreglo bidimensional imprimiendo en las coordenadas del rectangulo y los demas clculos son los mismos.

Funciones mas utilizadas en <graphics.h> de <stdlib.h>


La funcin atoi
int atoi(const char *s); El macro atoi() convierte una cadena a su valor entero. Retorna el valor convertido de la cadena leda. Si el valor no puede ser convertido el valor de retorno es 0. Observacin: es usada para convertir cadenas que contengas valores numricas a fin de que estos valores puedan ser computados. Ejemplo #include <stdio.h> #include <conio.h> #include <stdlib.h> void main(void) { char *string="545"; long int valor_entero; clrscr(); valor_entero=atoi(string); printf("La cadena es %s, el valor entero correspondiente es %d\n",string,valor_entero); getch(); }

La funcin itoa
int itoa(int value, char *string, int radix); La funcin itoa convierte un entero a cadena, recibe los siguientes parmetros: int value = es el valor que vas a convertir char *string = es una arreglo de caracteres o un puntero que apunte a char, aqu se colocar el valor entero convertido. int radix = quiere decir el sistema en el que est el valor entero, ejemplo para enteros decimales debe ser 10, para enteros hexadecimale debe ser 16, para octales debe ser 8. Esta funcin es comnmente usada con outtextxy(), en el siguiente ejemplo deseo mostrar en pantalla grfica el valor de una variable entera para lo cual tengo que convertirla a cadena.

Juan Carlos Gutirrez Barquero____________________________________________

77

Bismarck Salvador Traa Lpez__________________________________________ UNI


Ejemplo #include <conio.h> #include <stdlib.h> #include <graphics.h> void main(void) { char *stringx,*stringy; int x=150,y=150; int adaptador=DETECT,modo; initgraph(&adaptador,&modo,"c:\\tc20\\bin"); cleardevice(); itoa(x,stringx,10); itoa(y,stringy,10); outtextxy(150,130,"LOS VALORES DE X e Y SON:"); outtextxy(150,150,"x="); outtextxy(170,150,stringx); outtextxy(150,160,"y="); outtextxy(170,160,stringy); getch(); }

Funciones rand y random


int rand(void); int random(int valor_final);

Las funciones rand() y random() son similares, ambas devuelve un valor seudo-aleatorio, la primera no recibe parmetros y el rango del valores est entre 0 y RAND_MAX este usualmente es 32767, el rango de valores para random() esta entre 0 y (valor_final 1). El ejemplo siguiente simulara una cantidad de estrellas: #include <graphics.h> #include <conio.h> #include <stdlib.h> void main(void) { int adaptador=DETECT,modo; initgraph(&adaptador,&modo,"c:\\tc20\\bin"); while(!kbhit()) { putpixel(rand(),rand(),random(16)); } } Otra manera de realizar programas en modo grafico con gran efectiidad es utilizando la librera mouse.h; esta funcin no esta definida dentro de la ayuda de tc20 pero esta dentro del archivo BGI o include veremos cada una de las funciones asi como tambin como las funciones contenidas dentro de ella.

Juan Carlos Gutirrez Barquero____________________________________________

78

Bismarck Salvador Traa Lpez__________________________________________ UNI

Funciones de la librera Mouse.h


Todos las librerias aqui explicadas aparecen en la carpeta include de tc20.paracomenzar tenemos:

La funcin mver
Void mver (void) La funcin mver muestra el puntero del ratn no es necesario en viar ningn parmetro. La funcin mver no retorna ningn valor. Ejemplo #include<graphics.h> #include<conio.h> #include<mouse.h> void main(){ int adaptador=DETECT,modo; initgraph(&adaptador,&modo,"c:\\tc20\\BIN"); do{ mver(); }while(!kbhit()); closegraph(); getch(); }

La funcin mocultar void mocultar (void)


Esta funcin oculta el puntero del ratn no recibe ni retorna ningn valor. Ejemplo: #include<graphics.h> #include<conio.h> #include<mouse.h> void main(){ int adaptador=DETECT,modo; initgraph(&adaptador,&modo,"c:\\tc20\\BIN"); do{ mver(); mocultar() }while(!kbhit()); closegraph(); getch(); } Al utilizar estas dos funciones obtenemos un efecto del ratn muy vistoso.

Juan Carlos Gutirrez Barquero____________________________________________

79

Bismarck Salvador Traa Lpez__________________________________________ UNI La funcin mtest.


int mtest (void) Esta funcin sirve para testear el ratn en esta no es necesario enviar ningn parametro retorna: 0 si no esta instalado el ratn, y n si el nmero de botones del ratn. La funcion mtest retorna un entero Ejemplo: #include<graphics.h> #include<conio.h> #include<mouse.h> void main(){ int adaptador=DETECT,modo; initgraph(&adaptador,&modo,"c:\\tc20\\BIN"); do{ mver(); mtest(); }while(!kbhit()); closegraph(); getch(); }

La funcin mxpos
int mxpos (int modo) Dice la posicin de la coordenada x en la cual se encuentra el ratn. Es necesario enviarunvalor para especificar el modo en cual sera usado. 1 es para modo grfico. 8 es para modo texto La funcin mxpos regresa la posicin horizontal de un entero que seria la posicin del ratn en x. Ejemplo #include <graphics.h> #include <conio.h> #include <mouse.h> #include <stdlib.h> void main(void) { int adaptador=DETECT,modo; int x,y; char *strx, *stry; initgraph(&adaptador,&modo,"c:\\tc20\\bin"); setbkcolor(BLUE);

Juan Carlos Gutirrez Barquero____________________________________________

80

Bismarck Salvador Traa Lpez__________________________________________ UNI


while(!kbhit()) { setfillstyle(SOLID_FILL,BLUE); mver(); x=mxpos(1); y=mypos(1); itoa(x,strx,10); itoa(y,stry,10); outtextxy(100,100,strx); outtextxy(100,120,stry); if(x!=mxpos(1)||y!=mypos(1)) { setcolor(BLUE); outtextxy(100,100,strx); outtextxy(100,120,stry); setcolor(WHITE);} } }

La funcin mypos
int mypos (int modo) Dice la posicin de la coordenada y en la cual se encuentra el ratn. Es necesario enviarunvalor para especificar el modo en cual sera usado. 1 es para modo grfico. 8 es para modo texto La funcin mypos regresa la posicin horizontal de un entero que seria la posicin del ratn en y. Ejemplo #include <graphics.h> #include <conio.h> #include <mouse.h> #include <stdlib.h> void main(void) { int adaptador=DETECT,modo; int x,y; char *strx, *stry; initgraph(&adaptador,&modo,"c:\\tc20\\bin"); setbkcolor(BLUE); while(!kbhit()) { setfillstyle(SOLID_FILL,BLUE); mver(); x=mxpos(1); y=mypos(1);

Juan Carlos Gutirrez Barquero____________________________________________

81

Bismarck Salvador Traa Lpez__________________________________________ UNI


itoa(x,strx,10); itoa(y,stry,10); outtextxy(100,100,strx); outtextxy(100,120,stry); if(x!=mxpos(1)||y!=mypos(1)) { setcolor(BLUE); outtextxy(100,100,strx); outtextxy(100,120,stry); setcolor(WHITE);} } }

La funcin msituar
void msituar(int modo, int x, int y) Esta funcin permite situar al curcor en una posicin especfica para su utilizacin es necesario enviar tres parmetros modo, x,y. Modo: 1 para modo grfico. 8 para modo texto. X: posicin horizontal. Y: posicin vertical. La funcin no retorna ningn valor. Ejemplo #include<graphics.h> #include<conio.h> #include<mouse.h> void main(){ int adaptador=DETECT,modo; initgraph(&adaptador,&modo,"c:\\tc20\\BIN"); msituar(1,310,240); /*Coloca el cursor en el centro de la pantalla*/ do{ mver(); }while(!kbhit()); closegraph(); getch(); }

Juan Carlos Gutirrez Barquero____________________________________________

82

Bismarck Salvador Traa Lpez__________________________________________ UNI


La funcin mclick int mclick(void) Nos dice si se ha pulsado un boton del Mouse, no es necesario enviar un parmetro. Retorna 0 si no es presionado ningn botn. 1 si se presion el botn izquierdo del Mouse. 2. si se presion el botn derecho del Mouse. Ejemplo #include<graphics.h> #include<stdlib.h> #include<conio.h> #include<mouse.h> void main(){ int adaptador=DETECT,modo,x,y; initgraph(&adaptador,&modo,"c:\\tc20\\BIN"); do{ mver(); x=mxpos(1); y=mypos(1); if(mclick()==1) { setcolor(GREEN); outtextxy(x+30,y,"Diste un click izquierdo"); } if(mclick()==2) { setcolor(RED); outtextxy(x+30,y,"Diste un click derecho"); } delay(10000); setcolor(BLACK); outtextxy(x+30,y,"Diste un click izquierdo"); outtextxy(x+30,y,"Diste un click derecho"); }while(!kbhit()); closegraph(); getch(); }

La funcin mlimit
void mlimit(int modo, int x1, int y1, int x2, int y2) Esta funcin limita el espacio de movilizacin del cursor (ratn), en esta funcin es necesario enviar cinco parmetros modo,x1,y1,x2,y2.

Juan Carlos Gutirrez Barquero____________________________________________

83

Bismarck Salvador Traa Lpez__________________________________________ UNI


Modo: 1 para modo grfico. 8 para modo texto. X1: lmite de arriba. Y1: lmite ablajo. X2: limite de abajo Y2: lmite de la derecha Estas coordenadas formarn un rectngulo el cual sera el limite hasta donde podra llegar el ratn. Ejemplo #include<graphics.h> #include<conio.h> #include<mouse.h> void main(){ int adaptador=DETECT,modo; initgraph(&adaptador,&modo,"c:\\tc20\\BIN"); do{ outtextxy(100,50,"Dibuj el rect ngulo para que observaran el limite"); rectangle(100,100,500,400); mlimit(1,100,100,500,400); mver(); }while(!kbhit()); closegraph(); getch(); } La funcin minlimit int minlimit(int modo,int x1,int y1,int x2,int y2) Esta funcin verifica si el ratn se encuentra en un rea determinada para la implementacin de sta funcin es necesario enviar cinco parmetros. Modo: 1 para modo grfico. 8 para modo texto. X1: lmite de arriba. Y1: lmite ablajo. X2: limite de abajo Y2: lmite de la derecha Retorna 1 si esta en esa area en caso contrario regresar 0 (cero).

Juan Carlos Gutirrez Barquero____________________________________________

84

Bismarck Salvador Traa Lpez__________________________________________ UNI


Ejemplo #include<graphics.h> #include<conio.h> #include<mouse.h> void main(){ int adaptador=DETECT,modo; initgraph(&adaptador,&modo,"c:\\tc20\\BIN"); setbkcolor(BLUE); do{ setcolor(WHITE); outtextxy(210,105,"pasa el mouse por encima del botn y veras el efecto"); mver(); rectangle(100,100,200,120); if(minlimit(1,100,100,200,120)==1) { outtextxy(310,240,"Haz pulsado el ratn por encima del botn"); delay(30000); setcolor(BLACK); outtextxy(310,240,"Haz pulsado el ratn por encima del botn"); } }while(!kbhit()); closegraph(); getch(); }

Ejemplos de la de la VGA.
/*Este programa te muestra las figuras geometricas*/ # include<stdio.h> # include <dos.h> # include <stdlib.h> # include<graphics.h> # include<stdlib.h> # include<conio.h> void inicializar(void); void cuadro(void); void main(void) { inicializar(); cuadro(); restorecrtmode(); } void inicializar(void) { int adaptor=DETECT,modo,codigo;

Juan Carlos Gutirrez Barquero____________________________________________

85

Bismarck Salvador Traa Lpez__________________________________________ UNI


printf("desea seguir viendo los graficos"); initgraph(&adaptor,&modo,"c:\\tc20\\bin"); if((codigo=graphresult())!=0) { printf("%s",grapherrormsg(codigo)); exit(1); } } void cuadro(void) { int paginas=1; int i=155,j=120; /*i=izquierda arriba eje x jes igual eje y*/ int q=465,w=120; /* t= derecha arriba eje x k es igual eje y*/ int t=155,k=360; /*q= izquierda abajo eje x w es igual eje y */ int a=465,s=360; /*a= derecha abajo eje x s igual eje y*/ int pentagono[]={55,340, 105,410, 205,410, 255,340, 155,270, 55,340}; int hexagono[]={365,360, 415,410, 515,410, 565,360, 515,310, 415,310, 365,360}; while(paginas<=4) { system("cls"); setbkcolor(WHITE); setlinestyle(SOLID_LINE,15,THICK_WIDTH); setcolor(8); rectangle(1,1,getmaxx()-1,getmaxy()-1); line(310,0,310,480); line(0,240,640,240); setcolor(9); setlinestyle(SOLID_LINE,15,NORM_WIDTH); if(paginas>=1&&paginas<=2) { settextstyle(SMALL_FONT,HORIZ_DIR,4); outtextxy(400,460,"Presione enter para ver las sig. graficas"); } else { settextstyle(SMALL_FONT,HORIZ_DIR,4); outtextxy(370,460,"Fin de presentacion Presione enter para Salir"); } if(paginas==1) { /***************triangulo1**************************/ outtextxy(i-60,j-90,"Triangulo Rectangulo"); outtextxy(i-67,j-20,"h"); outtextxy(i,j+40,"b"); outtextxy(i-5,j+70,"S=(b x h)/2"); outtextxy(i-60,j-90,"Tri ngulo rectangulo"); line(i-60,j-60,i-60,j+40); line(i-60,j+40,i+100,j+40); line(i+100,j+40,i-60,j-60);

Juan Carlos Gutirrez Barquero____________________________________________

86

Bismarck Salvador Traa Lpez__________________________________________ UNI

/******************triangulo2****************************/ /* q eje x w eje y*/ outtextxy(q-100,w-90,"Triangulo Rectangulo 3 lados diferentes"); outtextxy(q-57,w-20,"h"); outtextxy(q-20,w+40,"a"); outtextxy(q+10,w-30,"b"); outtextxy(q-80,w-30,"c"); settextstyle(SMALL_FONT,HORIZ_DIR,5); outtextxy(q-45,w+60,"S=-\/ p(p-a)(p-b)(p-c)'"); line(q-15,w+60,q+110,w+60); outtextxy(q-30,w+75,"P=(a+b+c)/2"); settextstyle(SMALL_FONT,HORIZ_DIR,4); /*outtextxy(q-5,w+70,"(b x h)/2");*/ outtextxy(i-60,j-90,"Tri ngulo rectangulo"); outtextxy(i-60,j-90,"Tri ngulo rectangulo"); outtextxy(i-60,j-90,"Tri ngulo rectangulo"); setlinestyle(DOTTED_LINE,3,NORM_WIDTH); line(q-50,w-60,q-50,w+40); setlinestyle(SOLID_LINE,15,NORM_WIDTH); line(q-50,w+40,q+80,w+40); line(q+80,w+40,q-50,w-60); line(q-50,w+40,q-100,w+40); line(q-100,w+40,q-50,w-60); /*******************triangulo escaleno*****************************/ /*t es eje x k es eje y*/ outtextxy(t-60,k-90,"Triangulo Escaleno"); outtextxy(t-67,k-20,"h"); outtextxy(t,k+40,"b"); outtextxy(t-5,k+70,"S=(b x h)/2"); line(t-60,k-60,t-25,k+40); /*line que corta al triangulo o cat opu*/ line(t-25,k+40,t+100,k+40); /*cat ady.*/ line(t+100,k+40,t-60,k-60); /*hipoten.*/ setlinestyle(DOTTED_LINE,8,NORM_WIDTH); line(a+20,s-60,a+20,s+40); /*Triangulo isosceles*/ line(t-60,k-60,t-60,k+40); line(t-60,k+40,t+100,k+40); setlinestyle(SOLID_LINE,21,NORM_WIDTH); /*********************triangulo isosceles***************************/ outtextxy(a-40,s-90,"Triangulo Isosceles"); outtextxy(a+10,s-20,"h"); outtextxy(a+10,s+40,"b"); outtextxy(a-5,s+70,"S=(b x h)/2"); line(a+20,s-60,a-60,s+40); /*cat opt.*/ line(a-60,s+40,a+100,s+40); /*cat ady*/ line(a+100,s+40,a+20,s-60); /*hip*/ getch(); } if(paginas==2)

Juan Carlos Gutirrez Barquero____________________________________________

87

Bismarck Salvador Traa Lpez__________________________________________ UNI


{ /********************Rectangulo******************/ line(i-45,j-25,i+65,j-25); line(i-60,j+25,i+50,j+25); line(i-45,j-25,i-60,j+25); line(i+65,j-25,i+50,j+25); setlinestyle(DOTTED_LINE,8,NORM_WIDTH); line(i-45,j-25,i-45,j+25); /*altura*/ outtextxy(i-25,j-90,"Rectangulo"); outtextxy(i-52,j,"h"); outtextxy(i,j+30,"b"); outtextxy(i-35,j+60,"S=b x h"); setlinestyle(SOLID_LINE,8,NORM_WIDTH); /*****************************Rombo***********************/ line(t-90,k,t+90,k); line(t,k-60,t,k+60); line(t-90,k,t,k-60); line(t,k-60,t+90,k); line(t,k+60,t+90,k); line(t-90,k,t,k+60); setlinestyle(DOTTED_LINE,24,NORM_WIDTH); rectangle(t-90,k,t+90,k+70); line(t,k-60,t+120,k-60); line(t+120,k-60,t+120,k+60); line(t+120,k+60,t,k+60); line(q-60,w-45,q-60,w+45); outtextxy(t-25,k-90,"Rombo"); outtextxy(t-45,k,"D"); outtextxy(i+3,k+30,"d"); outtextxy(t-35,k+75,"S=(D * d)/2"); setlinestyle(SOLID_LINE,8,NORM_WIDTH); /*****************************Trapecio******************************/ line(q-60,w-45,q+60,w-45); line(q-85,w+45,q+90,w+45); line(q-85,w+45,q-60,w-45); line(q+90,w+45,q+60,w-45); outtextxy(q-25,w-90,"Trapecio"); outtextxy(q-52,w,"h"); outtextxy(q,w+50,"B"); outtextxy(q,w-60,"b"); outtextxy(q-35,w+60,"S=((B + b)* h)/2"); /*************************Polgono*****************************/ line(a-60,s,a+100,s); line(a+100,s,a+70,s+45); line(a+70,s+45,a-60,s); line(a+100,s,a+40,s-60); line(a+40,s-60,a-60,s); line(a+40,s-60,a-40,s-40);

Juan Carlos Gutirrez Barquero____________________________________________

88

Bismarck Salvador Traa Lpez__________________________________________ UNI


line(a-60,s,a-40,s-40); outtextxy(a-25,s-90,"Poligono"); outtextxy(a-30,s-40,"S1"); outtextxy(a+25,s-30,"S2"); outtextxy(a+30,s+10,"S3"); outtextxy(a-35,s+60,"S= S1 + S2 + S3"); getch(); } if(paginas==3) { /*********************tri ngulo equilatero*********************/ line(i-60,j+55,i+20,j-85); /*cat*/ line(i+100,j+55,i+20,j-85); /*cat*/ line(i-60,j+55,i+100,j+55); /*base*/ outtextxy(i-25,j-100,"Triangulo equilatero"); setlinestyle(DOTTED_LINE,24,NORM_WIDTH); line(i+20,j-85,i+20,j+55); setlinestyle(SOLID_LINE,8,NORM_WIDTH); outtextxy(i+25,i-30,"h"); outtextxy(i+30,i+20,"b"); outtextxy(i-35,i+55,"S= (b * h)/2"); /*******************************cuadrado***********************/ rectangle(q-50,w-50,q+50,w+50); outtextxy(q-25,w-100,"Cuadrado"); outtextxy(q,w+50,"b"); outtextxy(q-35,w+65,"S= b * b"); /****************************pent gono***********************/ fillpoly(5,pentagono); outtextxy(t-25,k-110,"Pent gono"); line(t,k-20,t,k+50); outtextxy(t+10,k+10,"a"); outtextxy(t-35,k+65,"S=(P * a)/2"); /*************Exagono o poligono regular*******************/ fillpoly(6,hexagono); outtextxy(a-65,s-100,"Hex gono o poligono regular"); /*setfillstyle(LINE_FILL,GREEN); floodfill(370,460,BLUE);*/ line(a,s,a,s+50); outtextxy(a+10,s+10,"a"); outtextxy(a-35,s+65,"S=(P * a)/2"); getch(); } if(paginas>4) exit(1); paginas=paginas+1; } clrscr();} Este programa te simula un paisaje nocturno con algunas efectos de estrellas.

Juan Carlos Gutirrez Barquero____________________________________________

89

Bismarck Salvador Traa Lpez__________________________________________ UNI

# include <conio.h> # include <dos.h> # include <process.h> # include <stdlib.h> # include <graphics.h> # define WHITE 15 void marco(int *,int *,int *,int *,int *); void estrellas(int *,int *); void ambiente(void); void ambientedos(void); void montana(void); void cometas(void); void main() { /*INICIALIZAR EL MODO GRAFICO DE MANERA RAPIDA*/ int a=DETECT,b; int x1=0,y1=0,x2=640,y2=480,color=6; int y=0, x=0; initgraph(&a,&b,"c:\\tc20\\bin"); system("cls"); ambiente(); ambientedos(); marco(&x1,&y1,&x2,&y2,&color); estrellas(&x,&y); montana(); cometas(); getch(); } void ambiente(void) { int x=50,y=480; setbkcolor(BLUE); setcolor(LIGHTGRAY); rectangle(0,0,639,479); moveto(x,y); setcolor(LIGHTGRAY); lineto(100,450); lineto(150,400); lineto(210,370); lineto(0,370); setfillstyle(SOLID_FILL,GREEN); floodfill(1,470,LIGHTGRAY); } void ambientedos(void) {

Juan Carlos Gutirrez Barquero____________________________________________

90

Bismarck Salvador Traa Lpez__________________________________________ UNI


setcolor(BROWN); moveto(105,370); lineto(125,350); lineto(155,365); lineto(155,360); lineto(125,345); lineto(55,345); lineto(22,370); lineto(105,370); setfillstyle(6,BROWN); floodfill(50,350,BROWN); setcolor(BROWN); rectangle(30,365,110,400); setfillstyle(SOLID_FILL,BROWN); floodfill(50,385,BROWN); line(150,362,150,382.5); /*linea lateral | */ line(110,400,150,382.5); /*union de la linea lateral con la casa*/ setfillstyle(SOLID_FILL,BROWN); floodfill(112,385,BROWN); setcolor(RED); line(130,367,140,364); /*ventana arriba --*/ line(130,377,140,374); /*ventana abajo __*/ line(130,367,130,377); /*lado derecha | */ line(140,364,140,374); /*lado izquierdo | */ setfillstyle(SOLID_FILL,MAGENTA); floodfill(135,368,RED); line(112,398,112,378); /*puerta arriba*/ line(112,378,120,374); /*puerta lado izquierdo*/ line(120,374,120.5,395); /*puerta lado derecho*/ line(112,397,120.5,394); /*puerta abajo*/ setfillstyle(SOLID_FILL,MAGENTA); floodfill(114,380,RED); line(110,365,110,400); setcolor(YELLOW); arc(310,300,90,270,30); ellipse(310,300,90,270,05,30); setfillstyle(SOLID_FILL,YELLOW); floodfill(300,300,YELLOW); } void marco(int *x1,int *y1,int *x2,int *y2,int *color) { setbkcolor(BLUE);

Juan Carlos Gutirrez Barquero____________________________________________

91

Bismarck Salvador Traa Lpez__________________________________________ UNI


setcolor(*color); rectangle(*x1,*y1,*x2,*y2); } void estrellas(int *x,int *y) { int i,px=*x,py=*y,color,t; setcolor(YELLOW); arc(310,180,90,270,30); ellipse(310,180,90,270,05,30); setfillstyle(SOLID_FILL,YELLOW); floodfill(300,180,YELLOW); color=getcolor(); t=1; for(i=0;i<=400;i++) { montana(); setcolor(GREEN); putpixel(px,py,color); putpixel(px+10,py+50,WHITE); px=(rand()%640); py=(rand()%200); if(i>=230) continue; else { putpixel(310,(480-t)-12,RED); putpixel(310,(480-t)-9,YELLOW); putpixel(310,(480-t),BLUE); putpixel(t+1,100,RED); putpixel(t-5,100,YELLOW); putpixel(t-11,100,BLUE); putpixel(t+1,50,RED); putpixel(t-5,50,YELLOW); putpixel(t-11,50,BLUE); t+=3; } delay(4000); } } void montana() { setcolor(LIGHTGRAY); line(0,250,494,250); line(480,250,560,200); line(560,200,639,250); line(480,250,639,250);

/*linea del lago superior */ /*montaa / */ /* montaa \ */ /* montaa ___ */

Juan Carlos Gutirrez Barquero____________________________________________

92

Bismarck Salvador Traa Lpez__________________________________________ UNI


setfillstyle(SOLID_FILL,LIGHTGREEN); floodfill(590,230,LIGHTGRAY); } void cometas(void) { int i,t; do { t=1; for(i=0;i<=450;i++) { if(i>=230) continue; else { putpixel(t+3,65,RED); putpixel(t-3,65,YELLOW); putpixel(t-9,65,BLUE); putpixel(t+13,80,RED); putpixel(t+7,80,YELLOW); putpixel(t+1,80,BLUE); putpixel(t+13,100,RED); putpixel(t+7,100,YELLOW); putpixel(t+1,100,BLUE); if((t+1)>=292 && (t+1)<=317) { putpixel(t+1,180,RED); putpixel(t-5,180,YELLOW); putpixel(t-11,180,YELLOW); } else { putpixel(t+1,180,RED); putpixel(t-5,180,YELLOW); putpixel(t-11,180,BLUE); } t+=3; } delay(2000); } t=0; }while(!kbhit()); } Este programa dibuja con el Mouse. #include <mouse.h>

Juan Carlos Gutirrez Barquero____________________________________________

93

Bismarck Salvador Traa Lpez__________________________________________ UNI


#include <stdlib.h> #include <stdio.h> #include <graphics.h> #include <conio.h> #define ESC 27 void main() { int a=DETECT,b; int posx,posy,h,z=0; initgraph(&a,&b,"c:\\tc20\\bin"); setcolor(YELLOW); outtextxy(10,10,"a) click izq sostenido para dibujar "); outtextxy(10,20,"b) click izq dibuja una linea desde la pos. anterior hasta la nueva pos."); outtextxy(10,30,"c) presionar una vez click der indica que se escogera un nuevo punto donde"); outtextxy(10,40," empezara a dibujar el click debe ser fuera del dibujo en caso contrario "); outtextxy(10,50," se borrara"); outtextxy(10,60,"d) click der sostenido para borrar"); outtextxy(10,70,"e) presiona una tecla para salir o click si no has empezado ha dibujar"); outtextxy(10,420,"Hecho por:"); settextstyle(4,0,1); outtextxy(10,430," Bismarck Salvador Traa Lpez"); outtextxy(10+textwidth("Hecho por: "),450,"Juan Carlos Gutirrez Barquero"); while(mclick()!=1) { setcolor(WHITE); rectangle(100,100,getmaxx()-100,getmaxy()-100); mver(); posx=mxpos(1); posy=mypos(1); } while(!kbhit()) { setcolor(WHITE); mlimit(1,100,100,getmaxx()-100,getmaxy()-100); rectangle(100,100,getmaxx()-100,getmaxy()-100); mver(); mocultar(); if(mclick()==1) { if(z==1) { z=0; posx=mxpos(1); posy=mypos(1); } line(posx,posy,mxpos(1),mypos(1)); posx=mxpos(1); posy=mypos(1); }

Juan Carlos Gutirrez Barquero____________________________________________

94

Bismarck Salvador Traa Lpez__________________________________________ UNI


else if(mclick()==2) { z=1; setcolor(BLACK); for(h=0;h<=20;h++) circle(mxpos(1),mypos(1),h); floodfill(mxpos(1),mypos(1),BLACK); } mlimit(1,100,100,getmaxx()-100,getmaxy()-100); } clrscr(); }

Este programa muestra el movimiento de una pelota. # include<stdio.h> # include <dos.h> # include <stdlib.h> # include<graphics.h> # include<conio.h> void inicializar(void); void juego_visual(void); void fondo_de_la_pantalla(void); void mover(void); void main(void) { inicializar(); juego_visual(); cleardevice(); fondo_de_la_pantalla(); mover(); getch(); restorecrtmode(); } void inicializar(void) { int adaptor=DETECT,modo,codigo; printf("desea seguir viendo los graficos"); initgraph(&adaptor,&modo,"c:\\tc20\\bin"); if((codigo=graphresult())!=0) { printf("%s",grapherrormsg(codigo)); exit(1); } } void juego_visual(void)

Juan Carlos Gutirrez Barquero____________________________________________

95

Bismarck Salvador Traa Lpez__________________________________________ UNI


{ int i; setbkcolor(BLUE); setcolor(YELLOW); outtextxy(5,5,"Cargando programa de movimiento grafico"); rectangle(21,20,450,30); sleep(1); for(i=11;i<=430;i++) { bar(10+i,20,20+i,30); delay(5000); if(i==430) { moveto(480,400); outtext("programa Cargado"); } } sleep(1); } void mover(void) { void far *buffer; int i; setcolor(WHITE); buffer=malloc(imagesize(127,98,172,143)); /*rectangle(127,98,172,143);*/ i=100; while(!kbhit()) { ala: circle(127+i,180,20); getimage(107+i,160,147+i,200,buffer); sleep(1); putimage(107+i,160,buffer,XOR_PUT); i+=10; if(i==300) { i=100; goto ala; } } free( buffer); } void fondo_de_la_pantalla(void) { setbkcolor(BLUE); setcolor(LIGHTBLUE);

Juan Carlos Gutirrez Barquero____________________________________________

96

Bismarck Salvador Traa Lpez__________________________________________ UNI


rectangle(1,1,getmaxx()-1,getmaxy()-1); setcolor(LIGHTGRAY); rectangle(6,5,634,20); setfillstyle(SOLID_FILL,LIGHTGRAY); floodfill(10,7,LIGHTGRAY); setcolor(BLUE); rectangle(5,5,100,20); setcolor(RED); outtextxy(8,11,"N"); setcolor(BLACK); outtextxy(17,11,"uevo Juego"); setcolor(BLUE); rectangle(110,5,160,20); setcolor(RED); outtextxy(116,11,"S"); setcolor(BLACK); outtextxy(124,11,"alir"); }

Modo 13h 320x200().


Introduccin.

Cuando aparecieron los primeros computadores exista una memoria de solo 640 Kb (memoria convencional) y el procesador que dominaba en aquella poca era el 8086 y 8088 el cual poda direccionar hasta 1 Mb de memoria, ya que el microprocesador era de 16 bits. Aadieron a este diferentes reas de memoria, para la BIOS, el video, cartuchos ROM, etc. Hoy en da la configuracin de todo PC est organizada en bloques de 64 kb. Organizacin de la memoria de un PC A000: corresponde a la memoria de la pantalla en los modos grficos de las tarjetas EGA y VGA. B000: Es para las tarjetas de video monocromo MDA y Hercules. Tambin sirve tarjeta CGA. Se utiliza como alojamiento de los modos alfanumricos. para la

C000: Se depositan algunas rutinas BIOS, que no forman parte del ncleo original de esta. D000: Para cartuchos ROM. No se suele utilizar. E000: Igual que D000. F000: Aqu se guardan todas la rutinas (funciones) de la ROM-BIOS.

Juan Carlos Gutirrez Barquero____________________________________________

97

Bismarck Salvador Traa Lpez__________________________________________ UNI

El Procesador . Para hacer la programacin del sistema, hay que conocer algunos conceptos que juegan un papel importante, trminos como por ejemplo los registros, a los que hay que conocer si se quieren manejar las interrupciones, ya sean a nivel DOS o BIOS. Los registros . Los registros son muy importantes para el ordenador, sirven para ayudar al funcionamiento de las instrucciones. Una definicin un poco ms acertada, sera decir que los registros son como variables internas con las que el computador realiza operaciones, y lleva el control de los programas. El tamao de estos registros en un 286 es de 16 bits, pero a partir del 386 estos registros son de 32 bits. Cada uno de estos registros se divide en dos partes de 8 bits cada una (esto es as, por que el DOS trabaja en modo Real, y no puede direccionar ms de 16 bits). Por ejemplo, el registro AX, se divide en AH y AL (H de High y L de Low). Podemos distinguir cinco tipos de registros diferentes: Registros Generales: Hay cuatro: AX, BX, CX, y DX. Son unos registros de 16 bits que se usan como almacenamiento temporal, para realizar operaciones aritmticas, cada uno de estos se divide en dos partes, la parte alta (AH), y la baja (AL), donde H significa High y L de Low. Tienen un propsito general para el programador. Registros de direccin (Puntero / Indice): SP, BP, SI y DI. Los utilizamos para formar direcciones de 20 bits, junto con los registros de segmento CS, DS, SS, y ES. Registros de segmento: CS, DS, SS y ES. Con ellos referenciamos direcciones de memoria. Registro de Puntero de Instruccin: IP (Instruction Pointer). Este lo usa el PC para acordarse en que punto se ha quedado a partir de la base CS. Va cambiando su valor cada vez que saltamos a un punto del programa. Registro de Bandera (Flag): Sirve para saber el estado y tener el control del procesador. Con este registro podremos saber, si por ejemplo despus de una suma, el valor excede de 65535 y por tanto no cabe en 16 bits. Estos bits, que pueden valer 0 o 1, indican varias cosas segn su valor. Las interrupciones . Las interrupciones, tal y como indica su nombre, tienen como funcin interrumpir en medio de un procedimiento, ejecutar un trozo de cdigo y continuar con lo que se estaba haciendo. De esta manera la CPU se ahorra de ir preguntado todo el rato a los diferentes perifricos si necesitan su ayuda (polling). Hay de varios tipos, las que son ejecutadas por el hardware, las del Sistema Operativo y las iniciadas por el sistema (BIOS). Dentro de estas hay las enmascarable, y las no enmascarables (NMI). El B.I.O.S ( Basic Input Output System) tiene una serie de interrupciones, para que cuando utilicemos alguna de ellas sepamos donde se encuentra. Para eso utilizaremos

Juan Carlos Gutirrez Barquero____________________________________________

98

Bismarck Salvador Traa Lpez__________________________________________ UNI


una tabla que nos servir de ndice para as obtener la direccin de la rutina. Esta tabla se aloja en la parte ms baja de la memoria, es decir, en 0000:0000, y tiene una longitud de 256 entrada de 4bytes cada una; 2 bytes de direccin (segmento) y 2 bytes de desplazamiento (offset), o sea, 1 kb en total. El Bios dispone de las funciones principales que necesita un programa para la comunicacin con el hardware del PC y los dispositivos conectados a l. Hay rutinas de todas clases. Su funcin ms importante, es que permite usar a los programas diferentes perifricos independientemente de las caractersticas del hardware. Esto nos ahorra mucho tiempo a la hora de programar para diferentes perifricos. O sea, que el Bios es un sistema de comunicacin estndar. A continuacin describir todas las interrupciones de la BIOS y su finalidad de la 00H a la 1BH, pero aunque hay ms, no sern comentadas ya que es de uso de la BIOS. INTERRUPCION 00H: Divisin entre cero. INTERRUPCION 01H: Un solo paso. INTERRUPCION 02H: Interrupcin no enmascarable. INTERRUPCION 03H: Punto de ruptura. INTERRUPCION 04H: Desbordamiento. INTERRUPCION 05H: Imprime pantalla. INTERRUPCION 08H: Sistema del cronmetro. INTERRUPCION 09H: Interrupcin del teclado. INTERRUPCION 0BH y INTERRUPCION 0CH: Estas dos son para el Control de Dispositivo Serial. INTERRUPCION 0DH y INTERRUPCION 0FH: Estas son para el Control del Dispositivo Paralelo. INTERRUPCION 0EH: Control disco flexible. INTERRUPCION 10H: Servicios de video. INTERRUPCION 11H: Obtener equipo instalado. Determinacin equipo. INTERRUPCION 13H: Obtencin tamao memoria. INTERRUPCION 14H: Comunicaciones i/o. INTERRUPCION 15H: Servicios sistema. INTERRUPCION 16H: Entrada teclado.

Juan Carlos Gutirrez Barquero____________________________________________

99

Bismarck Salvador Traa Lpez__________________________________________ UNI


INTERRUPCION 17H: Salida impresora. INTERRUPCION 18H: Entrada basic de rom. INTERRUPCION 19H: Cargador de arranque. INTERRUPCION 1AH: Lee y pone hora. INTERRUPCION 1BH: Tomar control en interrupcin del teclado. Estas son las interrupciones del BIOS, pero hay ms, las del sistema operativo, MS-DOS en nuestro caso. Cada interrupcin se divide en funciones, que son los diferentes servicios a los que tenemos acceso. Para llamar a una interrupcin utilizamos los registros, donde en AX indicaremos por norma general el nmero de interrupcin, y en los dems registros los parmetros. La Programacin del Sistema A la hora de programar una aplicacin, la forma de tratar la informacin, ordenarla, y representarla es siempre igual para todos los computadores, los algoritmos utilizados no varan, los podemos describir de forma muy general. Pero lo que s vara y que depende del sistema, es la forma en la que se debe tratar la informacin que entra en un programa y la forma en la que sale, esto s es realmente la programacin de sistemas, en la que se deben conocer como acceder al teclado, pantalla, impresora, archivos, etc. Una de las cosas mas importantes en este tipo de programacin es el acceso al hardware. Debemos saber por donde nos movemos si queremos que nuestra aplicacin funcione correctamente. Aunque la programacin de sistemas est tan fuertemente ligada al hardware, no significa que tengamos que rompernos la cabeza para poner un "Hola!" en pantalla, tenemos unas ayudas que nos simplifican mucho la vida. Esto es las funciones de el BIOS y del Sistemas Operativo. Estas rutinas (interrupciones) nos ahorrar mucho trabajo, ya que cada uno de estos servicios, conlleva ms tiempo mediante la programacin directa al hardware. Resumiendo, tenemos que las diferentes capas a la que una aplicacin puede acceder son tres: Para decidirnos por uno de los tres, se tendr que pensar en el objetivo de la aplicacin que se est desarrollando: si es un juego se tendr que ir directo al hardware del computador, por que si se hace mediante rutinas BIOS, el juego quedar demasiado lento. Esto no quiere decir que las rutinas de la BIOS sean lentas de por si, lo que pasa es que son universales y llevan muchos tipos de comprobaciones. Por otro lado, si lo que se quiere es hacer una aplicacin en modo texto, simplemente usaremos las funciones que nos pone a disposicin nuestro lenguaje de programacin favorito. Introduccin. Capitulo I. Inicializacin del modo grfico.

Juan Carlos Gutirrez Barquero____________________________________________

100

Bismarck Salvador Traa Lpez__________________________________________ UNI


La pantalla de nuestro computador puede funcionar en dos modos, modo texto (o alfanumrico) en el que se representan caracteres, y en modo grfico, en el cual adems de caracteres se pueden representar imgenes. Cuando hablamos de modos grficos, la unidad representable es el pixel. Un pixel (un punto) es la unidad mnima de informacin que podemos representar en pantalla. El elemento que determina tanto la resolucin como la cantidad de colores que podemos representar, es el adaptador. Cada adaptador tiene unas caractersticas determinadas, que hace que la forma de programar sea distinta para cada uno. La diferencia fundamental es la manera de gestionar la memoria. La informacin de un pixel, se almacena en cdigo binario. Esta informacin hace referencia al color y atributos especiales. Los registros de las tarjetas constituyen el dispositivo de Entrada/Salida (E/S) de ms bajo nivel de los adaptadores grficos. Es en ellos donde se almacena la informacin relativa a como debe el computador representar los datos en la pantalla. Estn conectados a puertos de E/S que los hacen accesibles, permitiendo su modificacin y lectura. Una tarjeta de video esta formada por varios controladores hardware integrados en una misma placa. Cada uno de estos controladores tiene a su vez una serie de registros asociados. A la hora de programar las tarjetas grficas, tendremos que acceder a estos registros, para lo cual se emplea un ndice de puerto o index port. Un mismo controlador puede controlar ms de un registro, por lo que la finalidad de este ndice es sealar cul de todos los registros es el que se modificar. El modo de acceder a cada controlador es distinto, la forma de leer o escribir en los registros ser diferente en cada caso. La aparicin de la tarjeta de video VGA (Video Graphic Array) como en el ao 1987, hizo que se convirtiera en un estndar de los computadores IBM y compatibles. La VGA tiene una resolucin mxima de 640x480 pixeles y puede mostrar simultneamente un mximo de 256 colores. Esta resolucin es muy alta comparada con las antiguas tarjetas CGA y EGA. Lamentablemente para usar los 256 colores solo se puede usar una resolucin de 320x200 pixeles. Este modo de vdeo es el conocido Modo 13h, en el cual se han programado la mayora de los juegos, demos, aplicaciones grficas, etc. Este modo es uno de los ms usados en la programacin grfica, debido a su facilidad de uso y rapidez. Las tarjetas VGA tienen normalmente un mnimo de 256 Kb, estando la memoria dividida en 4 segmentos o planos. Existe un bit, que puede estar a 1 o 0. En el primer caso (bit a 1) hablamos de modos lineales, limitados a un plano. Cuando el bit est a 0, fuerza a usar los cuatro planos, por lo que estamos en el caso de los modos denominados planares. Este bit se denomina CHAIN-4, porque encadena los cuatro planos. La denominacin chained (modos lineales) y unchained (modos planares), hacen referencia al estado de este bit, indicando que esta a 1 o 0, respectivamente. Los registros de estas tarjetas pueden ser, de lectura, de escritura, o de lectura/escritura. Las tarjetas SVGA tienen cada una de ellas su conjunto de registros. El inconveniente que presentan estas tarjetas, es que aparecen problemas de compatibilidad. No estaremos seguros de que todos nuestros programas que desarrollemos funcionen correctamente

Juan Carlos Gutirrez Barquero____________________________________________

101

Bismarck Salvador Traa Lpez__________________________________________ UNI


con todas las tarjetas. Este problema se puede evitar si nos limitamos a utilizar el conjunto de registros de la VGA, con los que la SVGA son perfectamente compatibles. Entrando al modo 13h . El nombre 13h viene del parmetro que hay que pasarle a la interrupcin 10h para iniciar este modo. Esta ultima es un interrupcin software que facilita al programador tomar el control del hardware de un PC. La interrupcin 10h esta encargado de dar los servicios de video. Ahora para iniciar el modo de video 13h debemos usar la funcin 00h de la interrupcin 10h, y para esto se les pasa unos parmetros. Qu significa todo esto, lo que sucede es que cada interrupcin posee varias funciones y a su vez cada funcin tambin puede tener sub-funciones. En este caso nosotros queremos iniciar un nuevo modo de video, para esto utilizamos la funcin 00h de la interrupcin 10h, la cual esta encargada de activar modos de video especficos. En este caso en el registro de 8 bits AL se le pasa el valor 00h y en el otro registro (tambin de 8 bits) se coloca el modo de video a inicializar. A continuacin podrs ver los distintos modos de video, que soporta la tarjeta VGA. Como podemos ver en la tabla el Modo 13h es uno de los que tiene menor resolucin de los modos grficos, pero es el que tiene mayor nmero de colores. Nosotros utilizaremos dos modos, el 13h y el 03h, este ltimo los usaremos por la sencilla razn, de que cuando se termina un programa grfico, se debe regresar nuevamente al modo texto, en este caso al modo 03h que es el que tienen por defecto todos los PC al ser encendidos. Este modo texto es de 80x25 y con 16 colores. Existen modos superiores al 13h, pero estos pertenecen a tarjetas Super VGA o superiores. El modo de video que utilizaremos se compone de 320 pixeles horizontales por 200 pixeles verticales, teniendo un total de 64000 pixeles. (320x200=64000) Despus de haber visto todo la teoria necesaria, podremos crear nuestra primera rutina en lenguaje C para inicializar el modo 13h. Al iniciarse el modo 13h, los registros de la VGA se programan automticamente con las caractersticas propias de este modo. Cuando se inicia este modo la memoria de video, en este caso los 64 Kb se limpian, es decir todos tienen el color 0 (negro). Acurdense de incluir la cabecera <dos.h> para utilizar la funcin int86 y la union REGS. La turina para incluir este modo sera: void Modo13h(void) { union REGS r; r.h.ah=0; r.h.al=0x13; int86(0x10, &r, &r); }

Juan Carlos Gutirrez Barquero____________________________________________

102

Bismarck Salvador Traa Lpez__________________________________________ UNI

Lo que hemos hecho con esta funcin es simplemente llamar a la interrupcin 10h con los parmetros necesarios para iniciar el modo 13h. Otra rutina que nos ser de mucha utilidad ser la que regresa al modo texto, esta funcin es similar al anterior, la nica diferencia es que al registro AL se le debe pasar el valor 03h. Podramos crear una funcin general para que realice los cambios de modos de video, esto quedara as: void SetMode(char mode) { union REGS r; r.h.ah=0; r.h.al=mode; int86(0x10, &r, &r); } Otra manera seria: void SetMCGA(void) { _AX=0x0013 ; geninterrupt(0x10) ; } Para volver al modo texto usamos la misma interrupcin 10h, slo que el servicio 03h : void SetText(void) { _AX=0x0003 ; geninterrupt(0x10) ; } y crear dos constantes con la directiva #define, es decir: #define TEXTO 0x03 #define GRAFICO 0x13 de esta manera para iniciar el modo 13h, llamaramos a la funcin SetMode de la siguiente forma SetMode(GRAFICO); y para volver al modo texto simplemente: SetMode(TEXTO); Veamos de la primera forma: #include <dos.h> para la funcion int86() # include <stdio.h> para la funcion printf() #include <conio.h> para la funcion getch()

Juan Carlos Gutirrez Barquero____________________________________________

103

Bismarck Salvador Traa Lpez__________________________________________ UNI


void Modo13h(void) { union REGS r; r.h.ah=0; r.h.al=0x13; int86(0x10, &r, &r); } void ModoTexto(void) { union REGS r; r.h.ah=0; r.h.al=0x03; int86(0x10, &r, &r); } void main(void) { Modo13h(); printf("Inicializacion correcta\npresione una tecla para volver\n al modo grafico"); getch(); ModoTexto(); printf("Regreso a modo VGA"); getch(); } De la segunda manera seria: #include <dos.h> para la funcion int86() # include <stdio.h> para la funcion printf() #include <conio.h> para la funcion getch() unsigned char *DIR_VGA=(unsigned char *) MK_FP(0xA000, 0); void Modo13h(void) { _AX=0x0013 ; geninterrupt(0x10) ; } void ModoTexto(void) { _AX=0x0003 ; geninterrupt(0x10) ; } void main(void) { Modo13h(); printf("Inicializacion correcta\npresione una tecla para volver\n al modo grafico");

Juan Carlos Gutirrez Barquero____________________________________________

104

Bismarck Salvador Traa Lpez__________________________________________ UNI

getch(); ModoTexto(); printf("Regreso a modo VGA"); getch(); } Un Ejemplo: Este es un ejemplo sencillo elaborado en el modo 13h (320*200) a 256 colores que realiza el efecto del fuego. El programa fue compilado con Turbo C Nota.- El programa debe ser compilado con alguno de estos modelos: COMPACT,LARGE o HUGE para que pueda funcionar correctamente. #include <dos.h> para MK_FP,poke,ouportb,geninterrupt #include <stdlib.h> para random() #include <conio.h> para kbhit() typedef unsigned char byte; byte far* Video= (byte far*)MK_FP(0xA000,0x000); void Setrgbpalette(byte c,byte r,byte g,byte b) { outportb(0x3c8,c); outportb(0x3c9,r); outportb(0x3c9,g); outportb(0x3c9,b); } void Modo13h(void) { _AL=0x13; _AH=0; geninterrupt(0x10); } void ModoTexto(void) { _AL=0x03; _AH=0; geninterrupt(0x10); } void main(void) { int x,y,c; Modo13h(); for(x=1;x<=32;x++){

Juan Carlos Gutirrez Barquero____________________________________________

105

Bismarck Salvador Traa Lpez__________________________________________ UNI


Setrgbpalette(x,x*2-1,0,0); Setrgbpalette(x+32,63,x*2-1,0); Setrgbpalette(x+64,63,63,x*2-1); Setrgbpalette(x+96,63,63,63); } do{ x=0; do{ y=60; do{ c=(Video[(y<<8)+(y<<6)+x]+Video[(y<<8)+(y<<6)+x+2]+ Video[(y<<8)+(y<<6)+x-2]+Video[(y+2)*320+x+2])/4; if(c!=0) c--; poke(0xA000,(y-2)*320+x,(c<<8)+c); poke(0xA000,(y-1)*320+x,(c<<8)+c); y+=2; }while(y<202); y-=2; Video[(y<<8)+(y<<6)+x]=random(2)*160; x+=2; }while(x<=320); }while(!kbhit()); ModoTexto(); } Ya vimos un ejemplo en el modo13h y que les parecio el efecto del fuego bonito no pero que dirian si les digo que hay otro metodo de inicializacion que puede darle mas realce a sus programas,!No es broma , si quieren saber un poco aqu les va: Se lla modo XGA Para poder ver estos ejemplos debes de tener intalada las librera que esta incluida en el tc20 que te obsequiamos

Modo grafico con resolucion de 1024x768x256


(1024 pixeles horizontales, 768 verticales, 256 colores) Antes que nada debes copiar el archivo Svga256.bgi ,que es un controlador para graficos, a la carpeta bin de TC20. Luego tienes que poner dentro del main la siguiente instruccin: installuserdriver(Svga256,DetectVGA256); Svga256 es nombre del dispositivo debes omitir la extensin .bgi DetectVGA256 es una funcin que debes declarar anteriormente como: int huge DetectVGA256() { return 4; } y luego puedes llamar a la funcion initgraph() para empezar a trabajar en modo grafico, para esta resolucion no estan disponibles las funciones setbkcolor(), ni cleardevice(). Aqu tienes el ejemplo completo:

Juan Carlos Gutirrez Barquero____________________________________________

106

Bismarck Salvador Traa Lpez__________________________________________ UNI


#include<conio.h> #include <graphics.h> int huge DetectVGA256() { /* 0 = 320x200x256 modo CGA 320(horizontal) con 200(vertical) pixeles(puntos) en 256colores 1 = 640x400x256 modo ATT400 2 = 640x480x256 modo VGA 3 = 800x600x256 modo SVGA 4 = 1024x768x256; modo XGA Todos son los modos graficos estandar */ return 4; } void main() { int modo = DETECT, tarj,TIPOLETRA; int color=0,x=180,y=50; /*/Instalamos el driver SVGA.bgi para acceder a 256 colores*/ installuserdriver("Svga256",DetectVGA256); /*Instalamos en nuestro proyecto el tipo de letra*/ TIPOLETRA = installuserfont("LITT.CHR"); /*Iniciamos el modo grafico*/ initgraph(&modo,&tarj,""); setfillstyle(SOLID_FILL,WHITE); /*elegimos el color de relleno para dibujar una barra */ bar(0 , 0, 1028, 768); /*y asi simulamos que hemos elegido un color de fondo*/ /*No se pueden utilizar los comandos cleardevice ni setbkcolor.*/ setcolor(7); while(color<256) { rectangle(x ,y ,x + 40, y + 40); setfillstyle(SOLID_FILL,color); bar(x + 1, y + 1, x + 39, y + 39); x = x + 40; color++; if((color%16==0)&&(color!=0)) { x = 180; y = y + 40; } } settextstyle(TIPOLETRA,0,9); /*usamos el tipo de letra*/ setcolor(41); /*usamos el color numero 18, un gris oscuro*/ outtextxy(40,10,"Prueba de Inicializacion del modo XGA 1024x768 pixeles"); settextstyle(TIPOLETRA,0,6); setcolor(BLACK);

Juan Carlos Gutirrez Barquero____________________________________________

107

Bismarck Salvador Traa Lpez__________________________________________ UNI


outtextxy(12,690,"Como ves ahora si puedes usar el color negro en tus aplicaciones y usar una mayor resolucion: 1024x768"); settextstyle(TIPOLETRA,0,7); setcolor(55); outtextxy(425,740,"Huacho - Peru"); getch(); closegraph(); } Ahora si quieren ver un programa funcionando a qui lo tienen Programa que carga imgenes .bmp en modo 1024x768: #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <graphics.h> #include <dos.h> #include <mouse.h> #define VAR 0 #define INVALIDO -1 #define FALLA 0 #define EXITO 1 #define KB_ESC 27 /* MACROS PARA LAS FUNCIONES GRAFICAS */ #define SEG_VIDEO 0xA000 #define M320x200 0x13 #define MTexto 0x3 struct cabecera { char ident[2]; unsigned long int tam; char reservado[4]; unsigned long int offset; }; struct info_general { unsigned long int tam_cabecera; unsigned long int anchura; /* en pixels */ unsigned long int altura; /* en pixels */ int planos; int tam_pixel; /* tamao en bits de cada pixel */ unsigned long int compresion; unsigned long int tam_imagen; /* en bytes */ unsigned long int h_resolution; unsigned long int v_resolution; unsigned long int num_color; /* numero de colores utilizados */ unsigned long int color_imp; /* numeros de colores importantes */ };

Juan Carlos Gutirrez Barquero____________________________________________

108

Bismarck Salvador Traa Lpez__________________________________________ UNI

struct valor_rgb { unsigned char azul; unsigned char verde; unsigned char rojo; unsigned char reservado; }; void modo_video(unsigned char modo); void setpal(char col,char r,char g,char b); /*void putpixel(unsigned int x, unsigned int y, unsigned char color);*/ /*-------------------------------------------------------------------------*/ char verifica(char *fname); void mostrar_pal(void); void carga(void); void menu(void); void presentacion(void); void info_general(void); void paleta(void); void mostrar_imagen(void); void cambiar_pal(struct valor_rgb *pal); void despedida(void); struct cabecera bmp_cab; struct info_general bmp_info; struct valor_rgb *rgb; FILE *f; char fname[50]; int main() { presentacion(); fclose(f); free(rgb); /* liberamos la memoria utilizada */ return 0; } void carga(void) { register int i; /* leemos la cabecera del archivo */ fread( &bmp_cab, sizeof(struct cabecera), 1, f); /* leemos la informacion general del archivo */ fread( &bmp_info, sizeof(struct info_general), 1, f); /*leemos todos los colores que existen en la imagen */ if (!bmp_info.num_color) /* si se usan todos los colores */

Juan Carlos Gutirrez Barquero____________________________________________

109

Bismarck Salvador Traa Lpez__________________________________________ UNI


bmp_info.num_color = 1 << bmp_info.tam_pixel; /* calculamos dependiendo del numero de bits que ocupa cada pixel */ /* reservamos memoria dinamica para la tabla de colores RGB */ rgb = (struct valor_rgb *) malloc (bmp_info.num_color * sizeof(struct valor_rgb)); fread(rgb, bmp_info.num_color * sizeof(struct valor_rgb), 1, f); } void presentacion(void) { char control; clrscr(); printf("%55s","---VISUALIZADOR DE IMAGENES BMP---"); printf("\n\n\n Introduzca el nombre y ruta de ser necesario"); printf("\n ARCHIVO: "); gets(fname); if (!fname[0]) exit(0); control = verifica(fname); if (control == FALLA) { printf("\n ERROR FATAL: el archivo no existe o esta protegido..."); exit(1); } if (control == INVALIDO) { printf("\n ERROR FATAL: el archivo no es un BMP valido... "); exit(1); } /* llamamos al menu principal */ menu(); } char verifica(char *fname) { f = fopen(fname,"rb"); if (!f) return (FALLA); carga(); /* leemos y almacenamos del archivo */ /* comprobamos que sea un archivo valido BMP */ if (bmp_cab.ident[0] == 'B' && bmp_cab.ident[1] == 'M') return (EXITO);

Juan Carlos Gutirrez Barquero____________________________________________

110

Bismarck Salvador Traa Lpez__________________________________________ UNI


else return (INVALIDO); } void menu(void) { char opcion; for (;;) { clrscr(); printf("\n\n (1) INFORMACION GENERAL DEL ARCHIVO"); printf("\n\n (2) PALETA DE COLORES USADAS"); printf("\n\n (3) MOSTRAR PALETA"); printf("\n\n (4) VISUALIZAR IMAGEN"); printf("\n\n (5) SALIR"); printf("\n\n OPCION: "); opcion = getche(); switch (opcion) { case '1': info_general(); break; case '2': paleta(); break; case '3': mostrar_pal(); break; case '4': mostrar_imagen(); break; case '5': despedida(); } } /* termina bucle for(;;) */ } void info_general(void) { clrscr(); printf("%35s%s>\n","<",fname); printf("\n Tamao del archivo: %ld bytes",bmp_cab.tam); printf("\n Offset del archivo: %ld",bmp_cab.offset); printf("\n Tamao de la cabecera: %d bytes",bmp_info.tam_cabecera); printf("\n Anchura: %d pixels",bmp_info.anchura); printf("\n Altura: %d pixels",bmp_info.altura); printf("\n Numero de planos: %d",bmp_info.planos); printf("\n Numero de bits por pixel: %d bits",bmp_info.tam_pixel); printf("\n Compresion: %d ",bmp_info.compresion); printf("\n Tamao de la imagen: %ld bytes",bmp_info.tam_imagen); printf("\n Resolucion horizontal: %d pixels/metros",bmp_info.h_resolution); printf("\n Resolucion vertical: %d pixels/metros",bmp_info.v_resolution); printf("\n Numero de colores utilizados: %d colores",bmp_info.num_color); printf("\n Numero de colores importantes: %d colores",bmp_info.color_imp); printf("\n\n\n PRESIONE CUALQUIER TECLA PARA CONTINUAR...");

Juan Carlos Gutirrez Barquero____________________________________________

111

Bismarck Salvador Traa Lpez__________________________________________ UNI

getch(); } void cambiar_pal(struct valor_rgb *pal) { register int i; for (i = 0; i < 256; i++) setpal( i, pal[i-VAR].rojo / 4, pal[i-VAR].verde / 4, pal[i-VAR].azul / 4); } void paleta(void) { register int i,j; char opcion; clrscr(); printf("\n %10s %10s %10s %10s\n\n","Color","Rojo","Verde","Azul"); for (i = 0, j = 1; i <= (bmp_info.num_color); i++, j++) { if (j == 20 || i == (bmp_info.num_color) ) { j = 0; i--; gotoxy(1,25); printf(" Presione [ESC] para salir o cualquier tecla para continuar...."); opcion = getch(); if (opcion == KB_ESC) break; if (i+1 == (bmp_info.num_color)) break; clrscr(); printf("\n %10s %10s %10s %10s\n\n","Color","Rojo","Verde","Azul"); continue; } printf("\n %10d %10d %10d %10d", i, rgb[i].rojo, rgb[i].verde, rgb[i].azul); } } void mostrar_imagen(void) { register int x,y; char *linea; int resto; unsigned long int posicion; posicion = ftell(f); /* tomamos la posicion del puntero del archivo */

Juan Carlos Gutirrez Barquero____________________________________________

112

Bismarck Salvador Traa Lpez__________________________________________ UNI


modo_video(M320x200); mver(); cambiar_pal(rgb); /* reservamos memoria suficiente para albergar una linea de pixeles */ linea = (char *) malloc (bmp_info.anchura); /* calculamos la cantidad de bytes necesario que sumado con la anchura sea un multiplo de cuatro */ resto = (4 * ((bmp_info.anchura + 3) >> 2)) - bmp_info.anchura; for (y = bmp_info.altura - 1; y >= 0; y--) { fread(linea, bmp_info.anchura, 1, f); for (x = 0; x < bmp_info.anchura; x++) putpixel(x,y,linea[x]); fseek(f, resto, SEEK_CUR); } getch(); fseek(f, posicion, SEEK_SET); /* restauramos la posicion inicial del puntero */ modo_video(MTexto); } void mostrar_pal(void) { register int i,j; modo_video(M320x200); cambiar_pal(rgb); for (i = 0; i < 256; i++) for (j = 0; j <= 50; j++) putpixel(i,j,i); getch(); modo_video(MTexto); } void despedida(void) { clrscr(); gotoxy(20,13); printf("ESPERO QUE HAYA DISFRUTADO DEL PROGRAMA..."); getch(); exit(0); }

Juan Carlos Gutirrez Barquero____________________________________________

113

Bismarck Salvador Traa Lpez__________________________________________ UNI


/* ----FUNCIONES GRAFICAS ESCRITAS EN ENSAMBLADOR PARA SU MAYOR RAPIDEZ---- */ int huge DetectVGA256() { return 4; } void modo_video() { int a=DETECT,b; installuserdriver("Svga256",DetectVGA256); initgraph(&a,&b,"c:\\tc20\\bin"); /* union REGS r; r.h.ah=0; r.h.al=0x13; int86(0x10,&r,&r);*/ } /*void putpixel(unsigned int x, unsigned int y, unsigned char color) { unsigned char *vga=(unsigned char *) MK_FP(0xA000, 0); asm { push ax push bx push di push es mov ax,SEG_VIDEO mov es,ax mov bx,[y] mov di,bx shl bx,8 shl di,6 add di,bx add di,[x] mov bl,[color] mov es:[di],bl pop es pop di pop bx pop ax } memset(vga+x+(y*320),color,1); }*/

void setpal(char col,char r,char g,char b) {

Juan Carlos Gutirrez Barquero____________________________________________

114

Bismarck Salvador Traa Lpez__________________________________________ UNI


/*asm { mov dx,03c8h; mov al,col; out dx,al; mov dx,03c9h; mov al,r; out dx,al; mov al,g; out dx,al; mov al,b; out dx,al; } */ outportb(0x3c8,col); outportb(0x3c9,r); outportb(0x3c9,g); outportb(0x3c9,b); } Ahora un Ejemplo de la utilizacin de las estructuras este programa se llama reloj analogo muestra la hora del sistema. #include <graphics.h> #include <stdio.h> #include <dos.h> #include <math.h> #include <conio.h> #include <stdio.h> void main(void) { struct time tiempo; int a=DETECT,b; int radio=180; int seg,min,w,h; float angulmin, anguloseg, angulhora,hora; char mensaje[20]; int xseg, yseg, xmin, ymin, xhora, yhora; initgraph(&a,&b,"c:\\tc20\\bin"); circle(310,240,238); h=0; for(w=0;w<=60;w++){ if(h%5==0) setcolor(RED); else setcolor(WHITE); outtextxy(310+sin(6*h*(3.141592/180))*225,240-cos(h*(3.141592/180)*6)*225,"*"); h+=1; }

Juan Carlos Gutirrez Barquero____________________________________________

115

Bismarck Salvador Traa Lpez__________________________________________ UNI


settextstyle(1,0,2); outtextxy(300,20,"12"); outtextxy(520,230,"3"); outtextxy(310,433,"6"); outtextxy(100,230,"9"); do{ gettime(&tiempo); seg=tiempo.ti_sec; min=tiempo.ti_min; hora=tiempo.ti_hour; if(hora>12) hora-=12; hora+=(min/60); anguloseg=((seg-15)/(3*3.14159)); angulmin=((min-15)/(3*3.14159)); angulhora=((hora*5-15)/(3*3.14159)); setcolor(WHITE); circle(310,240,8); rectangle(240,390,360,420); sprintf(mensaje,"%2.0f: %2.0d: %2.0d",hora,tiempo.ti_min,tiempo.ti_sec); outtextxy(250,390,mensaje); xseg = 310 + radio * cos(anguloseg); yseg = 240 + radio * sin(anguloseg); xmin = 310 + 120 * cos(angulmin); ymin = 240 + 120 * sin(angulmin); xhora= 310 + 90 * cos(angulhora); yhora= 240 + 90 * sin(angulhora); setcolor(WHITE); line(310,240,xseg,yseg); setcolor(GREEN); line(310,240,xmin,ymin); setcolor(RED); line(310,240,xhora,yhora); sleep(1); setcolor(BLACK); line(310,240,xseg,yseg); line(310,240,xmin,ymin); line(310,240,xhora,yhora); outtextxy(250,390,mensaje); } while(!kbhit()); }

Juan Carlos Gutirrez Barquero____________________________________________

116

Bismarck Salvador Traa Lpez__________________________________________ UNI


Ahora aremos un efecto que talvez les guste y lo estudien con detenimiento ya que merece mucha atencin. Primero guarda estas lineas de codigo en un programa de C con el nombre TECLA.C #define ARRIBA 72 #define ABAJO 80 #define DERECHA 77 #define IZQUIERDA 75 #define ESC 27 #define ENTER 13 Ahora en otro programa copia este codigo y te sorprenderas de ver lo que hace #include <graphics.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #include <dos.h> #include <conio.h> #include "tecla.c" //es para el manejo del teclado float A,B,TAM=15,fi= -M_PI/7,teta= -M_PI/7,pro_X,pro_Y; /* Definicion de funciones */ void IniciarGraficos(); void xyz(); void ProyectaPunto(float ,float ,float); void Objeto(); void instrucciones(); /*****************************************************************/ /* ProyectaPunto Funcion: Localiza un punto en la pantalla 3D */ void ProyectaPunto(float x, float y, float z) { pro_X = y*cos(teta) + x*sin(teta); pro_Y = z*cos(fi) + x*cos(teta)*sin(fi) - y*sin(fi)*sin(teta); } /* IniciarGraficos Funcion: Inicializa el modo grafico

Juan Carlos Gutirrez Barquero____________________________________________

117

Bismarck Salvador Traa Lpez__________________________________________ UNI


*/ void IniciarGraficos() { int Tarjeta=VGA,Modo=VGAHI; initgraph(&Tarjeta,&Modo,""); if(graphresult()!=grOk){ printf("\nSi perdiste el archivo EGAVGA.BGI no podes correr el programa : ( asi que buscalo el C:\\tc\\bgi"); getch(); exit(0); } } /* Main Funcion: Main. */ void main() { IniciarGraficos(); A=getmaxx()/2,B=getmaxy()/2; xyz(); Objeto(); closegraph(); } /* xyz Funcion: Dibuja Lineas de Guia en las coordenadas X,Y,Z */ void xyz() { float X0,Y0,X,Y,z,tam=3; int x,y; setcolor(8); ProyectaPunto(0,0,0);X0 = pro_X,Y0 = pro_Y; ProyectaPunto(tam,0,0);X = pro_X,Y = pro_Y; line(A + X0*TAM,B - Y0*TAM,A + X*TAM,B - Y*TAM); x=A + X*TAM,y=B - Y*TAM; setcolor(8); outtextxy(x,y,"x"); setcolor(8); ProyectaPunto(0,tam,0);X = pro_X,Y = pro_Y; line(A + X0*TAM,B - Y0*TAM,A + X*TAM,B - Y*TAM);

Juan Carlos Gutirrez Barquero____________________________________________

118

Bismarck Salvador Traa Lpez__________________________________________ UNI


x= A + X*TAM,y=B - Y*TAM; setcolor(8); outtextxy(x,y,"y"); setcolor(8); ProyectaPunto(0,0,tam);X = pro_X,Y = pro_Y; line(A + X0*TAM,B - Y0*TAM,A + X*TAM,B - Y*TAM); setcolor(8); x=A + X*TAM,y=B - Y*TAM; outtextxy(x,y,"z"); ProyectaPunto(0,10,0);X=pro_X,Y = pro_Y; x=A + X*TAM,y=B - Y*TAM; setcolor(RED); outtextxy(x,y,"JDZx"); setcolor(8); } /* Objeto Funcion: Dibuja un objeto 3D */ void Objeto() { float angulo=-M_PI/100.0; float AA[8],BB[8],CC[12],estrellas[2],EE[8],FF[8], xa1=3,ya1=-3,za1=-3,xa2=-3,ya2=-3,za2=-3, xa3=-3,ya3=-3,za3=3,xa4=3,ya4=-3,za4=3, xb1=3,yb1=3,zb1=-3,xb2=-3,yb2=3,zb2=-3, xb3=-3,yb3=3,zb3=3,xb4=3,yb4=3,zb4=3; float x,y; unsigned char tecla; int fo; do{ ProyectaPunto(xa1,ya1,za1);AA[0]=pro_X,AA[1]=pro_Y; ProyectaPunto(xa2,ya2,za2);AA[2] = pro_X,AA[3] = pro_Y; ProyectaPunto(xa3,ya3,za3);AA[4] = pro_X,AA[5] = pro_Y; ProyectaPunto(xa4,ya4,za4);AA[6] = pro_X,AA[7] = pro_Y; /*-------------------------------------------*/ ProyectaPunto(xb1,yb1,zb1);BB[0]=pro_X,BB[1]=pro_Y; ProyectaPunto(xb2,yb2,zb2);BB[2] = pro_X,BB[3] = pro_Y; ProyectaPunto(xb3,yb3,zb3);BB[4] = pro_X,BB[5] = pro_Y; ProyectaPunto(xb4,yb4,zb4);BB[6] = pro_X,BB[7] = pro_Y; ProyectaPunto(5,8,0);CC[0]=pro_X,CC[1]=pro_Y; ProyectaPunto(-4,-8,0);CC[4]=pro_X,CC[5]=pro_Y; ProyectaPunto(5,-5,3);CC[6]=pro_X,CC[7]=pro_Y; ProyectaPunto(10,5,-1);CC[8]=pro_X,CC[9]=pro_Y; ProyectaPunto(0,0,0);CC[10]=pro_X,CC[11]=pro_Y; setcolor(1);

Juan Carlos Gutirrez Barquero____________________________________________

119

Bismarck Salvador Traa Lpez__________________________________________ UNI


circle(A + CC[0]*TAM,B - CC[1]*TAM,TAM*0.52); setcolor(2); circle(A + CC[4]*TAM,B - CC[5]*TAM,TAM*0.25); setcolor(3); circle(A + CC[6]*TAM,B - CC[7]*TAM,TAM*0.8); setcolor(4); circle(A + CC[8]*TAM,B - CC[9]*TAM,TAM*2.5); setcolor(YELLOW); circle(A + CC[10]*TAM,B - CC[11]*TAM,TAM*2.2); /*-----------------------*/ ProyectaPunto(5,0,2);estrellas[0] = pro_X,estrellas[1] = pro_Y; putpixel(A + estrellas[0]*TAM,B - estrellas[1]*TAM,7); ProyectaPunto(-15-0.2,5,-2);estrellas[0] = pro_X,estrellas[1] = pro_Y; setcolor(8); circle(A + estrellas[0]*TAM,B - estrellas[1]*TAM,TAM*0.2); ProyectaPunto(-10,-3,-2);estrellas[0] = pro_X,estrellas[1] = pro_Y; putpixel(A + estrellas[0]*TAM,B - estrellas[1]*TAM,7); ProyectaPunto(-10,-3,-2);estrellas[0] = pro_X,estrellas[1] = pro_Y; putpixel(B + estrellas[1]*TAM,A - estrellas[1]*TAM,7); ProyectaPunto(-5,3,-2);estrellas[0] = pro_X,estrellas[1] = pro_Y; putpixel(A + estrellas[0]*TAM,B - estrellas[1]*TAM,7); ProyectaPunto(10,-3,-2);estrellas[0] = pro_X,estrellas[1] = pro_Y; putpixel(A + estrellas[0]*TAM,B - estrellas[1]*TAM,7); xyz(); line(A + AA[0]*TAM,B - AA[1]*TAM,A + AA[2]*TAM,B - AA[3]*TAM); line(A + AA[4]*TAM,B - AA[5]*TAM,A + AA[6]*TAM,B - AA[7]*TAM); line(A + AA[0]*TAM,B - AA[1]*TAM,A + AA[6]*TAM,B - AA[7]*TAM); line(A + AA[2]*TAM,B - AA[3]*TAM,A + AA[4]*TAM,B - AA[5]*TAM); line(A + AA[0]*TAM,B - AA[1]*TAM,A + BB[0]*TAM,B - BB[1]*TAM); line(A + AA[2]*TAM,B - AA[3]*TAM,A + BB[2]*TAM,B - BB[3]*TAM); line(A + AA[4]*TAM,B - AA[5]*TAM,A + BB[4]*TAM,B - BB[5]*TAM); line(A + AA[6]*TAM,B - AA[7]*TAM,A + BB[6]*TAM,B - BB[7]*TAM); line(A + BB[0]*TAM,B - BB[1]*TAM,A + BB[2]*TAM,B - BB[3]*TAM); line(A + BB[2]*TAM,B - BB[3]*TAM,A + BB[4]*TAM,B - BB[5]*TAM); line(A + BB[4]*TAM,B - BB[5]*TAM,A + BB[6]*TAM,B - BB[7]*TAM); line(A + BB[6]*TAM,B - BB[7]*TAM,A + BB[0]*TAM,B - BB[1]*TAM); tecla=IZQUIERDA; if(kbhit()) { tecla=getch(); } setfillstyle(1,0);

Juan Carlos Gutirrez Barquero____________________________________________

120

Bismarck Salvador Traa Lpez__________________________________________ UNI


switch(tecla) { case DERECHA:teta-=angulo;break; case IZQUIERDA:teta+=angulo;break; case ABAJO:fi+=angulo;break; case ARRIBA:fi-=angulo;break; case 122:if(TAM>0)TAM-=0.2;break; case 120:if(TAM<30)TAM+=0.2;break; }/*endcase*/ if(!kbhit()){delay(50);} bar(0,0,getmaxx(),getmaxy()); }while(tecla!=ESC); } /*Ahora un juego de la serpientes este es un programa que encontre en Internet, no se quien es el autor, le hice algunos cambios */ #include<stdlib.h> # include <dos.h> #include<stdio.h> #include<conio.h> #include<graphics.h> #define clear; clrscr(); #define colorfondo 0 #define colorcabeza 4 #define c 1 #define bordear 40 #define bordeab 460 #define bordeiz 20 #define bordede 620 /*acotamos la parte valida de pantalla*/

void Inicio(void); void Salir(void); void Juego(void); void Avanza(void); void Crece(void); void Libera(void); void Pinta_serpiente(void); void Pinta_rapido(void); int Choque(void); void Pinta_pantalla(void); int Es_punto(int x,int y); void Lee_record(void); void Escribe_record(void);

Juan Carlos Gutirrez Barquero____________________________________________

121

Bismarck Salvador Traa Lpez__________________________________________ UNI


struct bola{ int x; int y; /*La serp no es mas que una lista doble de puntos con su x y su y*/ struct bola *sig,*ant; }; int m,v,vel,tarj,modo,puntos,max,punt[9]={90,80,70,60,50,40,30,20,10}; int longitud=0,radio=5,xa,ya,superado=0; /*No hay mas remedio que usar todas estas globales*/ struct bola *cabeza,*indice,*ultimo; /*Para la lista*/ void main(void) { detectgraph(&tarj,&modo);/*comprueba el hw y detecta la tarjeta a usar*/ Inicio(); Juego(); } void Inicio(void) { int i; clear; textcolor(14); for (i=1; i<81; i++) { gotoxy(i,9); cprintf (""); } textcolor(1); gotoxy(34,1); cprintf (" "); gotoxy(34,2); cprintf (" "); gotoxy(34,3); cprintf (" "); gotoxy(34,4); cprintf (" "); gotoxy(34,5); cprintf (" "); gotoxy(33,6); cprintf (""); gotoxy(33,7); cprintf (""); gotoxy(34,8); cprintf (""); gotoxy(38,9); cprintf ("");gotoxy(42,9); cprintf(""); textcolor(4); gotoxy(40,1); cprintf("");gotoxy(40,2); cprintf(""); gotoxy(40,3); cprintf("");gotoxy(40,4); cprintf(""); gotoxy(36,4); cprintf("");gotoxy(44,4); cprintf(""); gotoxy(36,5); cprintf("");gotoxy(44,5); cprintf(""); gotoxy(39,7); cprintf("O");gotoxy(41,7); cprintf("O");

Juan Carlos Gutirrez Barquero____________________________________________

122

Bismarck Salvador Traa Lpez__________________________________________ UNI


textcolor(9); gotoxy(31,10); cprintf (" "); gotoxy(31,11); cprintf (" "); gotoxy(31,12); cprintf (" "); gotoxy(31,13); cprintf (" "); gotoxy(31,14); cprintf (" "); textcolor(15); gotoxy(29,16); cprintf ("Diseado por Abdul Ruiz"); gotoxy(31,17); cprintf ("CopyRight (c) 2002"); getch(); gotoxy(29,19); cprintf("Espera, por favor..."); delay(5500); clear; cprintf("TECLAS:\n\n\r"); cprintf(" -(Ar) 5(Ar)\n\r"); cprintf("MOVIMIENTOS o en el t.num.\n\r"); cprintf(" <(Izq) (Ab) >(Der) 1(Izq) 2(Ab) 3(Der)\n\r"); cprintf("Pausa: P\n\r"); cprintf("Salir: S\n\n\r"); cprintf("Si utilizas el teclado numerico, asegurate de que este activado\n\n\n\r"); cprintf("Pulsa una tecla para empezar"); getch(); sleep(5); clear; cprintf ("Dime el nivel de dificultad 1(Minima)...9(Maxima): "); do{ scanf("%d",&m); }while(m<1 || m>9); switch(m) { case 1:v=9;break;case 2:v=8;break;case 3:v=7;break;case 4:v=6;break;case 5:v=5;break; case 6:v=4;break;case 7:v=3;break;case 8:v=2;break;case 9:v=1;break; } } void Juego(void) { int obj=0;/*Para saber si hay algo de comida en la pantalla*/ int mov=radio*2; char t,a;/*La tecla pulsada y la anterior*/ char pito=7; int x2,y2; initgraph(&tarj,&modo,"c:\\tc20\\bin");/*iniciamos modo grafico*/ setbkcolor(colorfondo);/*configuramos los colores del juego*/ setcolor(colorfondo); setfillstyle(1,c);

Juan Carlos Gutirrez Barquero____________________________________________

123

Bismarck Salvador Traa Lpez__________________________________________ UNI

Lee_record(); t=77;/*ponemos una tecla (para que empiece yendo hacia la derecha)*/ superado=0; vel=v*300; Crece(); /*creamos la cabeza*/ cabeza->x=bordeiz+radio; /*la colocamos*/ cabeza->y=bordeab-radio; Crece(); /*ponemos otras dos bolitas de cuerpo*/ Crece(); Pinta_pantalla(); gotoxy(35,15); printf("ADELANTE"); delay(10000); cleardevice(); do { /*si no hay objeto, cogemos una pos aleatoria*/ if(obj==0) { do{ do{ x2=(((rand()%((bordede/(radio*2))-1)+1))*radio*2)-radio; }while(x2>bordede-radio || x2<bordeiz+radio); do{ y2=(((rand()%((bordeab/(radio*2))-1)+1))*radio*2)-radio; }while(y2>bordeab-radio || y2<bordear+radio); }while(Es_punto(x2,y2)); obj=1; } /*si se pulsa una tecla*/ if(kbhit()) { a=t; /*se guarda la anterior*/ t=getch(); /* y se coge*/ } if(Choque()) { printf("%c",pito); /*si se choca, pierde*/ Salir(); }

Juan Carlos Gutirrez Barquero____________________________________________

124

Bismarck Salvador Traa Lpez__________________________________________ UNI

Pinta_pantalla(); if(obj==1) /*si hay objeto, lo pintamos de otro color*/ { setfillstyle(1,12); fillellipse(x2,y2,radio-2,radio-2); setfillstyle(1,c); } switch(t) /*evalua la tecla*/ { case 72: case '5': Avanza(); cabeza->y=cabeza->y-mov; break; /*arriba */ case 75: case '1': Avanza(); cabeza->x=cabeza->x-mov; break; /*izquierda */ case 77: case '3': Avanza(); cabeza->x=cabeza->x+mov; break; /*derecha */ case 80: case '2': Avanza(); cabeza->y=cabeza->y+mov; break; /*abajo*/ case 's': case 'S': /*si quiere salir, liberamos mem, cerramos el modo grafico y exit*/ Libera(); closegraph(); Escribe_record(); exit(2); break; case 'p':/*pausa*/

Juan Carlos Gutirrez Barquero____________________________________________

125

Bismarck Salvador Traa Lpez__________________________________________ UNI


cleardevice(); Pinta_serpiente(); gotoxy(37,15); printf("Pausa"); t=getch(); cleardevice(); Pinta_serpiente(); break; /*si la tecla pulsada no hace nada, volvemos a poner la enterior*/ default: t=a; } /*si se pasa por encima del objeto, se borra y se crece*/ if(cabeza->x==x2 && cabeza->y==y2) { puntos+=punt[v-1]; obj=0; printf("%c",pito); switch(m) { case 1: Crece(); break; case 2: case 3: Crece();Crece();break; case 4: case 5: Crece();Crece();Crece();break; case 6: case 7: case 8: Crece();Crece();Crece();Crece();Crece();break; case 9: Crece();Crece();Crece();Crece();Crece();Crece();break; } } /*cuantas mas bolas tenga que dibujar el ordenador, mas se*/ /*ralentiza el juego, esto lo contrarestamos disminuyendo el delay*/ /*cada 30 bolitas(lo he calculado a ojo) if((longitud)/(i*30)<0) { vel-=15; i++; }*/ delay(vel); if(puntos>max) {

Juan Carlos Gutirrez Barquero____________________________________________

126

Bismarck Salvador Traa Lpez__________________________________________ UNI


max=puntos; superado=1; } }while(1); } void Salir(void) { char opc; /*no hace falta comentar nada*/ if(superado!=0) { Escribe_record(); gotoxy(11,10); printf(" Puntuacion maxima conseguida, eres el mejor, felicidades"); } gotoxy(11,15); printf("Estas muerto, lo siento (R)Reintentar,(I)Reiniciar,(S)Salir"); do{ opc=toupper(getch()); }while(opc!='R' && opc!='I' && opc!='S'); puntos=0; switch (opc) { case 'R': Libera(); Juego(); break; case 'I': closegraph(); Libera(); Inicio(); Juego(); break; case 'S': closegraph(); Libera(); exit(1); break; } } void Avanza(void) { indice=ultimo;

Juan Carlos Gutirrez Barquero____________________________________________

127

Bismarck Salvador Traa Lpez__________________________________________ UNI

xa=ultimo->x; ya=ultimo->y; /*nos quedamos con la posicion de la cola*/ /*corremos cada bola a la pos de la bola anterior*/ while(indice!=cabeza) { indice->x=indice->ant->x; indice->y=indice->ant->y; indice=indice->ant; } } void Pinta_serpiente(void) { int i=0; indice=cabeza; setfillstyle(1,colorcabeza); fillellipse(indice->x,indice->y,radio,radio); setfillstyle(1,c); i++; indice=indice->sig; /*sin comentarios*/ while(i<longitud) { fillellipse(indice->x,indice->y,radio,radio); i++; indice=indice->sig; } } /*Como hemos comprobado en anteriores versiones, al pintar la serpiente entera*/ /*, si esta media mucho, se ralentizaba el juego mogollon, y sabemos que, al pintar*/ /*una bola y moverla, se queda su estela pintada, no?, coo pues pintemos solo*/ /*la primera, segunda y ultima bolita, y asi, mida lo que mida la serpiente,*/ /*solo pintaremos 3 bolas, y no se ralentiza casi nada.*/ void Pinta_rapido(void) { setfillstyle(1,colorcabeza); fillellipse(cabeza->x,cabeza->y,radio,radio); setfillstyle(1,c); fillellipse(cabeza->sig->x,cabeza->sig->y,radio,radio); fillellipse(ultimo->x,ultimo->y,radio,radio);

Juan Carlos Gutirrez Barquero____________________________________________

128

Bismarck Salvador Traa Lpez__________________________________________ UNI


} int Choque(void) { indice=cabeza->sig; /*si la cabeza esta en la pos de alguna bola o sale de los limites, devolvemos un 1*/ while(indice!=NULL) { if(cabeza->x==indice->x && cabeza->y==indice->y) return 1; if((cabeza->y<bordear+radio)||(cabeza->x<bordeiz+radio)||(cabeza>x>bordede-radio)||(cabeza->y>bordeab-radio)) return 1; indice=indice->sig; } return 0; } void Crece(void) { struct bola *este; este=malloc(sizeof(struct bola)); /*pues eso, se aade una struct bola al final de la lista*/ if(cabeza==NULL) { ultimo=cabeza=este; cabeza->ant=NULL; ultimo->sig=NULL; cabeza->x=bordeiz+radio; cabeza->y=bordeab-radio; } else { ultimo->sig=este; este->ant=ultimo; ultimo=este; ultimo->sig=NULL; este->x=-100; este->y=-100; } indice=ultimo; longitud++; }

Juan Carlos Gutirrez Barquero____________________________________________

129

Bismarck Salvador Traa Lpez__________________________________________ UNI

void Libera(void) { struct bola *aux; indice=cabeza; /*no hace falta comentario*/ cabeza=ultimo=NULL; while(indice!=ultimo) { aux=indice; indice=indice->sig; free(aux); } aux=indice; free(aux); longitud=0; } void Pinta_pantalla(void) { gotoxy(1,1); printf(" Serpiente v1 Desarrollado por Abdul Ruiz Chaos\n\r"); gotoxy(10,2); printf("Nivel : %1d Punt.Max. : %4d Puntuacion :%4d Longitud : %4d",m,max,puntos,longitud); Pinta_rapido(); /* dibujamos la serp */ /*"borramos" la ultima bola*/ /*este metodo es mas util, porque usando un cleardevice(), la pantalla vibraba mucho*/ setfillstyle(1,colorfondo); fillellipse(xa,ya,radio,radio); setfillstyle(1,c); /* dibujamos los bordes de la pantalla */ setcolor(15); rectangle(bordeiz-1,bordear-1,bordede+1,bordeab+1); setcolor(0); } int Es_punto(int x,int y) { indice=cabeza->sig;

Juan Carlos Gutirrez Barquero____________________________________________

130

Bismarck Salvador Traa Lpez__________________________________________ UNI


while(indice!=NULL) { if(x==indice->x && y==indice->y) return 1; indice=indice->sig; } return 0; } void Lee_record(void) { FILE *arch; if((arch=fopen("chaos.ars","rb"))!=NULL) { fread(&max,1,sizeof(int),arch); if(puntos>max) { max=puntos; } fclose(arch); } else { max=puntos; } } void Escribe_record(void) { FILE *arch; arch=fopen("chaos.ars","wb"); fwrite(&max,1,sizeof(int),arch); fclose(arch); }

Juan Carlos Gutirrez Barquero____________________________________________

131

Bismarck Salvador Traa Lpez__________________________________________ UNI

1 Introduccin a la Geometra Computacional 1.1. Historia de la Geometra Computacional

La Geometra fue estudiada desde la antigua Grecia y Egipto. Constituan una herramienta muy importante para resolver problemas prcticos. El primer algoritmo que pueda considerarse completo es la construccin Eucldea, porque fue el primero que satisfizo todos los requerimientos: es correcto, no ambiguo y tiene un final. Este algoritmo adems da una coleccin de instrucciones y reglas, posee un conjunto de primitivas asociadas. Ya en 1902 se describi un conjunto de pasos para contar como realizar sobre papel una serie de primitivas Eucldeas. Se hablaba por entonces ya del trmino complejidad, no computacional pero s de dificultad para medir la complicacin de su realizacin. Se puede decir que fue una aproximacin a lo que entendemos hoy por .complejidad temporal.. No se hablaba del problema en funcin del conjunto de entrada, pero s intentaban reducirse el nmero de pasos a realizar para resolver un problema. Poco a poco se fueron dando cuenta de que todo problema posee un esfuerzo mnimo de realizacin, lo que nosotros llamamos .complejidad del algoritmo.. Ya en 1672 se demostr que cualquier construccin que pudiera realizarse slo con regla y comps podra hacerse usando slo comps. El concepto de lnea se ampli pasando a ser el lugar geomtrico compuesto por la unin de los puntos de corte de dos arcos realizados con un comps. La Geometra ha tenido momentos de especial realce, por ejemplo el crecimiento del anlisis real, la Geometra mtrica y la teora de la convexidad, han supuesto las herramientas matem ticas para el diseo de algoritmos rpidos. Por un lado la distancia es un tema esencial en conceptos geomtricos y la teora de la convexidad es analizada para obtener propiedades globales. La Geometra Algortmica est basada en caracterizaciones de objetos geomtricos en trminos de propiedades de subconjuntos finitos. Un tratamiento algortmico implica eliminar el trmino infinito. Hoy da la Geometra Computacional se utiliza como herramienta bsica, no slo en disciplinas inmediatamente relacionadas con la Geometra. A partir de finales de los aos 60 y 70, el incremento del uso de la computadoras en investigacin y desarrollo, propicia usar estas mquinas para resolver problemas clsicos que siempre fueron resueltos a base de reglas y comps. Pero la memoria de las mquinas y el tiempo de ejecucin de stas, la mayora de las veces compartido, exigi de pronto el conseguir mtodos que no slo funcionaran, sino que intentaran optimizar al mximo dos recuerdos muy importantes, sobre todo por aquel entonces: la memoria y el tiempo de CPU. Hoy por hoy a pesar de utilizar mquinas ms potentes, tambin se plantea en

Juan Carlos Gutirrez Barquero____________________________________________

132

Bismarck Salvador Traa Lpez__________________________________________ UNI


muchas ocasiones incrementar el nmero de datos a procesar, por lo que hoy sigue siendo un problema a resolver. Algunas aplicaciones donde la Geometra Computacional es necesaria es la Informtica Grfica, Robtica, Sistemas de Informacin Geogrficos, etc. El trmino nace en 1975 por Shamos y desde entonces los trabajos y los estudios en esta disciplina han ido creciendo de forma espectacular. 1.2. Eficiencia de los algoritmos

Existen distintas formas de medir algoritmos o de clasificarlos. Un algoritmo fcil de entender, codificar y depurar es preferible a otro que realice lo mismo pero que no cumpla estas carcter sticas. Algo similar ocurre con respecto a la eficiencia; un algoritmo es eficiente cuando usa adecuadamente los recursos del ordenador y lo hace con la mayor rapidez posible. Los recursos son siempre referidos al tiempo de ejecucin y al tiempo de CPU que necesita para ejecutarse. Para optar por escribir un tipo de algoritmo que cumpla con las especificaciones anteriores tambi n es necesario saber cuantas veces va a ejecutarse dicho algoritmo y con qu cantidad de datos. As, un algoritmo poco eficiente con pocos datos es preferible utilizarlo a otro que necesite gran cantidad de tiempo en disearse. Por el contrario es beneficioso en muchas ocasiones realizar un buen diseo a pesar de utilizar gran cantidad de esfuerzo y emplear estructuras de datos complejas, si se consigue finalmente un mtodo de resolucin que realice buenos tiempos de ejecucin para entradas grandes de datos. Por otra parte, cuando nuestro algoritmo pretende resolver un problema clsico, como puede ser en Geometra Computacional, se da por supuesto que tiene que ser eficiente con grantes cantidades de datos y adems hay que suponer que dicho algoritmo va a ser ampliamente utilizado. Por tanto, nuestro propsito es no slo entender y utilizar algoritmos que funcionen en Geometra Computacional sino que tambin sean eficientes. Para medir dicha eficiencia, hay que tener en cuenta ciertos parmetros: Dependencia de los datos de entrada del programa. Calidad del cdigo que genera el compilador en el programa objeto. Las instrucciones y arquitectura de las computadoras. Tiempo de ejecucin de dicho programa.

Como entrar en detalles de compiladores diferentes y de distintas arquitecturas es muy amplio y adems es absolutamente cambiante, basta decir que cuanto ms rpido mejor. Lo que haremos ser estudiar los algoritmos en funcin de la entrada, bsicamente de su tamao, y adems en la complejidad o tiempo que emplea el algoritmo para su ejecucin. Obviamente un algoritmo, o programa puesto que se est ejecutando, va a ser ms rpido si tiene que procesar diez datos que si tiene que realizar lo mismo con una entrada de tamao cien.

Juan Carlos Gutirrez Barquero____________________________________________

133

Bismarck Salvador Traa Lpez__________________________________________ UNI

Vamos a denominar T(n) al tiempo de ejecucin de un programa con tamao n. Para no especi ficar el tiempo en segundos, puesto que depende excesivamente de la mquina empleada, se usar una funcin expresada en trminos de n. Por ejemplo, T(n) = cn2, siendo c una constante. En muchas ocasiones es necesario referirse al tiempo de ejecucin esperado del algoritmo en el peor de los casos para una entrada de tamao n. De esta forma se puede acotar el problema con una cota superior que nos permita conocer el margen en el que nos podemos mover. El caso medio tambin puede ser interesante en casos donde se conozca que el peor caso se produce con una probabilidad muy pequea. Cuando decimos que el tiempo de ejecucin T(n) de un programa es O(n2) significa que existen constantes enteras positivas c tales que T(n) fi cn2. Por tanto es lo que llamamos cota superior que nos identifica el peor caso. En el caso genrico decimos que T(n) es O( f (n)). Tambin existen cotas inferiores para hablar del tiempo de ejecucin. Es una cota inferior o lo que es lo mismo: el algoritmo se ejecutar al menos en el tiempo que la funcin g(n) indica. Se dice que T(n) es (g(n)) cuando existe una constante c tal que T(n) fi cg(n). Cuanto menor sea la representacin grfica de la funcin f (n), ms rpido se ejecutar el algoritmo para un conjunto de entrada de tamao dado. Pero esto no siempre es verdadero para todo n, es decir, en ocasiones el tiempo de ejecucin se refiere a grandes cantidades de informacin y por tanto, n tiende a infinito. As O(n2) es mejor que O(n3); O(n) es mejor que O(n2) pero peor que O(nlogn). Por ejemplo un programa con tiempo O(100n) es ms lento para n menor que 20 que otro que se ejecute en tiempo O(5n2). En algoritmos tpicos de Geometra Computacional lo que se busca sobre todo son ejecuciones en tiempo lineal O(n), o en O(nlog n). A menos que un algoritmo tenga una velocidad de crecimiento baja, O(n) o O(nlogn), un crecimiento modesto en la rapidez de la computadora no infiuir gran cosa en el tamao del problema. A pesar de todo lo expuesto anteriormente, si un algoritmo va a ser utilizado pocas veces, el costo de escritura de una algoritmo eficiente puede que no merezca la pena. Tampoco es necesario si siempre va a recibir un conjunto de entrada pequeo. En algunas ocasiones un algoritmo puede permitirse el lujo de ser algo ms lento si a cambio es ms didctico. Por otro lado, si la eficiencia a nivel de tiempo en CPU implica un alto coste en cantidad de almacenamiento o porque se encuentre en dispositivos de memoria masiva. Por ltimo, en algoritmos numricos es tan importante la precisin de los clculos como la eficiencia de stos. Para calcular la eficiencia de un algoritmo hay que tener en cuenta ciertos casos:

Juan Carlos Gutirrez Barquero____________________________________________

134

Bismarck Salvador Traa Lpez__________________________________________ UNI Si T1(n) y T2(n) son tiempos de ejecucin de dos fragmentos de
programa, el tiempo totalser de T1(n)+T2(n). Sin embargo, se considera nicamente el ms lento de los dos y eltiempo de ejecucin vendr dado por tanto por O(max( f (n);g(n)) , siendo O( f (n)) eltiempo para T1(n) y O(g(n)) para T2(n). Tambin existen simplificaciones, por ejemplo,O(c f (n)) se considera siempre O( f (n)).

Una asignacin u operacin aritmtica suele considerarse con tiempo


O(1).

En las proposiciones condicionales, la parte de la condicin suele


considerarse tiempoconstante si no necesita realizar llamadas a otras funciones. El tiempo global de esta instruccin se toma de nuevo como el mayor de las dos partes que la forman, parte then o parte else.

multiplicadas por el orden del conjunto de instrucciones del cuerpo del bucle. Si tenemos dos bucles de n ciclos, uno dentro de otro, se considera tiempo cuadrtico (suponiendo que el cuerpo del bucle tuviera un tiempo contante). Cuando se hacen llamadas a procedimientos no recursivos, se suman todos los tiempos de ejecuci n segn las pautas anteriores, pero en procesos recursivos se trabaja de forma distinta. Supongamos la siguiente funcin:

En un ciclo se suele determinar por el nmero de iteraciones

Para n > 2, tenemos que T(n) = c +T(n 1). El trmino T(n 1) se sustituye por n 1: T(n1) = c+T(n2), sustituyendo tenemos que T(n) = c+c+T(n2). Siguiendo este proceso hasta el trmino i entonces T(n) = ic+T(ni). Cuando i = n1, T(n) = nc+T(1) = ncfi= O(n). En el siguiente ejemplo tenemos a un algoritmo recursivo. Para el caso general, n >1, el proceso divide el problema en dos mitades de aproximadamente el mismo tamao. Cuando ste proceso de divisin termina necesita un tiempo lineal para unir los resultados de las dos mitades. Este mtodo es muy habitual en los problemas resueltos con el mtodo Divide y Vencers.

Juan Carlos Gutirrez Barquero____________________________________________

135

Bismarck Salvador Traa Lpez__________________________________________ UNI

1.3.

Operaciones bsicas en Geometra Computacional

En este apartado entraremos en contacto con mtodos para la resolucin de algunos de los problemas ms elementales en Geometra. Nos servir igualmente para recordar conceptos a nivel computacional. Los algoritmos aparecern mayormente escritos en lenguaje Pascal, a no ser que alguno de ellos aparezca, no por razones prcticas sino didcticas. 1.3.1. Introduccin A nivel de tratamiento de la informacin, en Geometra Computacional es clara la preferencia por los tipos de datos enteros, lo que se denomina aritmtica entera. La razn es obvia, el ordenador debe transformar todo dato de la recta real en un tipo de dato de una computadora que tiene un espacio finito de almacenamiento. Los datos enteros s garantizan su transformacin ntegra a un tipo de dato almacenado en memoria, siempre que ste sea menor que una valor dado. Sin embargo, los datos reales o en coma flotante pierden casi siempre cierta precisin al ser guardados. Cuando una variable de tipo real nace en la ejecucin de un programa y a su vez es utilizada como entrada para crear otras nuevas, este proceso repetido puede hacer que el dato se aleje del valor correcto. Por esta razn, y siempre que sea posible, es preferible hacer uso de la aritmtica entera. Por ejemplo, para saber si dos segmentos intersecan basta utilizar aritmtica entera, sin embargo si queremos saber exactamente el lugar de interseccin, s era necesario realizar algn clculo en coma flotante. 1.3.2. Algunos tipos de datos simples Los datos geomtricos, a la hora de ser procesados por un ordenador, son reemplazados por lo que denominamos tipos de datos. Muchos conceptos tpicamente matemticos se denominan de forma anloga cuando se representan internamente, as usamos el concepto de variable o de constante. Los tipos de datos identifican el tipo de cada una de estas posibles variables o constantes. Los tipos de datos que cualquier lenguaje de programacin soporta cubren el espectro ms habitual, sin embargo, los de tipo geomtrico deben ser definidos explcitamente por el programador. En este curso utilizaremos varios de estos tipos de datos. Por ejemplo, el tipo de dato TipoPunto, TipoPoligono, etc. En las clases de prcticas se definirn muchos de ellos, ahora identificaremos los anteriores en Pascal para poder trabajar con ellos a lo largo de este tema:

Juan Carlos Gutirrez Barquero____________________________________________

136

Bismarck Salvador Traa Lpez__________________________________________ UNI


/************REPRESENTACION DE UN PUNTO*********************/ # define x 0; # define y 0; typedef enum{ FALSE, TRUE}bool; # define DIM 2 /*Dimensin del punto*/ typedef int tpointi(DIM); /*Declaracin de un arreglo de puntos*/ /*********REPRESENTACION DE UN PUNTO***********************/ # define PMAX 100 Typedef tpointi tpolygoni[PMAX] Por simplicidad computacional, se emplea un array con dos posiciones para un punto, identifi cando la posicin 0 para guardar el valor de la x y la posicin 1 para el de la y. Cuando se dice que un polgono es un array de puntos, realmente tenemos una matriz bidimensional con un total de dos columnas, igualmente fcil de manejar computacionalmente. Las tcnicas de tricoloreado dos tecnicas utilizadas para la representacin de los guardas y otras entidades diferentes de las triangulaciones y vasadas en las diagonales si desean informacin de estas acudan al libro geometry computacional in C. 1.3.3. Clculo del rea Una de las operaciones ms elementales en Geometra es el clculo del rea de un tringulo, sea del tipo que sea. El mtodo para realizar este clculo no es otro que la resolucin de un determinante 3x3, aunque no es objetivo de esta asignatura el clculo matemtico correspondiente. El algoritmo escrito en pseudocdigo aparece a continuacin. Por razones argumentadas anteriormente, se opta por trabajar siempre con aritmtica entera. La funcin AreaTriangulo2 evitar la divisin por dos y calcular el doble del rea del tringulo, por lo hay que tener en cuenta que para obtener el valor real del rea ser necesario hacer la divisin correspondiente. Ahora vemos el cdigo: Int Area2(tPointi a, tPointi c, tPointi c) { return : = ( ( a [ 0 ] *b[1])(a [ 1 ] * b [ 0 ]) + ( b [ 0 ] * c [1])(b [ 1 ] * c [ 0 ]) + ( c [ 0 ] * a[1])(c [ 1 ] * b [ 0 ]) ) ; } El resultado de este clculo ser positivo siempre que los vrtices abc sean recorridos en orden inverso a las agujas del reloj. En caso contrario el valor ser igualmente vlido y medir el rea, pero tendr el signo negativo.

Juan Carlos Gutirrez Barquero____________________________________________

137

Bismarck Salvador Traa Lpez__________________________________________ UNI

El clculo del rea de un polgono convexo es bien sencillo, basta con calcular el rea de todos los tringulos que se pueden formar lanzando diagonales desde cualquier vrtice, hasta el resto de los vrtices del polgono convexo.

Si el polgono no es convexo, el rea puede calcularse sumando las reas de los tringulos resultantes o incluso restando los de aquellos que no tengan superficie, como en el siguiente ejemplo:

El rea del polgono puede calcularse de dos modos: Area (abd) + area (bcd) Area(abc) area(adc)

Este mismo principio puede extenderse a cualquier polgono, indistintamente del tipo y nmero de vrtices que tuviera. Veamos el siguiente ejemplo: se ha elegido un punto cualquiera p, interior o exterior al polgono y se han trazado diagonales a todos sus vrtices. Los vrtices de ste han sido enumerados del o al n1 en orden inverso a las agujas del reloj. Este dato es muy importante, porque va a ser siempre el mecanismo utilizado para numerar los vrtices cuando trabajemos con polgonos. El nmero de tringulos obtenidos ser de n1, siempre partiendo del punto p y siguiendo con dos vrtices sucesivos del modo siguiente:

Juan Carlos Gutirrez Barquero____________________________________________

138

Bismarck Salvador Traa Lpez__________________________________________ UNI

El tringulo p01 se traza en sentido inverso a las agujas del reloj, lo que implicar siempre que el rea de dicho tringulo es positiva. Se ha sealado utilizando un smbolo + cuando el clculo se realiza en el sentido antihorario y con cuando el rea es negativa. Cuando el recorrido de los vrtices del tringulo siempre en la forma pvivi+1, sea en sentido horario, por ejemplo el tringulo p67, el rea correspondiente se resta. El resultado final, como podemos observar en la figura, es que todas las reas de los tringulos no contenidas en el interior del polgonos son sumadas y restadas una vez con resultado igual a cero, es decir, el resultado finalmente es el deseado. Por tanto, podemos hacer uso de la funcin AreaTriangulo2 tantas veces como tringulos se vayan formando con el proceso anterior, sumando unas veces las reas y otras restndose automticamente segn sea la salida de dicha funcin. Como de cada tringulo se calcula el doble de su rea, finalmente ser necesario dividir por dos el resultado final. Como el punto P puede ser cualquier punto, sea interior o no al polgono, podemos optar por tomar al punto del polgono s[0], o lo que es lo mismo computacionalmente, a s[0]. El resultado lo podemos escribir a continuacin: Veamos el cdigo: int AreaPolygoni(tpointi s, int n) { float suma; int i; suma=0; for(i=1;i<n-1;i++) suma=suma+Area2(s[0],s[i],s[i+1]); return suma; } 1.3.4. Interseccin de segmentos Una de las operaciones elementales en Geometra Computacional es la interseccin de segmentos, clculo vlido para otros muchos problemas. Sin

Juan Carlos Gutirrez Barquero____________________________________________

139

Bismarck Salvador Traa Lpez__________________________________________ UNI


embargo, y siguiendo con la dinmica de trabajar siempre que sea posible con aritmtica de enteros, el algoritmo de interseccin de segmentos va utilizar otra serie de subrutinas necesarias. Si recordamos una de las propiedades de la funcin del clculo del rea del tringulo, el resultado es positivo si la lectura ordenada de los vrtices nos da un recorrido antihorario. Esta propiedad puede ser til para determinar si un punto c est a la izquierda del segmento ab. Observemos la siguiente figura:

El tringulo imaginario abc se dibuja en orden inverso a la agujas del reloj, lo que automticamente nos est indicando que el punto c est a la izquierda de ab. Es necesario observar que no es lo mismo el segmento ab que el segmento ba computacionalmente hablando. El rea del tringulo bac es negativa porque el punto c est a la derecha del segmento ba. El subprograma correspondiente nicamente necesita realizar una llamada a la funcin AreaTriangulo2 anteriormente vista. Aprovechamos un clculo en principio de distinta ndole, para determinar la posicin de un punto con respecto a un segmento. Veamos el codigo: bool Left(tpointi a, tpointi b, tpointi c) { Return Area2(a,b,c)fi0; /*Si areamayor que cero retorna TRUE */ } No es difcil entender que este mismo principio sirve para determinar si el punto c est justamente a la derecha (la funcin anterior nos devuelve un valor f alse). o si el rea del tringulo abc es igual a cero, lo que indica que los tres puntos son colineales:

Juan Carlos Gutirrez Barquero____________________________________________

140

Bismarck Salvador Traa Lpez__________________________________________ UNI

Veamos el codigo en C: bool Collineal(tpointi a, tpoint b, tpoint c) { return Area2(a,b,c)==0; } Debemos insistir en que el cdigo anterior da por supuesto que todos los clculos se realizan nicamente utilizando aritmtica de enteros. No quiere decir sto que no pueda migrarse dicho cdigo a operaciones en coma fiotante, pero en ese caso jams debera realizarse una operacin como esta i f a = 0 ::::, puesto que no siempre el valor que nosotros consideramos como cero (o cualquier otro valor concreto) lo entienda as un tipo de dato en coma fiotante. Para solventar este problema es ms conveniente establecer un margen de error permitido, y operar as: i f abs(a) < 0;001 :::, o lo que es lo mismo, si el valor absoluto de la variable real a es menor que un valor prximo a cero. Para saber si dos segmentos ab y cd intersectan, deberamos saber si: 1. no son colineales 2. si d est a la izquierda de ab y c est a la derecha (o al revs) y adems 3. si a est a la derecha de cd y b lo est a la izquierda (o al revs) Nos podemos dar cuenta en la figura de que si no se cumple algunas de estas premisas no tenemos garanta de que ambos segmentos intersecten.

El cdigo debe tener en cuenta todos los casos citados anteriormente. La operacin vlida para implementar el .al revs., es la operacin XOR(a;b) cuya tabla de verdad da el valor verdadero cuando a y b son distintos.

Juan Carlos Gutirrez Barquero____________________________________________

141

Bismarck Salvador Traa Lpez__________________________________________ UNI

bool Intersect(tpointi a, tpoint b, tpointi c, tpointi d) { If (IntersectProp(a,b,c,d)) Return TRUE; /*Hay interseccin propia*/ else If(Between (a,b,c) || Between (a,b,d) || Between (c,d,a) || Between (c,d,b) Return TRUE; /*Hay interseccion impropia*/ else return FALSE; /*No hay interseccion*/ } El inconveniente del mtodo es la redundancia. Ahora realizaremos una nueva versin del algoritmo utilizando la primitiva Entre, que ser capaz de saber si un punto c est o no en el segmento ab. Para ellos veremos si la coordenada x de c cae en el intervalo determinado por la coordenada x de a y b. Lo mismo debe hacerse para la ordenada. Veamos el codigo en C: boll Between (tpoint a, tpointi b, tpoint c) { If(!Collineal(a,b,c)) Return FALSE; If(a[x]!=b[x]) return ( (a[x]<=c[x]) && (c[x]<=b[x]) || (a[x]>=c[x] ) && (c[x]>=b[x]) ); else return ( (a[y]<=c[y]) && (c[y]<=b[y]) || (a[y]>=c[y] ) && (c[y]>=b[y]) ); } Esta versin del algoritmo adems cuenta con al ventaja de poder trabajar con las intersecciones de forma propia o impropia. Una interseccin impropia ocurre cuando un extremo de uno de los segmentos est justo en en alguna posicin del otro. La siguiente funcin en Pascal detecta primero si existe la posibilidad de colinealidad con la funcin Entre. Posteriormente hace el mismo proceso que IntersectaSegmento. Veamos el cdigo: bool IntersecImprop(tpoint a, tpoint b, tpointi c, tpointi d) { If( Between (a,b,c) || Between (a,b,d) || Between (c,d,a) || Between (c,d,b) ) return TRUE; else return(Left(a,b,c) || Left(a,b,d) && Left(c,d,a) || Left(c,d,b) ) }

Juan Carlos Gutirrez Barquero____________________________________________

142

Bismarck Salvador Traa Lpez__________________________________________ UNI

Ahora veremos la function propia en C: bool IntersecProp (tpoint a tpoint b, tpointi c, tpointi d) { If( Collineal(a,b,c) || Collineal (a,b,d) || Collineal (c,d,a) || Collineal (c,d,b) ) return FALSE; return (Xor(Left (a,b,c), Left (a,b,d)) && Xor (Left(c,d,a),Left (c,d,b))); } bool Xor (bool x, bool y) { return !x^!y; } 1.3.5. Clculo de diagonales El clculo de una diagonal tiene como objetivo la triangulacin de polgonos. Una diagonal es aquel segmento que une dos vrtices del polgono de forma que no intersecte con ningn otro eje de dicho polgono y adems sea interno al polgono. Para saber si existe o no interseccin puede utilizarse el proceso anterior, pero para saber si es o no interno necesitamos realizar un procesamiento adicional. Este clculo puede realizarse en tiempo constante porque si una diagonal es interior a un polgono P en su vecindario (vrtices prximos), tambin lo es para todo el polgono, no siendo necesario un procesamiento completo del polgono P. Diremos que un segmento s es interno a P si y slo si es interno al cono cuyo vrtice es vi y cuyos lados pasan a travs de vi1 y vi+1. Existen dos casos, el caso convexo en el que el resto del polgono est en la parte de menor ngulo y el caso cncavo en cuyo caso el ngulo es mayor que La siguiente funcin . determina si el vector que une los vrtices i y j del polgono P es interior o no al polgono. Veamos el codigo: Esta funcin verifica si un vertice es convexo boll InCone(int i, int n, tpoligoni P) { int i1,inl; i1=(i+1)%n; inl=(i+n-1)%n; if(LeftOn(P[inl],P[i],P[i1])) /**/ return (Left(P[i],P[j],P[inl]) && Left (P[j],P[i],P[i1])); else return (!(LeftOn[P[i],P[i1]P[i1]) && LeftOn(P[j],P[i+,P[inl])); }

Juan Carlos Gutirrez Barquero____________________________________________

143

Bismarck Salvador Traa Lpez__________________________________________ UNI

bool LeftOn (tpointi a, tpoint b,tpoint c) { return Area2(a,b,c)fi0; } Vemos en la figura siguiente los dos casos comentados anteriormente. El caso convexo ocurre cuando el vrtice vi+1 est a la izquierda del eje trazado por vi1vi. En este caso, lo vemos en la figura de la izquierda, para que se trate de un eje interno debe ocurrir que vi1 est a la izquierda de viv j y que vi+1 lo est a la izquierda. El caso cncavo aparece a la derecha.

Por tanto, una diagonal es aquel segmento interior que est dentro del polgono. Pero el segmento i j es una diagonal si no intersecta con ninguna otro de las aristas del polgono. Este clculo necesita forzosamente un tiempo de ejecucin lineal. La funcin DiagonalfiIE se encargar de realizar este chequeo, y que ser invocado por la funcin Diagonal cuyo cdigo resulta bastante evidente: el segmento i j es una diagonal del polgono P de tamao n si es interior y adems no intersecta con ninguna arista. Veamos el cdigo: Es/*ta function verifica la possible diagonal entre dos vertices.*/ bool Diagonal (int i, int j,int n,tpolygoni P) { return(InCode(i,j,n,P) && Diagonaie(i,j,n,P)()); } /*Esta function verifica si una diagonal se intersecta con una arista del poligono */ bool Diagonalie (int i, int j, int n, tpoligono p) { Int k,k1; for(k=0; k<n; k++) { K1=(k+1)%n; if( !( ( k==i) || ( K1==i ) || ( k==j) || ( k1==j ) ) )

Juan Carlos Gutirrez Barquero____________________________________________

144

Bismarck Salvador Traa Lpez__________________________________________ UNI


if ( Intersect (p[i], p[j], p[k], p[k1])) return FALSE;

} return TRUE;

/*Esta function remueve el triangulo formado por la diagonal y la arista asociada ala diagonal, para lo cual reasigna las etiquetas del polgono.*/ void ClipEar1 (int i, int n, tpoligoni p, int labels [ ]) { Int k; for(k=I; k<n-1 ; k++) { point assign (p[k+1]); labels[k] = labels [k+1]; } } /*Esta funccion obtiene los vrtices de la possible diagonal */ void TriRecurse(int n, tpoligoni P, int labels []) { int i,i1,i2; if(n>3) for(i=0; i<n;i++) { i1=(i+1)%n; i2=(i+2)%n; if (Diagonal(i,i2,n,p)) { printf("%d %d ln",labels[i2]); ClipEar1(i1,n,p,labels); TriRecurse(n-1,P,labels); break; } /*Cierre del if*/ } /*Cierre del for*/ } /**Cierre de la funcion/ 1.3.6. Un ejemplo completo: triangulacin de un polgono La triangulacin de polgonos es un clculo muy importante en muchas aplicaciones de Geometr a Computacional. Permite, aparte de otras muchas aplicaciones, dividir un polgono con posible cierta complejidad, en un conjunto de tringulos fciles de procesar. Veremos que el siguiente mtodo puede ser perfectamente vlido para lograr la triangulacin de cualquier polgono P de tamao n. Sin embargo, y a pesar

Juan Carlos Gutirrez Barquero____________________________________________

145

Bismarck Salvador Traa Lpez__________________________________________ UNI


de su simpleza, su utilizacin no es aconsejable y por ello no se ha implementado en un leguaje de programacin. Vemos que es un mtodo recursivo porque se llama a s mismo. La llamada recursiva se realiza cuando se localiza una diagonal, y como en ese momento el nmero de vrtices a procesar es uno menos, puesto que el vrtice i1 queda aislado al encontrarse la diagonal ii2. La funcin EliminaVertice se encargara de este operacin, dejando cada vez que se llama un polgono ms pequeo. Esta funcin triangula el poligono P de n vertices. void Trinagulate1 (int n, tpoligoni) { tpoligoni.pt; int labels[PMax]; clrscr(); for(i=0;i<n;i++) { PointAssign(pt[i]<P[i]); labels[i]; } printf("Diagonales de la triangulacion;\n"); TriRecurse(n,pt,Labels); } /*Esta funcin asigna al punto "a" el valor del punto "b".*/ void PointAssign(tpoint a, tpoint b) { int i; for(i=0;i<DIM;i++) a[i]=b[i]; } La razn por la que este algoritmo no es desde luego nada interesente es por su tiempo de ejecucin. El algoritmo trabaja en O(n3) porque realiza un total n3 llamadas recursivas y cada una de ellas, en el peor de los casos, necesita un tiempo cuadrtico (la funcin diagonal es lineal, as como la ejecucin completa del bucle). Como veremos a lo largo de este curso, para valores de n elevados, este algoritmo resulta Evidentemente lento, y en Geometra Computacional todos los problemas cuyas soluciones inmediatas sean susceptibles de mejora, son estudiados. Como veremos en sucesivos captulos, cualquier polgono puede ser triangulado en tiempo O(nlog n). Los algoritmos geomtricos, al igual que los desarrollados para otras disciplinas, debern combinar adecuadamente junto con su conjunto de

Juan Carlos Gutirrez Barquero____________________________________________

146

Bismarck Salvador Traa Lpez__________________________________________ UNI


sentencias, a las estructuras de datos correctas para conseguir el objetivo final, obtener programas eficientes. 1.4.1. Introduccin a las estructuras de datos El estudio de las estructuras de datos y los mtodos para la organizacin de dichos datos es uno de los aspectos clsicos ms importantes para construir algoritmos eficientes. Los programas trabajan con informacin que permanece en memoria principal o en algn dispositivo de memoria secundaria. La organizacin que se le da a dichos datos es lo que denominamos estructuras de datos. La mayora de las estructuras de datos pueden verse como contenedores que mantienen informacin de un determinado tipo con un cierto orden. El acceso y manejo de los datos en un contenedor se realiza a travs de un localizador. Dependiendo de la estructura del contenedor, el localizador proporcionar un modo de acceso a los datos, por ejemplo, un ndice de un array o un puntero. Una estructura de datos adems de proporcionar un modo de acceso, tambin deber llevar asociado un conjunto de operadores, como insertar un nuevo dato, actualizar uno ya existente o eliminar algn otro. Las caractersticas de una estructura de datos va en relacin al orden de ejecucin de sus operaciones y a los requerimientos de espacio. En cualquier caso, la estructura de datos ms idnea depender siempre del problema que se pretenda resolver. Un tipo de dato es una coleccin de objetos a la que se le da una representacin matemtica. Un tipo de dato abstracto o TDA es un tipo de dato, ms un conjunto de operaciones que lo manejan. Las estructuras de datos pueden considerarse como implementaciones concretas de tipos de datos abstractos. Los TDAs (notacin anglosajona) han evolucionado hasta convertirse en clases de objetos. Lo que inicialmente se concibi como un concepto matemtico que se adapt a la sintaxis de los lenguajes de programacin tradicionales, se ha ido convirtiendo en una nueva filosofa de programacin con los nuevos lenguajes orientados a objetos. Existen multitudes de estructuras de datos ampliamente documentadas en la bibliografa. En este apartado repasaremos algunas de las estructuras de datos usadas en el curso. Dependiendo de la organizacin interna y del modo de acceso a los datos, existen dos tipos fundamentales de contenedores, los contenedores secuenciales o secuencias y los asociativos. Una secuencia es un contenedor que almacena los elementos con un orden lineal determinado, realizando el acceso a la informacin indicando la posicin donde se localiza el dato. Por el contrario un contenedor asociativo, independientemente de su organizacin interna, permite el acceso por clave. Contenedores secuenciales

Juan Carlos Gutirrez Barquero____________________________________________

147

Bismarck Salvador Traa Lpez__________________________________________ UNI

Las secuencias ms usuales son las listas enlazadas y los arrays. Las primeras forman una sucesin de nodos o elementos informativos unidos unos a otros mediante punteros. El tiempo de acceso es lineal, aunque normalmente el acceso a los puntos extremos es constante. Los arrays son contenedores implcitos con acceso directo. Esta ventaja de acceso en tiempo constante se ve mermada por poseer menor fiexibilidad. Por ejemplo, la operacin de insercin de un elemento en posiciones intermedias es de orden lineal. Sobre cualquiera de los contenedores secuenciales anteriormente citados puede construirse estructuras de datos muy conocidas y empleadas, las pilas (LIFO) o las colas (fiFO). Cualquiera de ellas implementada sobre una lista puede considerarse como una estructura de datos dinmica. Esta consideracin tambin puede realizarse sobre arrays dinmicos. Contenedores asociativos Los contenedores asociativos poseen una filosofa de manejo y una estructura interna totalmente diferente a las secuencias. La diferencia fundamental es que el acceso a la informacin se realiza siempre utilizando una clave y no una posicin, que puede identificar o no de forma unvoca al dato. Las operaciones fundamentales son de insercin, actualizacin, borrado y bsqueda por dicha clave. La organizacin interna de los datos depende del tipo de contenedor asocitivo, por rbol o por tabla hash. Los primeros mantienen un rbol binario de bsqueda o Inorden, manteniendo una relacin de orden entre nodos padre e hijos. Normalmente, todo nodo padre es mayor que su hijo izquierdo pero menor o igual que su hijo derecho. El tiempo de acceso en este tipo de estructuras permite eliminar en cada consulta la mitad del grueso de la informacin, siempre que todas las ramas del rbol permanezcan a la misma altura. Estas estructuras de datos garantizan bsquedas en O(logn). Las estructuras de datos consideradas de carcter general son ampliamente utilizadas en Geometra Computacional, pero existen otros aspectos como son la naturaleza espacial de los objetos geomtricos o sus propiedades estructurales que requieren del manejo de estructuras de datos ms especficas para construir algoritmos eficientes. La eleccin de un tipo de estructura de datos o de otro va a depender del tipo de objetivo que se persiga: captura de informacin estructural, acceso a los datos o actualizacin eficiente de stos, optimizacin del espacio requerido o del nmero de operaciones de E/S. En otras ocasiones, las estructuras de datos se eligen segn la asociacin de objetos geomtricos que representen. 1.4. Algunos mtodos de programacin utilizados en C.

La Geometra Computacional, en contraste con la disciplina clsica basada en proporcionar teoremas matemticos, enfatiza los aspectos computacionales de

Juan Carlos Gutirrez Barquero____________________________________________

148

Bismarck Salvador Traa Lpez__________________________________________ UNI


los problemas y atiende a las propiedades geomtricas para encontrar algoritmos eficientes. Que un problema geomtrico tenga solucin dentro de la Geometra Computacional no basta en muchas ocasiones, se desea adems que la solucin se encuentre en un tiempo ptimo. Existen una serie de tcnicas y paradigmas de programacin que vienen siendo muy habituales no slo en el campo de la Geometra Computacional. Algunos de estos mtodos como el divide y vencers ya haban proporcionado la solucin ptima a problemas como la ordenacin, en otras ocasiones los mtodos de resolucin estn ntimamente relacionados con las capacidades de la propia Geometra. A continuacin daremos un repaso a los paradigmas de programacin ms empleados dentro de la Geometra Computacional. 1.5.1. Mtodo incremental ste puede ser considerado como uno de los mtodos ms simples e intuitivos, tambin conocido como el mtodo iterativo. La idea sobre la que trabaja este mtodo consiste en construir la solucin de modo iterativo, considerando que la entrada se produce de modo incremental. Para cada una de las nuevas entradas, el problema se resuelve convenientemente. Supongamos que se pretende procesar una nube de n puntos en el plano S, para resolver cualquier problema Prob(S) bajo esta tcnica. En muchas ocasiones S deber estar ordenada bajo algn criterio con coste O(nlogn). El algoritmo trabaja siempre de forma similar. Inicialmente Prob se resuelve de forma trivial para fs0; s1; :::; sk1g, los primeros k puntos de S. Posteriormente y uno a uno, se resolver Prob(Si) para el resto de si 2 S; i = fk; :::;n1g tal y como indica el Algoritmo 1, obtiendo finalmente Prob(S). Si en un problema de tamao n, el coste de insertar un nuevo dato es O(n), entonces el tiempo global del algoritmo ser de O(n2). Pero si aadir un nuevo elemento a la solucin parcial del problema tiene coste constante o logartmico, el algoritmo final se procesar en O(nlogn), la misma cota impuesta por el algoritmo de ordenacin. Algoritmo 1 Incremental-generalizado. Incremental(RC,p) 1. Si p est dentro de RC 2. entonces devolver RC 3. sino 4. (Pt1,Pt2) := puntosTangentes(RC,p) 5. Eliminar aristas en RC de Pt1 a Pt2 6. Conectar Pt1 con p y p con Pt2

Juan Carlos Gutirrez Barquero____________________________________________

149

Bismarck Salvador Traa Lpez__________________________________________ UNI

Ahora veremos los puntos tangentes:

1.5.1.1. Lnea de barrido Esta estrategia es una particularizacin del mtodo incremental, considerndose vlida para problemas en dos dimensiones cuando el conjunto de entrada se produce en un cierto orden. La solucin de la mayora de estos problemas puede ser incremental, de hecho, la implementacin de este paradigma sigue las mismas premisas que las dadas para el mtodo incremental citado anteriormente. El mtodo supone que una lnea horizontal (o vertical) recorre el plano de arriba hacia abajo (o en sentido contrario). Cada vez que dicha lnea encuentra un tem (un punto, una lnea, etc) lo procesa modificando el conjunto de estructuras que datos que participen en la construccin de dicho algoritmo. La validez de esta tcnica est basada en la observacin de que la parte que queda por encima o por debajo de la lnea de barrido se ha construido correctamente. Por ejemplo en el problema de interseccin de segmentos, cuando la lnea encuentra un nuevo segmento, se realizar una insercin en alguna estructura de datos capaz de mantenerlos ordenados de izquierda a derecha (en el caso de que la lnea de barrido sea horizontal). Normalmente se escogen estructuras de datos con tiempos de actualizacin y de acceso logartmico. Si el procesamiento de dichos objetos geomtricos es constante, como es el caso de la interseccin de dos segmentos, pueden trabarse con tiempos del orden de O(nlog n).

Juan Carlos Gutirrez Barquero____________________________________________

150

Bismarck Salvador Traa Lpez__________________________________________ UNI


Esta tcnica es empleada para diferentes problemas como la interseccin de segmentos, particin de polgonos en subdivisiones montonas, interseccin de semiplanos, el diagrama de Voronoi y triangulacin de Delaunay, los mtodos de Jarvis y Graham para el clculo de la envolvente convexa, la tcnica de localizacin de los puntos ms lejanos, y otros ms. Existen tcnicas anlogas para dimensiones mayores. Algoritmo 1 El algoritmo de la lnea de barrido rotatoria (Rotational Sweep Line): Entrada: Un conjunto de obstculos poligonales S y un conjunto de puntos Q. Salida: Un grafo de visibilidad G = (V, E). Sea W la unin de los vrtices de S y los puntos de Q, sea E el conjunto de aristas, y sea T un rbol de bsqueda equilibrado. 1.- Para cada vrtice w de V: 2.- Ordenar todos los vrtices de W en sentido horario segn la semi-lnea P, y, en caso de empate, ordenar segn distancia al punto p. 3.- Ordenar las aristas que intersectan con P e insertarlas en el rbol equilibrado T. 4.- Para cada vrtice w de la lista ordenada W: 5.Si w es visible desde p, entonces aadir la arista e=(p, w) al grafo G. 6.Insertar en el rbol los obstculos que incidan en w y que estn en el lado horario de P. 7.Eliminar del rbol los obstculos que incidan en w y que estn en el lado antihorario de P.

1.5.2. Divide y Vencers

Juan Carlos Gutirrez Barquero____________________________________________

151

Bismarck Salvador Traa Lpez__________________________________________ UNI

Esta tcnica clsica de programacin es vlida para resolver de forma eficiente problemas Geom. tricos. Normalmente se basa en la sucesiva divisin en partes iguales del problema original, hasta conseguir que ste posea un tamao lo suficientemente pequeo como para poder resolverse fcilmente. Llegado a un punto en que la divisin deja de tener sentido, los problemas se van resolviendo recursivamente y combinando sus soluciones para obtener la solucin final. El mtodo ms eficiente de ordenacin, el quicksort, est basado en este paradigma. El Algoritmo 2 resume los pasos empleados para resolver el problema Prob(S) partiendo del conjunto de datos S y realizando sucesivas divisiones por dos. Para que el algoritmo se considere eficiente se espera que el Paso 3.a) que divide el problema en subproblemas y el Paso 3.c) que combina las soluciones parciales, se realice en tiempo lineal. El segundo ejemplo de ecuacin de recurrencia de la Seccin 1.2 corresponde al mtodo Divide y Vencers. Algoritmo 2 Paradigma de divide y vencers

Juan Carlos Gutirrez Barquero____________________________________________

152

Bismarck Salvador Traa Lpez__________________________________________ UNI

Juan Carlos Gutirrez Barquero____________________________________________

153

Bismarck Salvador Traa Lpez__________________________________________ UNI

Es un ejemplote Voronoi. Esta tcnica es ampliamente utilizada y sirve de base para construir

Juan Carlos Gutirrez Barquero____________________________________________

154

Bismarck Salvador Traa Lpez__________________________________________ UNI


algoritmos aleatorios. Puede emplearse para construir la envolvente convexa, el diagrama de Voronoi, etc.

2 La envolvente convexa y triangulacin de polgonos 2.1. La envolvente convexa 2.1.1. Introduccin El clculo de la envolvente convexa de un conjunto de puntos en espacios eucldeos ha sido sin duda uno de los problemas a la vez ms bsicos y ms ampliamente estudiados a lo largo de la historia de la Geometra Computacional. Adems, los campos en los que ha resultado un clculo til sorprenden por lo aparentemente poco relacionados con las matemticas en general y la geometra en particular.

Un conjunto convexo del plano se define como el conjunto que verifica que el segmento que une a dos cualesquiera de sus puntos est totalmente contenido en l. Evidentemente, esta definicin puede ser aplicada en cualquier espacio eucldeo n-dimensional. La idea de conjunto convexo nos lleva inmediatamente a la de envolvente convexa, considerando a sta como el menor conjunto convexo que contiene a dicho conjunto. Este concepto es fcil de entender en cierto modo si consideramos a la envolvente convexa de un conjunto de puntos en el plano, como la forma que adquirira una goma elstica envolviendo a todos los puntos del conjunto que estn fijos sobre el plano. De nuevo esta idea es extensible intuitivamente a otras dimensiones, y puede servir de partida para construir algoritmos simples para el clculo de la envolvente convexa. Pero exiten otras definiciones vlidas: la envolvente convexa de un conjunto de puntos en el plano es la unin de todos los tringulos determinados por dicho conjunto de puntos. El estudio de la envolvente convexa en dos dimensiones ha sido objeto de especial inters. Existen una serie de caractersticas asociadas a los puntos que

Juan Carlos Gutirrez Barquero____________________________________________

155

Bismarck Salvador Traa Lpez__________________________________________ UNI


forman parte de la envolvente convexa en el plano y que han servido igualmente para definirla y construirla. Un punto q 2 S pertenece a la envolvente convexa de S, q 2CH(S), si es posible trazar una recta pasando por dicho punto de forma que todo el conjunto S0, S0 = Sfqg quede a un lado de dicha recta. Como se ha indicado con anterioridad, el clculo de la envolvente convexa ha sido aplicado ampliamente a disciplinas en ocasiones ajenas a la Geometra Computacional y en espacios distintos de dos dimensiones. Tal es el caso del reconocimiento de patrones, procesamiento de imgenes, etc. Los algoritmos propuestos para este problema son realmente numerosos. Sin duda es uno de los planteamientos de la Geometra Computacional que ms soluciones ha conseguido. Desde incluso antes del nacimiento oficial de esta disciplina se conoce el trabajo de Graham en el ao 1972. Se han propuesto estrategias siguiendo los paradigmas ms empleados como el mtodo incremental y el divide y vencers. Todos estos algoritmos construyen la envolvente convexa en tiempo (nlog n). El mtodo propuesto por Preparata y Shamos en 1985 fue denominado Quickhull por su similitud con el mtodo de ordenacin Quicksort. Otra propuesta diferente se di a conocer en 1973 como .La marcha de Jarvis.. Este mtodo, que estudiaremos en este curso, posee un tiempo de ejecucin cuadrtico, sin embargo supone un interesante ejemplo basado en manejo de ngulos del cual partiremos para el tratamiento del diagrama polar. Todos estos trabajos constituyen el conjunto clsico de algoritmos para la resolucin de la envolvente convexa, al que habra que aadir otras tcnicas posteriores. La envolvente convexa posee una cota de (nlog n), es decir, no se puede encontrar una algoritmo que trabaje en menor tiempo para todos los casos. 2.1.2. Un ejemplo de resolucin El problema de encontrar la envolvente convexa de un conjunto de puntos puede ser interesante porque es equivalente a encontrar todo el conjunto de puntos extremos de dicha nube. Por tanto, puede definirse como punto extremo a cualquier punto de la envolvente convexa, y todo punto extremo tiene la propiedad de que es posible trazar una lnea recta a travs de l de modo que el resto de puntos queden a un lado. Tambin podemos decir que un punto es extremo si y slo si est dentro de algn posible tringulo cuyos vrtices son cualesquiera de los puntos de la nube original. Pero bajo esta definicin, necesitaramos procesar O(n3) tringulos para cada uno de los n puntos, lo que nos proporciona un mtodo en triempo O(n4), lo cual no es eficiente teniendo en cuenta que se trata de un problema (nlog n). Pero la envolvente convexa posee aplicaciones fuera del mbito de la Geometra. Supongamos que una explotacin petrolfera extrae diferentes tipos

Juan Carlos Gutirrez Barquero____________________________________________

156

Bismarck Salvador Traa Lpez__________________________________________ UNI


de componentes mezclados en distinta propocin. Si el objetivo es conseguir los componentes A y B pero en una nueva proporcin, podemos hacer uso de la envolvente convexa del modo siguiente. Supongamos que partimos de las mezclas: e1 = A10%B35%, e2 = A16%B20% y e3 = A7%B15% y queremos obtener e f = A13%B22%. Para saber si es posible obtener este producto final e f basta con considerar las anteriores mezclas como puntos del plano, obteniendo el siguiente esquema:

Todo punto que caiga dentro de la envolvente convexa de todas las muestras representadas por puntos en el plano, indica que puede ser producida. Si por contra, cayera fuera de dicha envolvente, la combinacin final no podra producirse. Este problema sera un problema 3D si cada mezcla tuviera tres componentes, la solucin sera la contruccin de la envolvente convexa tridimensional. 2.1.3 Algoritmo trivial 1. Determinacin de puntos extremos 1. Para cada i hacer 2. Para cada j i hacer 3. Para cada k i j hacer 4. Para cada h i k j hacer 5. Si Ph est a la izqda de (Pi,Pj) y 6. Ph est a la izqda de (Pj,Pk) y 7. Ph est a la izqda de (Pk,Pi) 8. entonces Ph no es extremo

Complejidad: O(n4 )

2.1.4 Algoritmo trivial 2. Determinacin de aristas extremas 1. Para cada i hacer 2. Para cada j i hacer 3. Para cada k i j hacer

Juan Carlos Gutirrez Barquero____________________________________________

157

Bismarck Salvador Traa Lpez__________________________________________ UNI


4. 5. Si Pk no est a la izqda de (Pi,Pj) entonces (Pi,Pj) no es extremo

Complejidad: O(n3 )

2.1.5 Gift Wrapping 1. Encontrar punto p ms pequeo en coord. y, sea i[0] su ndice 2. i := i[0] 3. Repetir 4. Para cada j i hacer 5. Calcular el ngulo en sentido antihorario entre Pj y la arista anterior de la EC 6. Sea k el ndice del punto con ngulo menor 7. Marcar (Pi,Pk) como una arista de la EC 8. i := k 9. Hasta que i = i0

2.1.6 Quick Hull QuickHull(a,b,S) 1. Si S={a,b} entonces devolver (a,b) 2. sino 3. c := ndice del punto con mxima distancia a (a,b) 4. A := puntos a la izquierda de (a,c) 5. B := puntos a la izquierda de (c,b) 6. devolver concatenar(QuickHull(a,c,A),QuickHull(c,b,B) ConvexHull(S) 1. a := punto ms a la derecha de S; 2. b := punto ms a la izquierda de S

Juan Carlos Gutirrez Barquero____________________________________________

158

Bismarck Salvador Traa Lpez__________________________________________ UNI


3. devolver concatenar(QuickHull(a,b,izquierda(a,b,S)), QuickHull(b,a,izquierda(b,a,S)))

La idea bsica del quickhull (envolvente rpida) es que para la mayora de las configuraciones de puntos se puede en cada paso descartar muchos puntos a la hora de construir la envolvente convexa. El primer paso del quickhull es encontrar los cuatro puntos extremos en las direcciones norte, sur, este y oeste y formar el cuadriltero que ellos definen (este cuadriltero puede ser degenerado), ahora todos los puntos en el interior de dicho cuadriltero no son extremos, con lo cual pueden ser descartados.

As nos quedan puntos repartidos en cuatro regiones no conectadas entre si, trataremos cada una de estas regiones independientemente. En cada una de ellas encontramos el punto ms alejado a la recta que define dicha regin obteniendo as cuatro nuevos puntos y un polgono de a lo ms ocho lados que divididir a los puntos que no hemos eliminado en ocho regiones que tratamos individualmente siguiendo la misma regla anterior.

Juan Carlos Gutirrez Barquero____________________________________________

159

Bismarck Salvador Traa Lpez__________________________________________ UNI

En nuestro ejemplo en el paso siguiente se obtine ya la envolvente convexa. El QuickHull suele calcular la envolvente convexa en un tiempo mucho ms corto que si lo hacemos a travs del diagrma de Voronoi. Sin embargo, un anlisis del algoritmo nos lleva a que su complejidad en tiempo es cuadrtica. Por lo tanto, centrmosno ahora en encontrar un algoritmo ptimo. Ejemplo:

Juan Carlos Gutirrez Barquero____________________________________________

160

Bismarck Salvador Traa Lpez__________________________________________ UNI


2.1.4. Graham's scan Este es sin duda uno de los algoritmos ms importantes para el clculo de la envolvente convexa, no nicamente por su simpleza sino tambin por su rapidez. El proceso realiza primero una ordenacin angular de los puntos. El punto tomado de referencia para tal fin debe ser un punto de la envolvente convexa, por ejemplo el de menor ordenada y al que llamaremos p0. El resto de puntos quedan ordenados de izquierda a derecha obteniendo la secuencia p1, p2,, pn1. El proceso seguido por Graham toma sucesivamente tringulos elegidos segn el orden conseguido tras la ordenacin. Siempre que el tringulo formado abc, posea una superficie positiva, el vrtice central, es decir, el vrtice b ser tenido en cuenta como probable punto de la envolvente. Pero cuando dicho rea es negativa, b es descartado definitivamente. Para comprender dicho algoritmo, ser necesario repasar el concepto de pila. Una pila es un tipo de dato abstacto (tipo de dato ms operaciones para su manejo) muy restrictivo a la hora de manejar los datos que almacena. Se construye utilizando una estructura de datos lineal, array o lista enlazada, sobre la que slo se pueden introducir (push) o sacar elementos (pop) por uno de sus extremos, lo que se denomina cima o tope de la pila. Algoritmo Scan de Graham 1. Encontrar el punto inferior ms a la derecha (P0) 2. Ordenar todos los puntos angularmente alrededor de P0; aquellos puntos que estn en el mismo ngulo colocar primero el ms cercano a P0: etiquetarlos P1,...,Pn-1 3. Pila S := (Pn-1,P0) 4. t := tope de S (P0) 5. i := 1 6. Mientras que i<n hacer 7. Si Pi est estrictamente a la izqda de (Pt-1,Pt) 8. entonces Push(S,i); i := i+1 9. sino Pop(S) Ejemplo: El orden de ejecucin de este algoritmo viene dado por la necesidad de ordenar los puntos angularmente. Cualquier ordenacin necesita al menos un tiemo O(nlogn). A este tiempo se le debe aadir el del proceso ideado por Graham. Para averiguar este tiempo basta con percatarse que en cada paso un punto es tenido en cuenta o es descartado. En el peor de los casos, cuando la envolvente convexa es un tringulo, necesitamos del orden de 2n3 operaciones.

Juan Carlos Gutirrez Barquero____________________________________________

161

Bismarck Salvador Traa Lpez__________________________________________ UNI

El Scan de Graham construye una lista que al final ser la de los puntos extremos ordenados. Supondremos que no existen tres puntos alineados (aunque esta condicin puede ser eliminada). Comenzamos encontrando el primer punto con el orden lexicogrfico, llamemosle p0. A continuacin ordenamos los puntos por el ngulo que forman con p0.

Suponemos que partimos de la lista ordenada as obtenida. En cada momento, tendremos tres puntos, llammosles Inicial, Medio y Final. Nos preguntamos si el ngulo IMF es positivo (en el sentido contraro de las agujas del reloj o negativo. Si es positivo, la lista la dejamos como estaba y el anterior Medio pas a ser Inicial y el final pas a ser Medio y escogemos el siguiente en la lista para ser el nuevo Final. Si es negativo, eliminamos Medio de la lista, el anterior Inicial pasa a ser Medio, el Final sigue como Final y escogemos el anterior de la lista para ser el nuevo Incial. La lista resultante despus de recorrer todos los puntos ser la de los extremos de la envolvente convexa. Teorema 5.1: El Scan de Graham calcula la envolvente convexa de n puntos en el plano en tiempo ptimo O(n log n).

Juan Carlos Gutirrez Barquero____________________________________________

162

Bismarck Salvador Traa Lpez__________________________________________ UNI

2.1.4. La marcha de Jarvis La marcha de Jarvis est basada en el siguiente resultado, que sirve de definicin para la envolvente convexa: El segmento l, definido por dos puntos de la nube de puntos, es un eje de la envolvente convexa si todos los puntos de la envolvente convexa estn a un lado de sta. Siguiendo este criterio podramos descubrir para cada punto los n2 combinaciones posibles, lo que nos da un fcil pero costoso O(n3) algoritmo. Sin embargo, Jarvis pudo bajar la cota al comprobar que si pi pj es una arista perteneciente a la envolvente convexa, la siguiente arista la encontramos partiendo de p j en tiempo lineal. Veamos el siguiente ejemplo: Partiendo de s6, el punto de menor ordenada, alcanzamos a s5 tras realizar un barrido angular en sentido antihorario desde la horizontal. El siguiente punto de la envolvente se puede localizar partiendo de s5 y haciendo un nuevo barrido angular, localizando as a s1. Es fcil de intuir que este proceso tardar en ejecutarse un tiempo proporcional al nmero de puntos en la envolvente y al tamao de la nube. Cada barrido angular necesita un tiempo de proceso del orden de O(n) pasos. Si la envolvente final posee k puntos, el tiempo final de ejecucin es del orden de O(nk). En el mejor de los casos el comportamiento puede ser lineal, por ejemplo si la envolvente es un tringulo. El peor de los casos, sin embargo, se da cuando todos los puntos estn en la envolvente convexa, convirtindose en un mtodo cuadrtico.

Juan Carlos Gutirrez Barquero____________________________________________

163

Bismarck Salvador Traa Lpez__________________________________________ UNI

2.1.5. Algoritmo Incremental La ventaja de unos mtodos con respecto a otros a veces viene dada por su velocidad computacional y otras veces por su fcil extensin a tres dimensiones, lo que habitualmente llamamos problemas 3D. El mtodo incremental para el clculo de la envolvente convexa es uno de estos casos. En todo mtodo incremental se supone que se ha resuelto el problema para un tamao n y que en cada paso se aade un nuevo punto dando solucin a un problema de tamao n+1. Para el clculo de la envolvente convexa ordenamos inicialmente los puntos del conjunto P de izquierda a derecha, por ejemplo, obteniendo el conjunto p0; p1; :::; pn1. Tomamos los tres primeros puntos tras esta ordenacin sabiendo que el polgono que forman p0; p1; p2, un tringulo, es convexo. El siguiente paso intenta aadir el siguiente punto, p3, de modo que se tras finalizar este paso tengamos la envolvente convexa de los primerso cuatro puntos p0; p1; p2; p3. Para aadir cada nuevo punto pi+1 basta con lanzar tangentes desde este punto hasta el polgono convexo obtenido en el paso anterior. Localizaremos dos tangentes, una superior y otra inferior, como vemos en la siguiente figura:

Siempre ocurre que el punto ms bajo de tangencia es tal que pi, es tal
que q est a laizquierda de pi1 pi pero a la derecha de pi pi+1.

El punto pj ser el punto de mayor tangencia si q est a la derecha de p


j1 pj pero a laizquierda de pj pj+1. El procedimiento PuntosTangentes calcula los puntos resultantes de lanzar tangentes desde el punto q al polgono P de tamao n obteniendo como

Juan Carlos Gutirrez Barquero____________________________________________

164

Bismarck Salvador Traa Lpez__________________________________________ UNI


resultado los vrtices pt1 y pt2. El algoritmo determina que el vrtice p[i] es un punto tangente si recorriendo cada arista del polgono P dicho vrtice implica un cambio de resultado tras ejecutar la funcin IzquierdaOSobre. Pero obtener los dos puntos tangentes no implica de ningn modo que el proceso ha finalizado. El punto q ser parte ahora del nuevo polgono convexo, as como lo sern los puntos pt1 y pt2. Sin embargo, es posible que algunos otros vrtices del polgono convexo desaparezcan. En el ejemplo de la figura, la secuencia de vrtices i+1; :::; j1 claramente desaparece al aadir el nuevo punto. El resultado final sera el polgono P = p0; p1; :::; pi_1; pi;q; pj ; pj+1; :::; pn_1. El orden de ejecucin del algoritmo es la suma de los siguientes trminos:

1. la operacin de ordenacin con coste O(nlogn)


2. Operacin que en el peor de los casos es lineal.

Por tanto, y aunque el algoritmo es susceptible de aadir mejoras, necesita en el peor de los casos un tiempo O(n2). 2.1.6.Mtodo Divide y Vencers Los mtodos divide y vencers siempre trabajan de modo similar. En este caso, partimos de una nube de puntos ordenada de izquierda a derecha que se divide en dos mitades A y B de aproximadamente el mismo tamao. Para cada una de estas mitades, continuamos el proceso de divisin hasta que finalmente el tamao de la nube de puntos es tan pequeo que puede resolverse el problema fcilmente. Este caso concreto es cuando tenemos tres puntos. Cuando el problema no pueda dividirse ms, el siguiente paso es unir dos a dos los polgonos convexos resultantes de la etapa anterior, en un nuevo polgono convexo. El proceso finaliza obteniendo la envolvente convexa de todos los puntos. Sin embargo, la etapa de unin de dos polgonos convexos en un nico polgono convexo no es inmediata. Necesitamos calcular dos tangentes que unan dichas envolventes, una tangente superior y otra inferior. El mecanismo para conseguir, por ejemplo, la tangente inferior, podemos observarlo en la siguiente figura. Se comenzara suponiendo que el segmento que une el punto ms a la derecha de A y el punto ms a la izquierda de B es una tangente vlida. Como esta suposicin es falsa para este ejemplo, decidimos bajar vrtices sucesivamente hasta que por fin para el polgono A se localiza una envolvente. En el ejemplo, A2-B5 ya es una tangente para A, sin embargo no lo es para B. El siguiente paso es hacer exactamente lo mismo pero bajando sucesivos vrtices de B. El proceso termina cuando para los dos polgonos se encuentra una tangente.

Juan Carlos Gutirrez Barquero____________________________________________

165

Bismarck Salvador Traa Lpez__________________________________________ UNI

Para saber si ab es tangente a un polgono observemos los siguientes grficos: queda como ejercicio la implementacin de las funciones TangenteMenor y TangenteMayor.

El tiempo de ejecucin de un algoritmo divide y vencers depende en gran medida del comportamiento de la funcin de mezcla de cada pareja de diagramas polares. Cuando sto se realiza en tiempo lineal, como es este caso, sabemos que contamos con un algoritmo en tiempo O(nlog n). 2.2. Triangulacin de polgonos

En el Tema 1 hicimos referencia por primera vez a la triangulacin de polgonos. En esa ocasin se hizo incapi de la necesidad de encontrar un algoritmo eficiente para realizar este clculo, puesto que el dado en dicho tema posee un tiempo de ejecucin poco eficiente. En esta seccin conseguiremos triangular cualquier tipo de polgono en tiempo ptimo O(nlogn), para ello sern necesarios dos pasos diferentes: la particin de cualquier polgono en particiones montonas y la triangulacin de cada una de estas porciones. 2.2.1. Polgonos montonos Un polgono montono con respecto a la vertical es aquel que si se recorre con una lnea horizontal bajando a lo largo del total del polgono, ocurre que slo encontramos como mximo dos intersecciones del polgono con dicha recta. Si

Juan Carlos Gutirrez Barquero____________________________________________

166

Bismarck Salvador Traa Lpez__________________________________________ UNI


adems no consideramos la existencia de aristas horizontales, entonces hablamos de polgono extrictamente montono. Intuitivamente hablando, un polgono montono ser aquel que no posee cspides interiores, considerndo al vrtice vi como cspide si vi1 y vi+1 estn ambos arriba o abajo. La ventaja de triangular un polgono montono es ms o menos intuitiva: al bajar una lnea horizontal imaginaria a lo largo de todo el tringulo y encontrarse con el vrtice vi, se sabe que su diagonal ir a un punto visible desde dicho punto. La idea es ir bajando paulatinamente vrtice a vrtice, bien por la izquierda, bien por la derecha, dibujando diagonales segn el siguiente algoritmo. ALGORITMO TriangulacionMonotona ENTRADA: El polgono S de tamao n SALIDA : El conjunto de Diagonales que t r i a n g u l a n e l polgono INICIO Ordenar (S, n , p ) ListaCrea ( l ) l i s t aCr e a ( Diagonales ) ListaMeteFinal ( l , p [ 0 ] ) ListaMeteFinal ( l , p [ 1 ] ) PARA j <_ 2 HASTA n_1 REPETIR SI Adyacente ( L i s t a I n i c i o ( l , p [ j ] ) AND NOT Adyacente ( L i s t a F i nal(l),p[j]) ENTONCES v<_ L i s t aSa c a I ni c io ( l ) MIENTRAS (NOT ListaVacia ( l ) ) REPETIR v <_ L i s t aSa c a I ni c i o ( l ) ListaMeteFinal ( Diagonales , v , p [ j ] ) FIN_MIENTRAS ListaMeteFinal ( l , v ) ListaMeteFinal ( l , p [ j ] ) SINO SI Adyacente ( L i s t a F i n a l ( l ) , p [ j ] ) AND NOT Adyacente ( L i s t a I n icio(l),p[j]) ENTONCES v<_ListaSacaFinal ( l ) x<_F i n a l L i s t a ( l ) MIENTRAS ( Angulo ( p [ j ] , v , x ) < Pi ) REPETIR ListaMeteFinal ( Diagonales , x , p [ j ] ) v <_ ListaFinalSaca ( l ) SI NOT ListaVacia ( l ) ENTONCES x<_L i s t a F i n a l ( l ) FIN_MIENTRAS ListaMeteFinal ( l , v ) ListaMeteFinal ( l , p [ j ] )

Juan Carlos Gutirrez Barquero____________________________________________

167

Bismarck Salvador Traa Lpez__________________________________________ UNI


SINO v<_L i s t aSa c a I n i c io ( l ) v<_L i s t aSa c a I n i c io ( l ) MIENTRAS NOT ( ListaVacia ( l ) ) v<_L i s t aSa c a I ni c i o ( l ) ListaMeteFinal ( Diagonales , p [ j ] , v ) FIN_MIENTRAS FIN_SI FIN_SI FIN_PARA En la siguiente figura podemos observar el conjunto de diagonales obtenidas tras la ejecucin de este algoritmo para el polgono montono de ejemplo.

Veamos como funciona el algoritmo en sus primeros pasos para este ejemplo. Al ordenar los puntos de mayor a menor obtenemos la numeracin que vemos en la figura. Antes de entrar en el bucle, la lista l = s0; s1. Al entrar por primera vez en el bucle con j = 2, observamos que s2 es adyacente al final de la lista l (2a sentencia condicional) pero el algoritmo no construye an diagonales porque el Angulo(s[2],1,0)>por lo que la lista acaba siendo l =s0; s1; s2. Las siguientes iteraciones son iguales, hasta que para j = 4 se construyen las diagonales 14;24;34. La idea bsica del algortimo es construir diagonales con el comienzo de la lista l o con el final de sta , teniendo en cuenta que slo se unen puntos visibles entre s (ngulo <) y que no son adyacentes. El tiempo de ejecucin de este algoritmo es O(nlog n). El proceso de ordenacin de los vrtices ya posee este orden de ejecucin, por lo que dicho algoritmo no podra ejecutarse en menor tiempo. Adems habra que aadir un

Juan Carlos Gutirrez Barquero____________________________________________

168

Bismarck Salvador Traa Lpez__________________________________________ UNI


tiempo lineal, puesto que todas las operaciones del algoritmo, operaciones con el final y principio de la lista, el clculo del ngulo, etc., se ejecutan en tiempo constante. Tan slo nos puede plantear un problema los bucles MIENTRAS, pero sin embargo aseguramos el tiempo lineal del proceso, puesto que todo vrtice es procesado como mucho dos veces, uno cuando entra en la lista y otra vez cuando sale de sta. 2.2.2. Particin de un polgono en componentes montonas La triangulacin de polgonos montonos desde luego deja de tener sentido si no es posible particionar cualquier tipo de polgono en particiones montonas. En este apartado completamos el proceso de triangulacin eficiente de polgonos dando un algoritmo capaz de encontrar diagonales tales que dividan dicho polgono en particiones montonas. Consideramos a un polgono y-montono si para cada horizontal h, la interseccin del polgono con h es conexa, esto es, es un punto o el vaco. La definicin para x-montono es anloga. Antes de ver el funcionamiento del polgono determinaremos los cinco tipos de vrtices que podemos encontrar: Vrtice comienzo: el vrtice vi es de comienzo si vi1 y vi+1 poseen menor ordenada y su ngulo interior es menor que .

Vrtice final: el vrtice vi es de final si vi1 y vi+1 poseen mayor ordenada y su ngulo interior es menor que .

Vrtice Particin: el vrtice vi es de particin si vi1 y vi+1 poseen menor ordenada ysu ngulo interior es mayor que .

Juan Carlos Gutirrez Barquero____________________________________________

169

Bismarck Salvador Traa Lpez__________________________________________ UNI

Vrtice Mezcla: el vrtice vi es de mezcla si vi1 y vi+1 poseen mayor ordenada y sungulo interior es mayor que .

Vrtice Regular: cualquier otro vrtice no considerado anteriormente.

Utilizaremos la tcnica de .lnea de barrido. para encontrar las distintas particiones montonas. La idea ser localizar los vrtices que rompen la monotona, los de particin y los de mezcla. Desde ellos se lanzarn diagonales, el destino de stos ser tambin un objetivo primordial del algoritmo. Las estructuras de datos implicadas son las siguientes: P: ser un array conteniendo los vrtices del polgono, ordenados como es habitual en sentido antihorario. Q: La lnea imaginaria bajando por el plano se encontrara los puntos de P de

Juan Carlos Gutirrez Barquero____________________________________________

170

Bismarck Salvador Traa Lpez__________________________________________ UNI


mayor a menor ordenada. Para no duplicar los puntos, y sobre todo por ventajas computacionales, Q ser un vector de tamao n con los ndices de P identificando los puntos ordenados de mayor a menor ordenada. T: Se trata de alguna estructura de datos con tiempo de acceso logartmico. Almacenar los vrtices ei, siendo ei = vi vi+1, con excepcin de en1 = vn1v0. El conjunto de ejes se almacenan por la coordenada x, tanto de izquierda a derecha. Ayu: Es un array que almacena en todo momento el vrtice candidato para unir a los vrtices de particin y mezcla. Los valores podrn ir cambiando hasta que se localice el valor correcto. D: Mantiene el resultado, es decir, el conjunto de diagonales conseguidas por el algoritmo. Puede ser un array o una lista.

Algoritmo de triangulacin PROCEDIMIENTO HacerMonotono (VAR P : TipoPol igono ; VAR D: TipoLi s ta ) ENTRADA: El polgono P de tamao n SALIDA : El conjunto D de diagonales INICIO Ordenar_Y ( P, n ,Q) I n i c i l i z a r L i s t a ( T) I n i c i a l i z a r L i s t a (D) Para k<_ 0 hasta n_1 Repet i r i <_Q( k )

Juan Carlos Gutirrez Barquero____________________________________________

171

Bismarck Salvador Traa Lpez__________________________________________ UNI


34 2 La envolvente convexa y triangulacin de polgonos EN CASO DE QUE TipoVer t i ce (P, i ) SEA 0 : ( _ Comienzo _) ListaInser tarOrdenado (T, i ,P) Ayu ( i ) <_ i 1 : ( _ Final _) Si TipoVer t i ce (P , Ayu ( i _1))=2 Entonces I n s e r t a r L i s t a (D, { i_Ayu ( i _1)}) L i s t aEl imi n a r ( T , i _1) 2 : ( _ Mezcla_) Si TipoVer t i ce ( P, Ayu ( i _1))=2 Entonces L i s t a I n s e r t a r (D, { i_Ayu ( i _1)}) L i s t aEl imi n a r ( T , i _1) j <_ ListaBuscar Izdo ( T , i ) Si TipoVer t i ce ( P, Ayu ( j ) )=2 Entonces L i s t a I n s e r t a r (D, { i_Ayu ( j ) } ) Ayu ( j ) <_ i 3 : ( _ Pa r t i c i n ) j <_ ListaBuscar Izdo ( T , i ) L i s t a I n s e r t a r (D, { i_Ayu ( j ) } ) Ayu ( j )<_ i ListaInser tarOrdenado ( T , i ,P) Ayu ( i )<_i 4 : ( _ Regular_) Si Inter iorDecha ( P, i ) Entonces Si TipoVer t ice (P , Ayu ( i _1))=2 Entonces L i s t a I n s e r t a r (D, { i_Ayu ( i _1)}) L i s t aBo r r a r (T, i _1) ListaInser tarOrdenado (T, i ,P) Ayu ( i )<_i Sino j <_ListaBuscar Izdo (T, i ) Si TipoVer t ice (P, Ayu ( j ) ) = 2 Entonces L i s t a I n s e r t a r (D, { i_Ayu ( j ) } Ayu ( j )<_ i FIN_SI FIN_SI FIN_CASE FIN El tiempo de ejecucin del algoritmo es ptimo. La ordenacin de los vrtices puede realizarse en tiempo O(nlog n). Cada una de las n iteraciones de bucle se ejecuta en tiempo logartmico, el correspondiente a las operaciones de manejo de la estructura de datos T.

Juan Carlos Gutirrez Barquero____________________________________________

172

Bismarck Salvador Traa Lpez__________________________________________ UNI

3 Intersecciones La deteccin de intersecciones constituye una de las primitivas geomtricas fundamentales con muy diversas aplicaciones. En realidad virtual o diseo de circuitos VLSI el manejo de intersecciones es fundamental. Pero existen otras reas de inters ms prximas a la Topografa como son los Sistemas de Informacin Geogrfica. En muchas ocasiones para hacer los mapas ms manejables y legibles, la informacin que contienen se divide en distintos tipos de mapas, cada uno especializado en carreteras, ciudades, ros y montaas, densidad de poblacin, etc. La informacin geomtrica subyacente en cada uno de estos mapas tambin puede considerarse diferente, as una carretera puede ser representada mediante una polilnea y un ncleo urbano puede serlo mediante conjunto de polgonos. Sin embargo, cuando dos de estos mapas necesitan ser manejados al mismo tiempo (por ejemplo para conocer las carreteras que llegan a una ciudad), es necesario el manejo de intersecciones entre iguales o diversos objetos geomtricos. Los problemas que necesitan del procesamiento de intersecciones pueden ser de distinta ndole. En algunas ocasiones no es necesario determinar con exactitud el punto de corte entre dos elementos geomtricos, nicamente conocer si existe dicha interseccin. Tambin podemos encontrar una diferencia sustancial entre manejar un par de lneas o segmentos o hacerlo con un conjunto de ellos. De hecho, la realidad a veces necesita simular la forma de cualquier lnea mediante una polilnea o conjunto de segmentos unidos a modo de cadena. La naturaleza de los objetos tambin puede ser conveniente conocerla a priori, puesto que la interseccin de polgonos convexos cuenta con un orden de ejecucin menor que si se trata de polgonos generales. 3.1. Interseccin de polgonos convexos El tiempo de ejecucin para conocer la interseccin de dos polgonos cualesquiera es O(nm), siendo n y m el nmero de ejes de los dos polgonos. El resultado de calcular la interseccin de dos polgonos cualesquiera podemos verlo en la siguiente figura:

Juan Carlos Gutirrez Barquero____________________________________________

173

Bismarck Salvador Traa Lpez__________________________________________ UNI

Sin embargo, realizar esta operacin con polgonos convexos puede hacerse en tiempo O(n+m). Existe una propiedad importante para la interseccin de polgonos convexos: la interseccin es tambin un polgono convexo. Denominaremos a A y B a los ejes que en cada momento se estn ejecutando. En cada iteracin se avanza el eje A o el B (siempre en orden inverso a las agujas del reloj) dependiendo de ciertas reglas de avance. El objetivo es que dichos avances se vayan sincronizando en cuanto a su velocidad para encontrar todas las intersecciones. Denominamos a como el punto de la cabecera del vector A, y b el punto de la cabecera de B. Las reglas de avance harn por ejemplo, que si B apunta hacia la lnea que contiene a A, entonces avanzamos B para buscar la interseccin con A. Denominaremos a H(A) como el semiplano cerrado a la izquierda de A y a H(B) como el semiplano cerrado a la izquierda de H(B). Ocurre que AxB > 0 cuando el giro ms corto de girar A hacia B es en sentido inverso a las agujas del reloj. Como por regla general los dos vectores no coincidirn en su inicio, imaginaremos sin embargo que as ocurre para localizar el giro ms corto. En el siguiente ejemplo, AxB > 0 puesto que observamos que hacemos un giro en sentido de las agujas del reloj para ir de A hacia B.

Las reglas de avance quedan resumidas en la siguiente tabla: AXB Condiciones del semiplano Regla de avance

Juan Carlos Gutirrez Barquero____________________________________________

174

Bismarck Salvador Traa Lpez__________________________________________ UNI

El mtodo anteriormente descrito aparece a continuacin. Tambin aparece el pseudocdigo de otros subalgoritmos llamados por el algoritmo principal. PROCEDIMIENTO IntersectaPol igonosConvexos (VAR P,Q: TipoPol igono ; n ,m: Entero ) ENTRADA: P,Q de tamao n y m SALIDA : VARIABLES: CONSTANTES: Origen : ( 0 , 0 ) INICIO a<0 b<0 Dentro < 1 REPETIR a1 < (a+n1) mod n b1 < (b+m1) mod m Subvector (P[ a ] , P[ a1 ] , A) Subvector (Q[ b ] , Q[ b1 ] , B) ProductoX < Area2 ( Origen , A, B) bHA < IzdaSobre (P[ a1 ] ,P[ a ] ,Q[ b ] ) aHB < IzdaSobre (Q[ b1 ] ,Q[ b ] ,P[ a ] ) SI ( I n t e r s e c t a P[ a1 ] ,P[ a ] ,Q[ b1 ] ,Q[ b ] ,P) ENTONCES SI Dentro = 1 ENTONCES AvanA < 0 AvanB < 0 fiNfiSI Dentro < TestDentro ( aHB) fiNfiSI SI ( ProductoX fi 0) ENTONCES SI ( bHA) ENTONCES a < Avanza ( a , AvanA , n , Dentro , P[ a ] ) SINO b < Avanza ( b , AvanB , m, NOT Dentro , Q[ b ] ) SINO SI ( aHB) ENTONCES b < Avanza ( b , AvanB , m, NOT Dentro , Q[ b ] ) SINO a < Avanza ( a , AvanA , n , Dentro , P[ a ] ) fiNfiSI HASTA ( AvanA fi n AND AvanB fi m) SI Dentro = 1 ENTONCES ESCRIBIR "No ha habido i n t e r s e c c i n " ; fiN

Juan Carlos Gutirrez Barquero____________________________________________

175

Bismarck Salvador Traa Lpez__________________________________________ UNI


FUNCION TestDentro (H: Entero ) : Lgico INICIO SI H < > 0 ENTONCES TestDentro < 1 SINO TestDentro < 0 fiN FUCION Avanza (VAR ab , Avd : Entero ; n : Entero ; Dentro : Lgico ; v : TipoPunto ) INICIO SI Dentro ENTONCES Pi n t a r ( v ) fiNfiSI Adv < Adv + 1 ab < (ab +1) mod n fiN PROCEDIMIENTO Subvector (VAR a , b , c : TipoPunto ) INICIO PARA i < 0 HASTA 1 INCR + 1 REPETIR c [ i ] < a [ i ] b [ i ] fiNfiPARA fiN En el siguiente ejemplo observamos un ejemplo de polgonos convexos.

En la siguiente tabla observamos el resultado tras aplicar el algoritmo. En la ltima columna observamos el avance de los ejes. Podemos comprobar que el recorrido conjunto de ambos ejes permite localizar todas y cada una de las intersecciones existentes.

Juan Carlos Gutirrez Barquero____________________________________________

176

Bismarck Salvador Traa Lpez__________________________________________ UNI

3.2. Interseccin de segmentos La interseccin de segmentos es un clculo muy importante por las repercusiones que tiene a nivel de intersecciones en el mundo real. Podemos simular una carretera como un conjunt de segmentos. Para saber donde se podra construir un puente podramos computar el conjunto de intersecciones entre el mapa de carreteras y el mapa de ros. Las operaciones realizadas a bajo nivel en la aplicacin informtica que lleve a cabo este clculo sern las de intersecciones de segmentos. Puede realizarse siempre un algoritmo de fuerza bruta para realizar este clculo utilizando para ello un tiempo O(n2) si supuestamente empleamos un nmero similar de ros y de carreteras. Como es de imaginar este algoritmo procesara todos los ros con todas las carreteras, y siendo por tanto poco eficiente. Probablemente el nmero de intersecciones sea mucho menor al de potenciales puntos de interseccin, por lo que podra buscarse un mtodo alternativo que tuviera por principio el procesar nicamente posibles intersecciones en segmentos que estn cerca, evitando as clculos innecesarios. La estrategia a seguir puede ser la de bajar una lnea horizontal L de arriba hacia abajo por el plano de modo que se vaya tropezando tanto con un tipo de segmentos como del otro. Cada vez que L se encuentra con un segmento lo almacena en una lista ordenada de izquierda a derecha, y as sucesivamente con todos y cada uno de los segmentos localizados. Para cada nueva interseccin y borrado en dicha lista se pregunta si la nueva situacin provoca una interseccin, siempre entre segmentos vecinos de la lista.

Juan Carlos Gutirrez Barquero____________________________________________

177

Bismarck Salvador Traa Lpez__________________________________________ UNI


Emplear las estructuras de datos correctas en este mtodo es fundamental para la eficiencia de ste. P: Es un array que contiene el conjunto de segmentos iniciales dispuesto en principio en cualquier tipo de orden. El array tiene un tamao de nx4 puntos, siendo cada fila los cuatro puntos que forman un segmento en el orden {x0; y0; x1; y1}, siendo siempre el punto (x0; y0) el extremo de mayor ordenada. Q: Es la denominada cola de eventos que almacena el conjunto de vrtices y de puntos interseccin. Mantendr los puntos extremos ordenados de mayor a menor ordenada. Cuando en dicha lista se inserten dos puntos con la misma ordenada, se considerar primero el de menor abscisa. Ser preferentemente una lista a un array porque deber permitir inserciones. T: Estructura de datos que simula el comportamiento de la lnea imaginaria L. Mantendr ordenados de izquierda a derecha los segmentos que en todo momento vaya atravesando, eliminado los ya procesados e insertndolos cuando se comienzan a atravesar. Esta estructura de datos deber permitir inserciones y borrados en tiempo logartmico 1. I: Cualquier tipo de estructura de datos que almacene las intersecciones localizadas. La funcin ManejarEvento es la encargada de procesar cada uno de los nuevos extremos de la cola de eventos Q. Esta funcin sera llamada por el algoritmo EncontrarIntersecccion tal y como vemos a continuacin. ALGORITMO Encontrar Interseccin

Juan Carlos Gutirrez Barquero____________________________________________

178

Bismarck Salvador Traa Lpez__________________________________________ UNI

Juan Carlos Gutirrez Barquero____________________________________________

179

Bismarck Salvador Traa Lpez__________________________________________ UNI

Sin embargo, la funcin de interseccin de segmentos desarrollada en el primer tema no es vlida para conocer el punto de interseccin entre dos segmentos, slo para saber si dicha interseccin se produce.

Juan Carlos Gutirrez Barquero____________________________________________

180

Bismarck Salvador Traa Lpez__________________________________________ UNI


En el siguiente ejemplo vemos un conjunto de segmentos en los cuales podemos encontrar un conjunto de intersecciones. Hay que tener en cuenta que el algoritmo tambin detecta las intersecciones de los segmentos por sus extremos, ya que hay que tener en cuenta que los segmentos pueden llegar desordenados y sin relacin unos con otros.

4 Localizacin de puntos y diagramas de Voronoi 4.1. Punto en polgono El problema denominado punto en polgono se presenta cada vez que se pincha el ratn en pantalla. Si el polgono P sobre el que trabajamos es convexo, el problema puede solucionarse en tiempo O(logn). Pero el mtodo ms interesante ocurre cuando P no es convexo. Para este caso utilizamos el siguiente mtodo: si queremos saber si el punto q est dentro o fuera del polgono P trazamos una lnea en cualquier direccin, por ejemplo utilizando la recta r igual a y = 0, x fi 0 y entonces contamos el nmero de intersecciones que se producen. El punto q est dentro de P si el nmero de intersecciones es impar. Para hacer ms fcil el clculo y utilizar una recta r vlida para cualquier caso, hacemos coincidir el punto q con el origen de coordenadas de forma que la r pueda ser simplemente y = 0; para x >= 0.

Juan Carlos Gutirrez Barquero____________________________________________

181

Bismarck Salvador Traa Lpez__________________________________________ UNI

Para conocer el lugar justo de interseccin utilizaremos la siguiente frmula:

trasladamos la idea anterior al siguiente algoritmo en pseudocdigo que realiza el test de inclusin de punto en polgono. El primer conjunto de bucles hace el cambio de origen de coordenadas. En el siguiente se detectan las intersecciones con la recta y = 0, pero slo se tienen en cuenta los cortes que se producen para x > 0.

El tiempo de ejeccin de este test de inclusin es lineal, como claramente indica la bsqueda exhaustiva de intersecciones de una recta con todas las aristas de un polgono.

Juan Carlos Gutirrez Barquero____________________________________________

182

Bismarck Salvador Traa Lpez__________________________________________ UNI


DIAGRAMA DE VORONOI

En este captulo estudiamos el diagrama Voronoi, una estructura geomtrica segunda en importancia slo detrs del buque convexo. En cierto sentido un diagrama de Voronoi registra todo lo que uno alguna vez querra saber acerca de proximidad para un grupo de puntos (u objetos ms generales). Y a menudo uno quiere saber detalles acerca de la proximidad: Quin est ms cercano a quin? Quin est ms lejos? Etctera. El concepto tiene ms de un siglo de antigedad, discutido en 1850 por Dirichlet y en 1908 por Voronoi. Comenzaremos con una serie de ejemplos para motivar el debate y entonces, la zambullida en los detalles de la estructura enriquecedora del diagrama Voronoi (en las Secciones 5.2 y 5.3). Hay que familiarizarse con estos detalles antes de que los algoritmos puedan ser apreciados (en la Seccin 5.4). Finalmente revelaremos la bella conexin entre diagramas Voronoi y buques convexos en la Seccin 5.7. Este captulo incluye slo dos pedazos pequeos de cdigo, para construir lo dual del diagrama Voronoi (la triangulacin Delaunay), en la Seccin 5.7.4.

APLICACIONES PRELIMINARES

1. Las torres de observacin de fuego Imagine un bosque vasto conteniendo un nmero de torres. Cada guardabosque es responsable de extinguir cualquier fuego ms cercano para su torre que para cualquier otra torre. El grupo de todos los rboles para los cuales un guardabosque particular es responsable constituye el Polgono de Voronoi asociado con su torre. El diagrama de Voronoi traza las lneas entre estas reas de responsabilidad: Los lugares en el bosque que son equidistantes de dos o ms torres. (Una vistazo a la Figura 5.5 puede ayudar a la intuicin).

Juan Carlos Gutirrez Barquero____________________________________________

183

Bismarck Salvador Traa Lpez__________________________________________ UNI


2. Las torres en llamas Imagine ahora la situacin perversa donde todos los guardabosques encienden sus torres simultneamente, y el bosque se quema a una velocidad uniforme. El fuego se dispersar en crculos centrado en cada torre. Los puntos en los cuales el fuego se apaga es porque ha alcanzado previamente rboles consumidos son esas puntos equidistantes de dos o ms torres, los cules son exactamente los puntos en el diagrama Voronoi. 3. La agrupacin de vecinos mas cercanos Una tcnica frecuentemente utilizada en el campo de reconocimiento de patrones es trazar un mapa de un grupo de objetos blancos en un rasgo del espacio reduciendo los objetos a puntos cuyas coordenadas son las medidas de rasgo. El ejemplo de cinco medidas de la sastrera de la Seccin 4.6.1 puede ser visto como una definicin o una caracterstica del espacio. La identidad de un objeto de afiliacin desconocida entonces le puede ser asignada al objeto prximo de blanco en el rasgo del espacio. Un ejemplo har esto ms claro. Suponga que un depsito de partes incluye dos tipos de nueces A y B, una con dimetros interior y exterior de 2 y 3 centmetros respectivamente, y B con el espacio de dimetros 3 y 4 cm., el rasgo es el cuadrante positivo del plano Euclidiano de dos dimensiones, positivo porque ningn radio puede ser negativo A traza al grano (2,3), y B al punto (3,4). Suponga, que un sistema de visin enfoca la atencin en una nuez x en el depsito y se mide su radio interior y exterior para tener 2.8 y 3.7 cm. Conociendo que hay inexactitudes de medida, y que slo las nueces de tipo A y B estn en el depsito, que tipo de nuez es x? Es ms probable que sea una nuez de tipo B, porque su distancia para B en el rasgo del espacio 0.36, considerando su distancia para A es 1.06. Vea la Figura 5.1. En otras palabras, la vecina ms prxima de x es B, porque la x est en el polgono de Voronoi de B. Si hay muchos tipos de nueces, la tarea de identificacin es localizar la nuez desconocida x en el diagrama de Voronoi de las nueces blancos. Cmo puede estar esto hecho eficazmente se discutir en la Seccin 5.5.1.

Juan Carlos Gutirrez Barquero____________________________________________

184

Bismarck Salvador Traa Lpez__________________________________________ UNI

4. La facilidad de Localizacin Suponga que a usted le gustara localizar una tienda de comestibles nueva en un rea con varias tiendas de comestibles existentes, irreconciliables. Asumiendo densidad de poblacin uniforme, dnde debera estar la tienda nueva localizada para optimizar sus ventas? Un mtodo natural que satisfaga esta restriccin vaga es localizar la tienda nueva tan lejos de las viejas como sea posible. Aun esto es un poco vago; Ms precisamente podramos escoger una localizacin cuya distancia para la tienda prxima es tan grande como sea posible. Esto es equivalente a localizar la tienda nueva en el centro del crculo vaco ms grande, el circulo ms grande cuyo interior no contiene otras tiendas. La distancia para la tienda mas prxima es entonces el radio de este crculo. Mostraremos en 5.5.3 Seccin que mientras central de crculo vaco ms grande debe mentir en el diagrama Voronoi. 5. Planeando el camino Imagine un ambiente desordenado a travs del cual un robot debe planear un camino. Para minimizar el riesgo de colisin, al robot le gustara quedarse tan lejos de todos los obstculos como sea posible. Si restringimos la pregunta a dos dimensiones, y si el robot es circular, entonces el robot debera quedarse todo el tiempo en el diagrama de Voronoi de los obstculos. Si los obstculos son puntos (digamos polos delgados), entonces ste es el diagrama convencional de Voronoi. Si los obstculos son polgonos u otras formas, entonces una versin generalizada del punto del diagrama Voronoi determina el camino apropiado. Revisaremos este ejemplo en el Captulo 8 (la Seccin 8.5.2). 6. La cristalografa

Juan Carlos Gutirrez Barquero____________________________________________

185

Bismarck Salvador Traa Lpez__________________________________________ UNI

Asuma un nmero de granos de cristal crecen uniformes, a velocidad constante. Cul ser la apariencia del cristal cuando el crecimiento ya no es posible? Debera estar claro ahora que esto es anlogo al incendio de bosques, y que cada grano crecer para un polgono de Voronoi, con regiones adyacentes del grano encontrndose a lo largo del diagrama de Voronoi. Los diagramas de Voronoi por mucho tiempo se han usado para simular crecimiento del cristal. La lista de aplicaciones podra seguir sin parar, y veremos otros en la Seccin 5.5. Pero es hora de definir el diagrama formalmente. DEFINICIONES Y PROPIEDADES BASICAS Sea P = {p1, p2,, pn} un grupo de puntos en el plano Euclidiano de dos dimensiones. stos son llamados los sitios. Divida en partes el plano asignando cada punto en el plano a su sitio ms prximo. Todos esos puntos asignados a pi forman la regin de Voronoi V (pi). V (pi) consiste de todos los puntos al menos tan cercanos a pi en lo que se refiere a cualquier otro sitio: V (pi) = {x: | pi - x pj - x j }. Note que hemos definido este grupo para ser cerrado. Algunas puntos no tienen un nico sitio prximo, o vecino prximo. El grupo de todos los puntos que tienen ms de un vecino cercano forman el diagrama de Voronoi V (P) para el grupo de sitios. Ms tarde definiremos los diagramas de Voronoi para grupos de objetos ms generales que puntos. Primero miramos diagramas con justamente algunos sitios antes de detallar sus propiedades para n mayor. Dos sitios Considere solo dos sitios, p1 y p2. Sea B (p1, p2) = B12 la bisectriz perpendicular del segmento p1p2. Entonces cada punto x en B12 es equidistante de p1 y p2. Esto puede verse dibujando el tringulo (p1, p2, x) como se muestra en la Figura 5.2. Por el teorema del lado - ngulo - lado de Euclides, | p 1x | = | p2x |.

Juan Carlos Gutirrez Barquero____________________________________________

186

Bismarck Salvador Traa Lpez__________________________________________ UNI

Tres sitios Para tres sitios, es claro que fuera del tringulo (p1, p2, p3), el diagrama contenga la bisectriz B12, B23, B31. Lo que no esta claro es que ocurre en los alrededores del tringulo. Otra vez de Euclides las bisectrices perpendiculares de los tres lados del tringulo todos atraviesan un punto, el circuncentro, el centro del nico crculo que pasa a travs de los vrtices del tringulo. As el diagrama Voronoi para tres puntos debe aparecer como en la Figura 5.3. (Sin embargo, el circuncentro de un tringulo no est siempre dentro del tringulo como se muestra).

Semiplanos La generalizacin ms all de tres puntos quiz todava no esta clara, pero es ciertamente claro que la bisectriz Bij desempear un papel. Sea H el semiplano cerrado con lmite Bij y conteniendo pi. Entonces H puede ser visto como todos los puntos que estn cercanos a p i que a pj. Ahora ordene el regreso de que V (pi) es el grupo de todos los puntos ms cercano a p i que a cualquier otro sitio: En otras palabras, los puntos ms cercanos a pi que a p1, y

Juan Carlos Gutirrez Barquero____________________________________________

187

Bismarck Salvador Traa Lpez__________________________________________ UNI


ms cercano a pi que a p2, y ms cercano a pi que a p3, etctera. Esto muestra que podemos escribir esta ecuacin o V(pi): V (pi) =

i j

H (pi, pj)

(ecuacin 5.2)

Donde la notacin significa que la interseccin debe estar ocupada sobre todo i y j como i j. Note que esa conjuncin inglesa y ha sido trasladada a interseccin de conjunto.

Figura 5.4 (a) Diagrama de Voronoi para cuatro puntos cocirculares; (b) diagrama despus de mover los puntos hacia la izquierda. La ecuacin (5.2) inmediatamente nos da una propiedad importante de los diagramas de Voronoi: Las regiones de Voronoi son convexas, pues la interseccin de cualquier nmero de Semiplanos es un grupo convexo. Cuando las regiones estn rodeadas, son polgonos convexos. Los bordes de las regiones de Voronoi son llamados bordes de Voronoi, y los vrtices son llamados vrtices de Voronoi. Note que un punto en el interior de un borde de Voronoi tiene dos sitios prximos, y un vrtice de Voronoi tiene al menos tres sitios prximos. Cuatro sitios El diagrama de cuatro puntos formando las esquinas de un rectngulo es mostrado en la Figura 5.4 (a). Note que el vrtice de Voronoi es de grado cuatro. Ahora suponga que un sitio es movido ligeramente, como en la Figura 5.4 (b). Hay un sentido en el cual este diagrama es normal, y uno en la Figura 5.4 (a) que es anormal o degenerado. Es degenerado por que hay cuatro puntos cocirculares. A menudo lo encontraremos til para excluir este tipo de degeneracin.

Juan Carlos Gutirrez Barquero____________________________________________

188

Bismarck Salvador Traa Lpez__________________________________________ UNI


Muchos sitios Un diagrama tpico con muchos sitios es mostrado en la figura 5.5. Un vrtice de Voronoi no es mostrado en esta figura: Los dos rayos casi horizontales dejando el diagrama para la izquierda no son muy paralelos y se intersecan en un vrtice de Voronoi cerca de 70 centmetros a la izquierda de la figura. Tamao del diagrama Aunque hay exactamente n regiones de Voronoi para n sitios, el tamao combinatorio total del diagrama concebible podra ser cuadrtico en n, pues cualquier regin particular de Voronoi puede tener (n) bordes de Voronoi (Ejercicio 5.3.3 [4]). Sin embargo, nosotros ahora mostramos que de hecho este no es el caso, que el tamao total del diagrama es (n). Asumamos pues por simplicidad que ninguna de los cuatro puntos son cocirculares, y por consiguiente cada vrtice de Voronoi es de grado tres. Construya la grfica dual G (Seccin 4.4) para un diagrama Voronoi V (P) como sigue: Los nodos de G son sitios de V (P), y dos nodos estn conectados por un arco si sus polgonos correspondientes de Voronoi comparten un borde de Voronoi (comparten un borde de longitud positiva). Ahora observe que ste es un grafo planar: Podemos incrustar cada nodo en su sitio, y todo el incidente de arcos para el nodo puede ser angularmente clasificado lo mismo los bordes del polgono. Adems todas las caras de G son tringulos, siendo propio del vrtice de Voronoi de grado tres. Este reclamo ser hecho ms claro en un momento (la Figura 5.6). Pero previamente mostramos que la frmula de Euler significa que un grafo planar triangulado con n vrtices tiene 3n-6 de bordes y 2n-4 caras; Vea la Seccin 4.1.1 Teorema 4.4.5. Porque las caras de G son propias de los vrtices de Voronoi, y porque los bordes de G son propios de los bordes de Voronoi (desde que cada arco de G le cruza un borde de Voronoi), hemos mostrado que el nmero de vrtices de Voronoi, bordes, y las caras es (n). Si ahora removemos, entonces la suposicin que ninguno de los cuatro puntos son cocirculares, la grfica es todava planar, pero no necesariamente triangulado. Por ejemplo, lo dual del diagrama mostrado en Figura 5.4 (a) es un cuadriltero. Pero tales grficas poco trianguladas tienen menos conexiones entre dos vrtices de un grfico y caras, as es que los (n) saltos continan teniendo aplicacin. Una consecuencia del salto del borde 3n-6 es que el nmero comn de bordes de un polgono de Voronoi no puede ser ms de seis (el Ejercicio 5.3.3 [5]). Triangulacin de Delaunay En 1934 Delaunay prob que cundo la grfica dual se traza con lneas rectas, produce una triangulacin planar de los sitios de Voronoi P (si ninguno de los cuatro sitios son cocirculares), ahora llamado la triangulacin de Delaunay D

Juan Carlos Gutirrez Barquero____________________________________________

189

Bismarck Salvador Traa Lpez__________________________________________ UNI


(P). Figura 5.6 muestra la triangulacin de Delaunay para el diagrama de Voronoi en Figura 5.5, y la figura 5.7 muestra que la triangulacin de Delaunay superpuesta en el diagrama correspondiente de Voronoi. Note que no es inmediatamente que usando lneas rectas en el duales evitaria cruzarse adentro del dual; El segmento dual entre dos sitios necesariamente no cruza el borde Voronoi compartido entre ahora, pero ms bien esperaremos hasta que hayamos recogido ms propiedades de la triangulacin Voronoi de diagramas y Delaunay, cundo la prueba ser fcil. Las propiedades de triangulacin de Delaunay Debido que la triangulacin de Delaunay y el diagrama de Voronoi son estructuras duales, cada uno contiene la misma informacin en algn sentido, solamente represent en una forma ms bien diferente. Para ganar un agarre en estas estructuras complicadas, es importante para tener una comprensin cabal de las relaciones entre una triangulacin de Delaunay y su diagrama correspondiente de Voronoi. Listamos sin prueba varias propiedades de Delaunay y seguiremos con una lista ms substantiva de propiedades de Voronoi. Slo la propiedad D6 y D7 no han sido mencionados anteriormente. Fija un grupo de sitios P. D1. D (P) es la lnea recta dual de V (P). Esto es por definicin. D2. D (P) es una triangulacin si ninguno de los cuatro puntos de P son cocirculares: Cada cara es un tringulo. ste es el teorema de Delaunay. Las caras de D (P) son llamados tringulos de Delaunay. D3. Cada cara (tringulo) de D (P) es propia de un vrtice de V (P). D4. Cada borde de D (P) es propio de un borde de V (P). D5. Cada nodo de D (P) es propio de una regin de V (P). D6. El lmite de D (P) es el buque convexo de los sitios. D7. El interior de cada (tringulo) cara de D (P) no contiene sitios. Las propiedades D6 y D7 aqu son lo ms interesante; Pueden ser verificados en Figura 5.6 y 5.7. Elementos del diagrama de Voronoi Podemos considerar los siguientes elementos en el diagrama de Voronoi: pi punto generador. eje es el conjunto de segmentos, semirectas o lneas in_nitas que son frontera de una regin de Voronoi a otra. vrtice un punto que comparte ms de dos polgonoos de Voronoi. adyacentes dos regiones se dice que son adyacentes si comparten algn eje.

Juan Carlos Gutirrez Barquero____________________________________________

190

Bismarck Salvador Traa Lpez__________________________________________ UNI


Los conceptos anteriores son extensibles a tres dimensiones, teniendo en cuenta que ahora las regiones de Voronoi seran poliedros y los ejes seran polgonos. Las propiedades de los Diagramas de Voronoi V1. Cada regin de Voronoi V (pi) es convexa. V2. V (pi) es ilimitada si pi est en el buque convexo del grupo del punto. V3. Si la v es un vrtice de Voronoi en la unin de V (p 1), V (p2), y V (p3), entonces la v es el centro del crculo C (v) determinado por p1, p2, y p3. (Este reclamo generaliza a los vrtices de Voronoi de cualquier grado). V4. C (v) es el circuncirculo para el tringulo de Delaunay correspondiente a v. V5. El interior de C (v) no contiene sitios. V6. Si pj es el vecino prximo a pi, entonces (pi, pj) es un borde de D (P). V7. Si hay algn crculo a travs pi y pj que no contiene otros sitios, entonces (pi, pj) es un borde de D (P). El inverso tambin tiene aplicacin: Pues cada borde de Delaunay, hay algn crculo vaco. La propiedad V7, la menos intuitiva, es una caracterizacin importante de los bordes de Delaunay y ser usada en varias pruebas ms tarde. sta es la nica propiedad que probaremos formalmente. La prueba. En una direccin es fcil: Si ab es un borde de Delaunay, entonces V (a) y V (b) comparten un borde de longitud positiva e V (P). Ponga a un crculo C (x) con centro en x, con radio igual a la distancia de a o b. Este crculo est obviamente vaco de otros sitios, pero si no fuera as, el sitio c estara sobre o dentro del crculo, x estara en V (c) igualmente, pero conocemos que x esta solamente V (a) y V (b).

La implicacin inversa es ms sutil. Suponga que hay un crculo vaco C (x) a travs de a y b, con centro en x. Tenemos la intencin de poner a prueba que

Juan Carlos Gutirrez Barquero____________________________________________

191

Bismarck Salvador Traa Lpez__________________________________________ UNI


ab D (P). Porque la x es equidistante de a y b, x est en las regiones de Voronoi de ambos a y b mientras ningn otro punto interfiera con El sentido de la hermandad prximo. Pero ninguno es, porque el crculo est vaco. Por consiguiente, x V(a) V (b) (la retentiva que definimos como regiones de Voronoi son grupos cerrados). Porque ninguno de los puntos estan sobre el lmite de C (x) de otra manera que a y b (por la hiptesis), all deban ser libertad para contonearse la x un poco y mantener vaco C (x). En particular, podemos mover x a lo largo de Bab, la bisectriz entre a y b, y podemos mantener vaco al conservar el crculo a travs de a y b. Ver la Figura 5.8. Por eso la x est en una longitud positiva del borde de Voronoi (un subconjunto de Bab ) compartido entre V (a) y V (b). Y por consiguiente ab D (P). Dejamos la prueba de las otras propiedades para la intuicin, los ejercicios, y para la Seccin. 5.7.2 Ejercicios 1. El polgono regular [fcil]. Describa la triangulacin del diagrama de Voronoi y la triangulacin de Delaunay para los vrtices de un polgono regular. 2. Las regiones ilimitadas. Ponga a prueba la propiedad V2: V (pi) es ilimitada del si pi est en el buque convexo del grupo del punto. No se haga cargo de la propiedad correspondiente de Delaunay D6, pero de otra manera cualquier propiedad Delaunay o Voronoi puede ser empleada en la prueba. 3. El vecino ms cercano. Ponga a prueba propiedad V6: Si el pj es un vecino prximo a pi, entonces (pi, pj) es un borde de D (P). Cualquier propiedad Delaunay o Voronoi puede ser empleada en la prueba. 4. El vrtice de Delaunay de alto-grado. Disee un grupo de puntos, con n arbitrario, y sin cuatro puntos cocirculares, algo semejante aqul que el vrtice de la triangulacin Delaunay tiene grado n-1. 5. Numero promedio de bordes del polgono de Voronoi, pruebe que el promedio de todas las regiones Voronoi para cualquier grupo de n puntos, no excede 6. 6. Las triangulaciones de Pitteway. Una triangulacin de un grupo de P de puntos es llamada una triangulacin Pitteway si, para cada tringulo T = (a, b, c), cada punto en T tiene uno de a, b, o c como su vecino mas cercano entre los puntos de P. a. Muestre por ejemplo que no toda triangulacin de Delaunay es una triangulacin de Pitteway. b. Caracterizar aquellas triangulaciones de Delaunay que son triangulaciones de Pitteway. Los ALGORITMOS Las muchas aplicaciones del diagrama de Voronoi y su belleza inherente les han instado a los investigadores a que inventen una coleccin variada de algoritmos para computarlo. En esta Seccin 5.7.2 examinaremos cuatro algoritmos, cada uno superficialmente, para ver que la Seccin 5.7.2 que el diagrama Voronoi puede ser computado usando nuestro cdigo del buque convexo.

Juan Carlos Gutirrez Barquero____________________________________________

192

Bismarck Salvador Traa Lpez__________________________________________ UNI


La interseccin de los Semiplanos Podramos construir cada regin de Voronoi separadamente, por la interseccin de n-1 semiplanos segn la ecuacin (5.2). Construyendo la interseccin de n semiplanos es dual para la tarea de construir el buque convexo de n puntos en dos dimensiones y puede ser llevado a cabo con algoritmos similares en el tiempo O(n log n) tiempo (Ejercicio 6.5.3 [5]). Hacer esto para cada sitio costara a O (n2 log n). Construccin incremental Suponga que el diagrama de Voronoi V para k puntos estn ya construidos, y ahora nos gustara construir el diagrama V despus de aadir uno o mas puntos p. Suponga que p cae dentro de los crculos asociados con varios vrtices de Voronoi, dice C (v1),, C (vm). Entonces estos vrtices de V no pueden ser vrtices de V, pues violan la condicin de que los crculos del vrtice de Voronoi deben estar vacos de sitios (V5, Seccin 5.3.2). Resulta que stos son los nicos vrtices de V que no estn arrastrados sobre V Tambin resulta que estos vrtices estn todos localizados en un rea del diagrama. Estas observaciones vagas pueden ser hechas precisas, y forjan uno de los algoritmos ms limpios para construir el diagrama de Voronoi. El algoritmo gasta O (n) tiempo por insercin de punto, para una complejidad total de O (n2). A pesar de esta complejidad cuadrtica, ste ha sido el mtodo ms popular de construir el diagrama; Ver Field (1986) para los detalles de implementacin. El algoritmo incremental ha sido revitalizado recientemente con aleatorizacin, el cual tocaremos en la Seccin 5.7.4. Divide y vencers El diagrama de Voronoi puede estar construido con un complejo algoritmo divide y conquista en el tiempo O (n log n), primera parte detallada por Sahmos y Hoey (1975). Fue este papel que introdujo el diagrama de Voronoi para la comunidad de ciencia de la computacin. Esta vez la complejidad es asintticamente ptima, pero el algoritmo es bastante difcil para implementar. De cualquier forma puede estar hecho con atencin meticulosa para las estructuras de datos.

Juan Carlos Gutirrez Barquero____________________________________________

193

Bismarck Salvador Traa Lpez__________________________________________ UNI

Omitiremos este algoritmo histricamente importante para enfocar la atencin en algunos desarrollos recientes emocionantes. El algoritmo de Fortune

Hasta la mediados de los 80, la mayora de implementaciones para computar el diagrama de Voronoi le usaron a la O (n 2) algoritmo incremental, aceptando su desempeo ms lento para evitar las complejidades de la codificacin divide y conquista. Pero en 1985, Fortune (1987) invent un algoritmo del barrido de plano listo que es tan simple como los algoritmos incrementales pero tiene complejidad del peor caso de O (n log n). Nosotros ahora esbozaremos la idea principal detrs de este algoritmo. Los algoritmos Plane-sweep(barrido de plano) (Seccin 2.2.4 ) pasan una lnea de barrido sobre el plano, dejando en cualquier hora el problema solucionado para la porcin del plano ya barrido y no resuelta para la porcin todava no alcanzada. Un algoritmo Plane-sweep para construir el diagrama de Voronoi construira el diagrama detrs de la lnea. A primera vista, esto parece realmente mentira, como los bordes Voronoi de una regin de Voronoi V (p) seran encontrados por la lnea de barrido antes de que la L encuentre la p del sitio responsable para la regin. Fortune super esta imposibilidad aparente por una idea extraordinariamente lista.

Juan Carlos Gutirrez Barquero____________________________________________

194

Bismarck Salvador Traa Lpez__________________________________________ UNI


Los conos

Imagine los sitios en el plano xy del sistema de coordenadas tridimensional. Erecto sobre cada sitio p un cono cuya cima est en p, y cuyos lados se inclinan a 45. Si la tercera dimensin es mirada como el tiempo, entonces el cono sobre p representa un crculo dilatndose sobre p a una velocidad nica: Despus de t unidades tiempo, su radio es t. Ahora considere dos conos cercanos, sobre los sitios p1 y p2. Se intersecan en una curva en el espacio. Recordando la vista de crculos en expansin del diagrama de Voronoi, debera ser esperado que esta curva yazca enteramente en un plano vertical, el plano ortogonal para la bisectriz de p 1p2. Vea la Figura 5.9. As que aunque la interseccin est curvada en tres dimensiones, se proyecta para una lnea recta en el plano xy. Es solamente un paso pequeo de aqu a que si los conos sobre todos los sitios son opacos, y son mirados de z = - , lo que se ve es precisamente el diagrama Voronoi! El corte del cono Estamos ahora preparados para describir la idea de Fortune. Su algoritmo barre los conos con un plano sesgado, sesgado a 45 para el plano xy. La L de la lnea de barrido es la interseccin con el plano xy. Demos por supuesto que la L es paralela al eje vertical y que su coordenada de la x es l(ele). Vea Figura 5.10. Imagnate que , al igual que los conos, es opaco, y otra vez considera la vista de z = - . Para la x > l, lado de L, solamente es visible desde abajo: Hace un viraje debajo del plano xy y as tambin obscurece los sitios y los conos. Esto representa la porcin del plano todava no ha sido barrido. Para la x < l , lado de L, el diagrama de Voronoi es visible hasta la interseccin de con la frontera derecha (x positiva) de los conos. La interseccin de con cualquier cono es una parbola (una propiedad bsica de secciones cnicas), y as la interseccin de con su frontera derecha proyecta al plano xy (y as aparece z = - ) como un frente parablico, una curva compuesta de piezas de parbolas. Vea Figura 5.11. Dos parbolas se unen en un lugar donde encuentra dos conos. De nuestro debate de la interseccin de dos conos arriba, esto debe estar en un borde de Voronoi. Frente parablico Ahora finalmente podemos ver cmo solucion Fortune el problema del problema de la lnea de barrido encontrando bordes de Voronoi antes de los sitios generadores: Porque su plano de barrido se inclina en los mismos bordes como los lados de los conos, L encuentra un sitio p exactamente cuando primero golpea el cono para p! Por lo tanto no es se el caso que el diagrama de Voronoi que est en todo tiempo construido para la izquierda de L, pero est en todo tiempo construido bajo , lo cual quiere decir que esta

Juan Carlos Gutirrez Barquero____________________________________________

195

Bismarck Salvador Traa Lpez__________________________________________ UNI


construido a la izquierda de L arriba para la parte delantera parablica, lo cual queda atrs de L un poco. El Lo que es mantenido en todo tiempo por el algoritmo es la parte delantera parablica, cuyas uniones trazan el diagrama de Voronoi sobre el tiempo, Desde que todas estas enroscaduchas permanecen en los bordes de Voronoi. Aunque nos acabamos de ninguna manera con la descripcin del algoritmo, no haremos el intento de detallarlo mas alla de esto. Finalmente, debera estar claro que el algoritmo slo necesite almacenar la parte delantera parablica, que es de tamao O (n) y es a menudo O( n ) .Esto es una ventaja significante del algoritmo de Fortune cuando la n es grande: El almacenamiento necesitado es a menudo mucho ms pequeo que el tamao de diagrama. Y n es a menudo grande, quiz 10 6 (Sugihara e Iri 1992), para diagramas basados en datos recogidos por ejemplo en los sistemas de informacin geogrficos. 5.4.5 Ejercicios

1. D V (p) (p) Disear un algoritmo para la computar del diagrama de Voronoi, dado la triangulacin Delaunay. Trate de lograr complejidad de 0 (n) tiempo. 2. Diagramas de Voronoi unidimensionales. Un Diagrama unidimensional de Voronoi para un grupo de puntos P = { P1, , Pn } en una lnea (diga el eje de la x) es un grupo de puntos V (P) = { x1, , xn-1 } algo semejante que el x1 es el punto medio de pi de Pi + 1. Suponga que usted da un conjunto X = { x1, , xn-1 }. Disee criterios que te permitirn determinar si es o no X es un diagrama de unidimensional de Voronoi de un grupo de puntos, y si es as. Determine P. Con qu rapidez es el algoritmo implementado? 3. Los diagramas dinmicos Voronoi. La imagen un grupo de puntos moviendo en el plano, cada uno con una velocidad fija y direccin. Sea V (t) el diagrama de Voronoi de puntos en el tiempo t. Este un problema no resuelto, obtener saltos apretados en el nmero de diagramas distintos combinatoriamente que pueden resultar todo el tiempo. Aqu le pregunto a usted que establezca lo mejor conoce salto inferior: (n2). En otras palabras, encuentre un grupo de n moviendo puntos algo tal que V (t) cambie su estructura combinatoria cn2 para alguna constante C. Ningn a mismo capaz de encontrar un ejemplo en el cual haya ms cambios pero el mejor salto alto esta alrededor de O(n3). n2

4. La triangulacin arbitraria. Disee un algoritmo para encontrar que una triangulacin arbitraria de un grupo de punto P: Una coleccin de diagonales incidente para cada punto de P que divide H (P) en tringulos. La ausencia del

Juan Carlos Gutirrez Barquero____________________________________________

196

Bismarck Salvador Traa Lpez__________________________________________ UNI


requisito que la triangulacin sea Delauny permite libertad considerable en el diseo. 5. Algoritmo Lanzando. Investigue el siguiente algoritmo pensado para construir a D (P): Comience con una triangulacin arbitraria de P. Entonces repito el siguiente procedimiento hasta que D (P) es logrado. Identifique dos tringulos adyacentes abc y cbd compartiendo la diagonal bc, tal que el cuadriltero abcd sea convexo. Si d est dentro del circuncirculo de abc, entonces suprima cb y agregue ad. Trabajar esto? 5.5 Aplicaciones en Detalle.

Ahora Discutiremos cinco aplicaciones del diagrama de Voronoi, en el detalle accidentado: Los vecinos prximos, las triangulaciones gordas, los crculos ms grandes vacos, los rboles de extensin mnimos, y viajando a travs de caminos del vendedor. 5.5.1 Los vecinos ms cercanos. Una aplicacin del diagrama Voronoi para agrupamiento de los vecinos ms cercanos mencionado en Seccin 5.1 Este problema puede verse como un problema de consulta: Cul es el vecino mas cercano a un punto buscado? Otra versin es la problema del vecino ms cercano: Encuentras el vecino mas cercano para cada punto en un grupo dado. Esto tiene un nmero de aplicacin en una variedad de campos, incluyendo biologa, la ecologa, la geografa, y Fsica. Defina la relacin entre el vecino mas cercano y un grupo P de puntos como sigue: La b es una vecina prxima de a si | a b | minc a| a c |, donde c P. Podemos escribir esta relacin a b: Un vecino cercano de a es b. Note que la definicin no es simtrica con respectos a las tareas que a a y b les toca, sugiriendo que la relacin no sea as misma simtrica. Y de hecho ste es ciertamente el caso: Si a b, no es necesaria que b a; Ver a Figure 5.12 Tambin nota que un punto puede tener varios vecinos igualmente cercanos (ejemplo, punto d en la figura). El vecino cercano pregunta Dado un grupo fijo de puntos P, construir el diagrama de Voronoi en el tiempo O (n log n). Ahora para un punto de consulta q, encontrando un vecino cercano de q para encontrar en cul regin de Voronoi cae, pues los sitios de esas regiones de Voronoi son precisamente sus vecinos cercanos. El problema de hallar un punto dentro de una particin es llamada localizacin del punto. El problema ha sido estudiado con exceso y ser discutido en el Captulo 7 (Seccin 7.11). Veremos que en este ejemplo, el tiempo O (log n) es suficiente para cada consulta. Todos los Vecino Cercanos

Juan Carlos Gutirrez Barquero____________________________________________

197

Bismarck Salvador Traa Lpez__________________________________________ UNI

Defina al Nearest Neigbor Graph ((NNG) Graficos de vecinos mas cercanos) para asociar un nodo con cada punto de P y un arco entre ellos si un punto es un vecino cercano del otro. Hemos definido esto para ser un grfico orientado, aunque la relacin no es simtrica, adecuadamente podra ser directa. Pero no necesitaremos la versin directa aqu.

Una forma sucinta a captar la esencia del algoritmo del vecino cercano eficiente es a travs del siguiente lema. Lema 5.5.1 NNG D (P) Dejo la prueba para el ejercicio 5.5.6 [2] y [3 ] Un algoritmo de fuerza bruta para encontrar a los vecinos cercanos para cada punto en un grupo requerira O (n2), pero el lema de arriba nos deja registrar solo los bordes O (n) de la triangulacin de Delauny y por lo tanto logra O (n log n). Vecino natural: Otra forma de conseguir el valor que tendra un punto cualquier p sera el de conocer todos aquellos vecinos naturales de p. Averiguar esta informacin no es ms que resolver el problema de los vecinos ms cercanos a un punto utilizando el diagrama de Voronoi. Aplicaciones en este sentido son la identi_cacin de tomos vecinos en el espacio, molculas o partculas en estructuras cristalinas y amorfas, etc. Ahora el punto de estudio p puede estar in_uenciado por dicho conjunto de vecinos, los cuales tambin puede llevar asociados distintos pesos de in_uencia

Juan Carlos Gutirrez Barquero____________________________________________

198

Bismarck Salvador Traa Lpez__________________________________________ UNI

1.5.2 La triangulacin Maximizando el ngulo Mnimo. Analizar las propiedades estructurales de forma complicada es a menudo realizado por una tcnica llamada anlisis finito del elemento. Esto es usado, por ejemplo, por fabricantes del automvil a modelar cuerpos del coche (Field 1986). El dominio a ser estudiado est subdividido en una malla de elementos finitos, y entonces las ecuaciones diferenciales relevantes modelando la dinmica estructural sea solucionado por discretizacin sobre la particin. La estabilidad de los procedimientos numricos usados depende de la calidad las buenas particiones y esto pasa por que la triangulacin de Delaunay son especialmente buenas particiones. Nosotros ahora discutiremos el sentido en el cual la triangulacin Delauny es buena. Una triangulacin de un grupo de puntos S es la generalizacin del objeto del cual la triangulacin de Delauny es un ejemplo particular. Un grupo de segmentos cuyos puntos finales estn en S, Que slo interseca a cada quien en puntos finales, y cul divide en partes el buque convexo de S en tringulos. Para los propsitos del anlisis finito del elemento, las triangulaciones con tringulos gordos son ms convenientes. Una forma para hacer esto precisa ms es evitar tringulos con ngulos pequeos. As es natural buscar una triangulacin que tiene el ngulo menor ms grande, esto es, para maximizar el ngulo de ms pequeo sobre todas las triangulaciones. Esto ocurre para hacer precisamente la triangulacin de Delauny! De hecho, una declaracin algo ms fuerte puede ser hecha, cul nosotros ahora describimos despus de introducir alguna notacin. Sea T una triangulacin de un grupo de puntos S, y sea su secuencia de angulos( 1, 2, , 3t), una lista de los ngulos de los tringulos, clasificados del ms pequeo al ms grande, con t el nmero de tringulos en T. El nmero t es uno constante para cada S (Ejercicio 5.5.6[4 ] ). Podemos definir una relacin entre dos triangulaciones del mismo grupo del punto, T y T ', eso trata de capturar la gordura de los tringulos. Diga que T T (T es ms gorda que T) si la secuencia de ngulo de T es lexicogrficamente mayor que la secuencia de ngulo de T ': Ya sea 1 > 1, o 1 = 1 y 2 > 2 o 1 = 1 y 2= 2 y 3 > 3,, etctera. Edelsbrunnerr (1987, p. 302) prob este teorema: Theorem5.5.2..La triangulacin de Delaunay T=D (P) es lo mximo con respecto a la relacin de la gordura - ngulo: T T para cualquier otra triangulacin T ' de P. En particular esto dice que la triangulacin Delaunay maximiza el ngulo menor. 1.5.3 El crculo Vaco ms grande

Juan Carlos Gutirrez Barquero____________________________________________

199

Bismarck Salvador Traa Lpez__________________________________________ UNI


Mencionamos en seccin 5.1 el problema de encontrar el crculo vaco ms grande entre un conjunto S de sitios: El centro de tal crculo es una buena localizacin para una tienda nueva. Otra aplicacin es mencionada por Toussaint (1983a): Localice un reactor nuclear tan lejos de una coleccin de ciudades-sitios como sea posible. Ahora examinamos problema del crculo vaco ms grande en detalle. El problema hace sentir un poco menos alguna restriccin sobre la localizacin del centro del crculo, para hay siempre crculos arbitrariamente vacos grandes fuera de cualquier grupo de puntos finito. As nosotros redactamos el problema de esta forma: El crculo Vaco ms grande. Encuentre que un crculo vaco ms grande cuyo centro est en el buque convexo (cerrado) de un grupo de n sitios S, vacos en que no contiene sitios en su interior, y ms grande que no hay otro semejante con estrictamente radio mayor. Sea a f (p) el radio del crculo ms grande y vaco puesto en el centro en P del punto. Entonces andamos buscando un mximo de esta funcin sobre toda p en el buque de S, H=H(S). Pero hay un nmero aparentemente infinito de candidatos apuntando a este mximo. Un tema comn en la geometra computacional es reducir un grupo infinito del candidato para una lista finita pequea, y entonces encontrar estos eficazmente. Seguimos esto en este escenario en esta seccin, comenzar por discutir informalmente que solamente ciertos puntos p son candidatos verdaderos para un mximo de f. Concntrese Dentro del cierre. Imagine inflar un crculo desde un punto p en H. El radio en el cual este circulo golpea y por consiguiente incluye algn sitio de S = { S1, Sn } es el valor de f (P). asumamos temporalmente a esta subdivisin que la p es estrictamente interior para H. Si el radio f (P), el crculo incluye justamente un sitio S1, entonces debera ser claro que f (p) no puede ser un mximo de la funcin del radio. Pues si p es movido para P ' a lo largo del rayo s1p (el rayo de s1 a travs de p) lejos de s1, entonces f (P ') es mayor, como se muestra en Figure 5.13 (los segundos pisos). Por eso la p no pudo haber sido un mximo local de f, pues hay un punto P ' en cualquier barrio de p donde f es mayor. Nota que esa suposicin de que p es estrictamente interior para el buque garantiza que hay una p ' como esa tambin en H. Asumamos que en el radio f (P), El circulo incluye exactamente dos sitios S1 y S2. Otra vez f (P) no puede estar en un mximo: Si la p es movida para P ' a lo largo de la bisectriz de s1s2 (fuera de s1 s2), entonces f (P ') es otra vez mayor, como se muestra en Figure 5.13 (baje crculos). Otra forma de ver esto por la interseccin de dos tales conos de sitios en el centro (Figure5 5.9) discutido en la seccin 4.4.4. la curva de interseccin de dos conos represe la distancia de los sitios para puntos en la bisectriz. Desde que la curva es una

Juan Carlos Gutirrez Barquero____________________________________________

200

Bismarck Salvador Traa Lpez__________________________________________ UNI


hiprbola ascendente, ningn punto interior de la bisectriz es un mximo local: La distancia aumenta de una direccin o otra. Es nica cuando el crculo incluye tres sitios que f (P) pudo estar en el mximo. Si lo tres sitios entrecruzados el centro p, en el sentido que hizo girar ms que lo que un semicrculo (como en Figure 5.3), entonces el movimiento de p en cualquier direccin resulta en moverse p ms cercano para algn sitio, y as disminuir a f (P). Nosotros ahora hemos establecido este hecho: Lema 5.5.3 Si el centro p de un crculo vaco ms grande es estrictamente interior para el buque de la sitio H (S), entonces la p debe ser coincidente con un vrtice de Voronoi. Note que no es necesariamente cierto que cada vrtice de Voronoi represente un mximo local de f (p) (el Ejercicio 5.5.6[5 ] ). Centro dentro del convexo Ahora consideremos que el circulo de centro p est en el buque H =H(S). La razn que nuestras anteriores discusiones no ejercen es esa movindose p para p ' el movimiento fuera del buque, y nuestra especificacin problemtica restringieron centros para el buque. Nosotros ahora discutimos an ms informalmente que por encima de que un crculo mximo debe incluir dos sitios.

Juan Carlos Gutirrez Barquero____________________________________________

201

Bismarck Salvador Traa Lpez__________________________________________ UNI

Supongo que f (p) es un mximo con p en H y el crculo incluye justamente s1 de sitios. Primero, que no puede ser esa p est en un vrtice de H, pues los vrtices de H es todos los sitios mismos, y esto implicara a esa f (P) = 0. As es que p est en el interior de un borde de H. Entonces moviendo p en uno u otro caso a lo largo de h debe aumentar su forma de distancia s1, cortado en rodajas por un plano vertical (la Figura 5.9). Si, sin embargo, el crculo centr en p contiene s1 de dos sitios y s2, entonces es posible que la direccin a lo largo de la bisectriz de los sitios que aumenta sus distancias sea la direccin que va fuera del buque. As adecuadamente podra ser que f (P) est en el mximo. Hemos mostrado este hecho: Lema5.5.4 si el centro p de un circulo vaci mas grande permanece en el buque de sitios H (S), Entonces p debe permanecer sobre un borde Voronoi.

Juan Carlos Gutirrez Barquero____________________________________________

202

Bismarck Salvador Traa Lpez__________________________________________ UNI

El algoritmo Nosotros ahora hemos establecido nuestro meta: Ha encontrado un grupo finito de punto que son centros potenciales de crculos vacos ms grandes: Los vrtices de Voronoi y las intersecciones entre bordes de Voronoi y el buque de sitios. Esto sugiere el algoritmo 5.1, debido a Toussaint (1983a). Note que no cualquier vrtice de Voronoi est necesariamente dentro del buque (la Figura 5.14), que necesita comprobar que v H dentro del algoritmo. Una implementacin ingenua de este algoritmo requerira el tiempo cuadrtico en n, pero localizar un vrtice Voronoi en H e intersecar un borde de Voronoi con e puede estar consumado en el tiempo O (log n), y estas eficiencias conducen a un algoritmo O (n log n) en conjunto. Dejamos Detallamos para ejercitar a 5.5.6[6. El algoritmo: crculo Vaco MS GRANDE Computar el diagrama Voronoi V (s) de la S de sitios. Computar el buque convexo H=H (S). Para v del vrtice Voronoi haga Si la v est dentro de H: V H entonces El radio de cmputo si el grupo cerrado de gente gir alrededor de v y actualizacin llega al lmite. Para cada e del borde Voronoi haga El cmputo p =e H, la interseccin del con el lmite del buque. El radio de cmputo de crculo gir alrededor de actualizacin de la P llegue al lmite. El regreso llegue al lmite.

Juan Carlos Gutirrez Barquero____________________________________________

203

Bismarck Salvador Traa Lpez__________________________________________ UNI

Lo mnimo que se extiende a lo largo un rbol. Lo mnimo que se extiende a lo largo un rbol. (MST)(A minimum spanning tree) de un grupo de puntos es la longitud del arbol que se extiende a lo largo de todos los puntos: es decir en rbol ms pequeo cuyos nodos son precisamente esos en el grupo. Cuando el largo de un borde es medido por la longitud usual del segmento Euclideano conectando sus puntos finales, el rbol es a menudo llamado el Euclideano mnimo extendindose a lo largo de rbol, abreviado a EMST. Aqu slo considerarn las longitudes Euclideano y as tambin dejarn caer al modificador redundante. Un ejemplo es mostrado en Figure 5.15. MST tienen muchas aplicaciones. Pues el ejemplo es la topologa de la red que minimiza la longitud total del alambre que usualmente minimiza ambos costo y el tiempo que se demora. Algoritmo de Kruskal Aqu consideraremos el problema de computar el MST de un grupo de puntos en el plano. Veamos primero el problema ms general de computar el MST para una grfica G. Aunque es de ninguna manera obvio, una estrategia vida sin discernimiento es encontrar al MST, basada en la intuicin simple que un rbol ms pequeo debera estar cercano de los bordes ms pequeos. Esto sugiere que puede estar tal rbol construido arriba del incrementalmente aadiendo borde ms pequeo, todava ningn explorado, lo cual tambin mantiene un arbolado (alifaticidad). Este algoritmo es conocido como el algoritmo de Kruskal y se publico en 1956. Sea T el rbol incrementalmente construido, y sea la notacin T + e quiere decir que el rbol T une el borde e. El algoritmo Kruskal se muestra en Algoritmo 5.2. No nos detendremos para probar este algoritmo, esta bien?. pero slo demanda que su complejidad se domina por el primer paso ordenando. Esto requiere (E log E) de tiempo, dnde la E es el nmero de bordes en la grfica.

El algoritmo: El ALGORITMO DE KRUSKAL Ponga en cortocircuito bordes de G por el largo por ah: E1, e2 Inicializar T para que este vaco Mientras la T no avanza a rastras haga Si T + e1 es acclica Entonces T + T + ei Juan Carlos Gutirrez Barquero____________________________________________ Ii + 1 El algoritmo 5.2 el algoritmo de Kruskal.

204

Bismarck Salvador Traa Lpez__________________________________________ UNI

MST D (p) Para el MST de puntos en el plano, hay ( n ) bordes, as es que la complejidad 2 del paso de clasificacin es O (n2 log n) si es cargada fuera en la grfica completa. Para llamar a este registro de los bordes de la triangulacin de Delaunay de proximidad en algn sentido, es razonable esperar que slo los bordes de Delaunay alguna vez necesiten ser usados para construir un MST. Y afortunadamente esto es cierto, como se muestra en el siguiente teorema. Teorema 5.5.5 Lo mnimo que se extiende a lo largo un rbol es un subconjunto de triangulacin Delaunay: MST D (p). Prueba. Queremos mostrar que si ab MST, entonces ab D. Implica that ab MST y suponga lo contrario que ab MST. Entonces tratamos de derivar una contradiccin enseando lo que se supuso MST no es mnimo. Recuerde que si ab D, entonces hay un crculo vaco a travs de a y b (Propiedad V7 y Teorema 5.3.1) .en caso contrario ab D, ningn crculo a travs de a y b puede estar vacos. En particular, el crculo de dimetro ab debe de tener un sitio dentro de este. As se supone que C est en este crculo, como se muestra en figura 5.16. Entonces | ac | < | ab |, y |bc|< |ab|; Estas desigualdades tienen aplicacin aun si C est en el crculo, puesto que la C es distinta de a y b. La extraccin de ab desconectar el rbol en dos rboles internos, con a en primera parte, Ta, y b en el otro, Tb. Suponga sin la prdida de generalidad que e esta en Ta. Elimine ab y aada el borde bc para hacer un rbol nuevo, T = Ta bc +Tb. Este rbol es mas corto, as el nico nico usado ab, no podra serminimo. Hemos alcanzado una contradiccin negando que ab est en D, as es que debe ser ese ab D.

Juan Carlos Gutirrez Barquero____________________________________________

205

Bismarck Salvador Traa Lpez__________________________________________ UNI

Esto entonces produce una mejora en el primer paso de algoritmo de Kruskal: Primero encuentre la triangulacin de Delaunay en el tiempo O (n Long n), y entonces clasifique slo esos bordes O (n), en el tiempo O (n logn). Resulta lo dems de algoritmo de Kruskal puede ser implementado para poner a funcionar en O (n log n), para que la complejidad total por encontrar el MST para el grupo de n untos en el plano es O (n log n). 5.5.5. El Problema del Vendedor de viajes. Uno de los problemas ms estudiados en la informtica es el problema del vendedor de viajes: Encuentre el ms pequeo camino cerrado que visita cada punto en un grupo dado. Tal camino se llamado El camino Vendedor de viajes(TSP); imagine los puntos como ciudades que el vendedor debe visitar en el orden arbitrario antes de devolver casa. Este problema tiene tremenda importancia prctica, no slo para esa aplicacin si no porque muchas otras problemticas pueden reducirse a l. Se ha probado que desafortunadamente, el problema es duro NP, un trmino tcnico que ningn algoritmo polinmico conoce para resolverlo (Garey y Johnson 1979); Ni parece probablemente al momento de escribir la presente que a ser encontrada. Las combinaciones de significado prctico y la inflexibilidad han conducido a una bsqueda para los algoritmos de heursticas efectivos y de aproximacin. Uno de los algoritmos de la aproximacin ms simples es basado en la triangulacin de Delaunay, Va lo mnimo que Se extiende a lo largo el rbol. La idea es ms bien algo simple, pero no obstante hace un trabajo razonable. Encuentra al MST para el grupo de puntos, y simplemente lo lleva cabo y lo all por la manera ilustrada en Figure 5.17. Debera estar claro que la excursin construida por aqu tiene exactamente dos veces el largo del MST, desde que cada borde del rbol se cruza una vez en cada direccin.

Juan Carlos Gutirrez Barquero____________________________________________

206

Bismarck Salvador Traa Lpez__________________________________________ UNI

Ahora obtenemos un lmite dentrote que esta mal este doble-MST recorrido podra ser. Sea M la longitud de Lo mnimo que se extiende a lo largo un rbol y M2 la longitud de a doble-MST; claro M2 = 2M. Sea T la longitud de El camino de un Vendedor de viajes r y T1 la longitud de un TSP con un borde removido. Note que T1 se extiende a lo largo del rbol.

Las siguientes desigualidades son inmediatas: T1 < T, M T1, M < T, M2 < 2T. Esto entones logra un lmite superior constante en la calidad del recorrido: Lo doble-MST no est peor que dos veces la longitud de TSP.

Juan Carlos Gutirrez Barquero____________________________________________

207

Bismarck Salvador Traa Lpez__________________________________________ UNI

Este resultado puede ser mejorado con heursticas diversas. Esbozar slo el ms simple tan heurstico, lo cual se basa en la determinacin comprensible para no volver a visitar un sitio dos veces. El recorrido del camino doble-MST de entrada, con la modificacin que si el prximo sitio ya se ha visitado hasta ahora por el camino, salte el sitio y considera conectarse al prximo uno a lo largo del doble-MST recorrido. Esto hace el efecto de tomar una ruta ms directa para recorrer MST . Si ponemos en un ndice los sitios por el orden en que ellos se visitan a lo largo del recorrido del MST, a algunos sitios que Si podra conectar para Sj por un segmento de la lnea recta o un atajo al recorrido, considerando que el recorrido doble-MST sigue un camino encorvado Si, Si+1 , , Sj-1,Sj.. Heurstico puede ser nico acorta el camino. Un ejemplo es mostrado 5.18. Note que el camino fue acortado. Desafortunadamente este heuristico no garantiza un desempeo mejorado, pero una variacin leve Conocido como las gamas Heursticas Christofides. Usa un grupo de segmentos llamados un El mnimo de Euclideano emparejando como un gua para atajos y puede garantizar un longitud del camino no ms de (3/2) T, eso es, no ms de 50 % ms largo que lo ptimo. Ms heursticos sofisticaron generalmente encuentran un camino dentro de un poco porcentaje ptimo (Bentley 1992), aunque este desempeo no est garantizado en su estado actual para el algoritmo citado anteriormente. Un resiente descanso terico es sin dudarlo el esquema de aproximacin de Polinomio-tiempo para el TSP, acerca de lo mejor, puede ser esperanza para un problema completo a NP. ste es un mtodo de llegar dentro (1 + ) de > 0, en un tiempo O (np), dnde la p son optativo para cualquier . Vea a Arora (1996) y Mitchell (1996). proporcionales para 1/ 5.5.6 Los ejercicios 1. El grado de NING. Cul es grado mnimo de salida de un nodo de un Grafico de vecino mas cercano(NING) (la Seccin 5.5.1) de n puntos en dos 2 dimensiones? Cul es el grado mximo de un nodo? Demuestran ejemplos que justifiquen su respuesta, e intento probar que son mximos. 2. NNG y D [Fcil] . Encuentran un ejemplos que muestre ese NNG pueden ser un subconjunto correcto de D (p). 3. NND D. Ponga a prueba a Lema5.5.1: Si la b es una vecina prxima de a. Entonces ab D (p). 4. Los Nmeros de tringulos en una estrangulacin. Comprobar que el nmero de tringulos t en cualquier triangulacin de algn grupo de puntos reparados S esat una constante toda triangulacin de S tiene la misma t. 5. El vrtice de Voronoi no un mximo local. Construya un grupo de puntos que tiene un vrtice de Voronoi estrictamente p dentro del buque, algo

Juan Carlos Gutirrez Barquero____________________________________________

208

Bismarck Salvador Traa Lpez__________________________________________ UNI


semejante que f (p) no es un mximo local, donde la f es funcin del radio definido en la seccin 5.5.3 6. El algoritmo del crculo vaco. El detalle (en el cdigo pseudo) cmo llevar a cabo el algoritmo del crculo vaco (Algoritmo 5.1) con el fin de que su complejidad de tiempo es O (n log n). 7. El Grfico del Barrio relativo (RNG) de juego de puntos P1,, Pn es un grfico cuyos nodos corresponden a los puntos, y con Pi de dos nodos y Pj conectado por un arco ellos son para que no acerca de cualquier otro punto, eso es, si |Pi + Pj| max { | Pi + Pm |,| Pi + Pm | }. m i . j (Vea Jaromezyk + y Toussaint (1992).) Esta ecuacin determina una regin prohibida dentro de la cual ningn punto Pm puede mentir si Pi y Pj son adyacentes en el RNG, no a diferencia del Teorema 5.3.1 Esta regin, llamada Lune ( Pi, Pj), son la interseccin de dos discos abiertos centradas en Pi y Pj, ambos de radio | Pi Pj |. a. Disee un algoritmo de fuerza bruta para construir al RNG. No se preocupe por eficiencia. Qu es su complejidad de tiempo? b. Ponga a prueba a ese RNG: Cada borde del RNG es tambin borde de la triangulacin de Delauny. (Comprese con Teorema 5.5.5). c. Use (b) disear un algoritmo ms rpido. 8. El tamao de triangulacin de Delaunay en tres dimensiones. Tenemos que mostrar cual es el tamao de la triangulacin de Delaunay adentro de dos dimensiones es lineal, O (n). Mostrar que esto no se mantiene en tres dimensiones: El tamao de D (p) puede ser cuadrtico. Defina a D (p) en tres dimensiones exactamente, anlogamente y para la versin de Dos dimensiones (bidimensional): Es el dual de V (p), el cual es el lugar de puntos geomtricos que no tienen un nico vecino cercano. Sea P un punto determinada consistente en dos partes: a El n/2 puntos uniformemente distribuidos alrededor de un crculo en el plano x y centrados en el origen, y b El n/2 puntos uniformemente distribuidos en el origen del eje z simtrico al origen.. Sostenga la opinin que el tamao de D (p) es (n2).

Juan Carlos Gutirrez Barquero____________________________________________

209

Bismarck Salvador Traa Lpez__________________________________________ UNI


9. El tamao del grfico del barrio relativo (RNG) en dimensiones del rbol. Ejercicio[7] anteriormente establecido ese RNG D (P) en dos dimensiones, y esta relacin contiene dimensiones arbitrarias. Se ha demostrado el tamao que tiene el RNG en dimensiones del rbol es O (n3/2) (Jaromezyk y Toussaint 1992), as es que es ms pequea que la triangulacin de Delaunay. Pero parece que este salto superior es dbil: Jaromezyk y Kowaluk (1991) suponen que el tamao es O (n). Confirmar esta conjetura es un problema. 10. MST RNG Pruebe que cada borde de un MST es un borde del RNG. (Comprese con Teorema 5.5.5)

11. Los puntos ms remotos de Voronoi. Defina el diagrama de puntos ms remotos de Voronoi F (P) asociado cada punto del plano para el sitio que es su vecino ms remoto, el sitio que est ms lejos (fuera). Los puntos con el vecino mas cercano de una region de voronoi mas remota; Los puntos con dos vecinos mas lejanos limitan con forma de bordes F (P). Vea Figura 5.19. a. Que es F (P) para dos sitios? b. Cul es F (P) para tres sitios? c. Derive algunas propiedades estructurales de diagrama ms remoto Voronoi, parecido al Delaunay y Voronoi en Seccin 5.3.1 y 5.3.2. Uso Figure 5.19 y 5 5.2.3. Uso 5.19 para ayudar a formar a hiptesis

Juan Carlos Gutirrez Barquero____________________________________________

210

Bismarck Salvador Traa Lpez__________________________________________ UNI


12. L Mnimo que se expande a lo largo de un Crculo. Muestre cmo el crculo ms remoto del radio el diagrama del punto de Voronoi puede usarse para computar lo ms pequeo que rodea un grupo dado del punto. Asuma que F (P) est disponible.

Ejes Medios El diagrama de Voronoi puede ser generalizado en varias direcciones, y algunas de estas generalizaciones tienen importante significado prctico. En esta seccin tocamos una generalizacin, una de las ms simples: aceptando un grupo de sitios que son un grupo infinitos de puntos, en particular el lmite contino de un polgono.

En la seccin 5.20 definimos el diagrama de Voronoi como el grupo de puntos cuyo sitio ms cercano no es nico. Estos puntos son equidistantemente mejor cerrados en dos o ms sitios. Define los ejes medios de un polgono P, que estn dentro de un grupo de puntos internos P que un punto bien cerrado entre los puntos de P. Una definicin muy similar puede ser usada para una coleccin de puntos arbitrarios, pero aqu examinaremos solo el caso donde los puntos forman el lmite de un polgono. El eje medio de un rectngulo se muestra en la figura 5.20; cada punto sobre el segmento horizontal dentro del rectngulo est equidistante de los puntos verticales de arriba abajo y estn por encima y por debajo de los lados del rectngulo. Cada punto sobre un segmento diagonal esta equidistante de dos lados adyacentes del rectngulo y los dos puntos finales del segmento horizontal estn equidistante de tres lados del rectngulo.

Juan Carlos Gutirrez Barquero____________________________________________

211

Bismarck Salvador Traa Lpez__________________________________________ UNI


Un ejemplo mas completo se muestra en la figura 5.21, ocho vrtices en un polgono convexo. Uno puede suponer a partir de este ejemplo que el eje medio del polgono convexo P est un rbol cuyos permisos son los ejes de P. Esto es un porcentaje verdadero y est realmente lleno de polgonos no convexos. Todo punto de los ejes medios est en el centro de un circulo que toca el lmite de los puntos ms lejanos y as es como los vrtices de Voronoi estn en los centros de los crculos tocando tres sitios, los vrtices de los ejes medios estn en el centro de los crculos tocando tres puntos distintos del limite como se muestra en la figura 5.22. A veces los ejes medios de P estn definidos como el sitio central de los crculos mximos: los crculos dentro de P estos no son los mismos encerrados en algunos otros sitos dentro de P. El proceso de transformacin dentro de los ejes medios son en ocasiones llamados Transformacin de Bosques Quemados por si una imagen del polgono P tal como un csped seco que alumbra con un fuego a los bordes de P, todo esto causar que queme todo dentro de el a una velocidad uniforme y los ejes medios sean el grupo de puntos extintos donde el fuego conozca al fuego de otra direccin. La conexin entre esta analoga y la quema del bosque discutido en la seccin 5.1 debera ser evidente. Los ejes medios fueron introducidos por Blum en 1967 para el estudio en forma biolgica, el observo de manera semejante a un esqueleto (eje) las amenazas bajo el medio (mediana) de alguna forma. Esta es menos aparente para un polgono convexo que para un no convexo y formas planas que era el principal inters de Blum, uno puede caracterizar la forma de cierta seccin de la estructura de estos ejes medios y esto va incluido un inters considerable entre los investigadores en el reconocimiento de patrones y visiones de computadoras, por ejemplo bookstein lo usa para caracterizar las diferencias entre los huesos de la mandbula normales y los deformados. Puede ser usada para calcular una compensacin interior de un polgono, todos de cuyas fronteras son compensaciones interiores por una distancia fija. Expandidas o externas compensaciones cuentan en la versin exterior del eje medio. Calcular compensaciones es un importante problema en la manufacturacin, donde la tolerancia de ingeniera es llevada naturalmente a formas de compensacin.

Juan Carlos Gutirrez Barquero____________________________________________

212

Bismarck Salvador Traa Lpez__________________________________________ UNI

El eje medio de un polgono de n vrtices puede ser construido en 0 (n log n) time; asintoticamente menor pero ms prcticos de logaritmos estn disponibles. Para polgonos convexos, 0 (n) veces es suficiente.

Ejercicios Eje medio de un polgono no convexo. Mostrar por ejemplo que el eje medio de un polgono no convexo puede contener segmentos curvados. Qu puedes decir acerca de la forma funcional de estas curvas?

Juan Carlos Gutirrez Barquero____________________________________________

213

Bismarck Salvador Traa Lpez__________________________________________ UNI


Eje medio y el diagrama de Voronoi o hay alguna relacin entre el eje medio de un polgono convexo P y el diagrama de Voronoi de los vectores de P? Supone algunos aspectos de esta relacin y prubalos y construye contra ejemplos.

Eje medio de un polgono. Describe lo que debe parecer el eje medio de un polgono. Estructura recta. Aichholzer, Alberts, Aurenhammer & Grtner, introdujo una estructura que es similar al eje medio, pero compuesta de segmentos rectos incluso para polgonos no convexos. Mover cada borde de un paralelo al mismo interior a una velocidad constante con bordes adyacentes encogiendo y creciendo as que los vrtices viajan a lo largo del ngulo bisector. Cuando un borde se encoge hasta la longitud cero, sus bordes vecinos se hacen adyacentes. Cuando un vrtice reflejo choca hacia adentro de un borde, el poligono se agrieta y el proceso de encogimiento de las piezas contina. Trabaja manualmente la estructura recta con unas formas letras conectadas del alfabeto: T, E, X. Forma algunas suposiciones acerca de las propiedades de la estructura recta.

Conexin con el Convexo Hulls El 1986 Ellels Brunner & Seidel decubri una bella conexin entre la triangulacin de Delaunay y el convex hulls en una de las ms altas dimensiones: primero explicar entre el convex hull bidimensional y la triangulacin unidimensional de Delaunay (que son admitimademente triviales) y entonces generaliza la triangulacin bidimensional de Delaunay y el tridimensional convex hull. Entonces esta conexin nos dar un mtodo fcil para calcular la triangulacin de Delaunay y del diagrama de Voronoi, va tridimensional hulls triangulacin unidimensional de Delaunay. Empezaremos en una dimensin donde la matemtica es transparente sea P= {x1,,xn} un conjunto de puntos sobre el eje x. Claramente la triangulacin unidimensional de Delaunay es simple el camino conecta x1 a x2 a xn , pero veremos que esto es una proyeccin sobre el eje x de un conjunto de puntos bidimensionales con coordenadas (xi, x2i). Estos puntos pueden ser vistos como una proyeccin de la ascendencia de x en la parbola z= x2. Es trivialmente verdadero que el connuex hull de estos puntos bidimensionales proyectado hacia abajo a la triangulacin unidimensional de Delaunay, tanto como el borde ms alto del hull es descartado, pero hay mucho ms aqu que esta observacin trivial que puede ser aclarada con la consideracin de las tangentes a la parbola.

Juan Carlos Gutirrez Barquero____________________________________________

214

Bismarck Salvador Traa Lpez__________________________________________ UNI

La pendiente de la parbola z= x2 en el punto x= a es 2a (porque dz/dx= 2x). De esta manera la ecuacin de la tangente a la parbola en el punto (a, a2) es z-a2= 2a (x-a) z= 2a x-a2 En preparacin para estudiar el mismo proceso en tres dimensiones, ahora investigaremos la interseccin entre esta tangente y la parbola cuando la tangente es trasladada verticalmente una distancia r2. Cuando la tangente es aumentada por esta cantidad su ecuacin se convierte en z=2a x-a2 + r2 Entonces la tangente aumentada intersecta la parbola en + r lejos de a, el punto original de tangencia. Nota que x= a + r puede ser pensado como la ecuacin de un circulo unidimensional de radio r centrado en a. Esto es ilustrado en la figura 5.23 con a= 5 y r= 3 as que el disco es el segmento [2,8]. Triangulacin Bidimensional de Delaunay Repetimos el mismo anlisis en dos dimensiones. El paraboloide es z= x2 + y2, (Ver la figura 5.24) toma los sitios/puntos dados en el plano y los proyecta hacia arriba hasta que toca el paraboloide, eso es, trazar cada punto como sigue: (xi, yi) | (xi, yi, x2i + y2i)

Juan Carlos Gutirrez Barquero____________________________________________

215

Bismarck Salvador Traa Lpez__________________________________________ UNI


Toma el convex hull de este conjunto de puntos tridimensionales, ver la figura 5.25. Ahora descarta las caras ms altas de este hull. Todas esas caras que son exteriores punteando los puntos superiores normales, en el sentido de times un producto positivo el resultado es una condra ms baja. Proyectar esto al plano xy. El reclamo es que esta es una triangulacion de Delaunay. Ver la figura 5.26. Ahora establecemos esta fenomenal conexin formalmente. La ecuacin del plano tangente encima del punto (a, b) es z=2a x + 2b y (a2 + b2) (Esta es una analoga directa a la ecuacin z= 2a x a2: dz/dx= 2x and dz/dy= 2y)

Ahora cambiamos este plano superior por r2, exactamente como cambiamos la lnea tangente en la subseccin previa z= 2a x +2b y (a2 + b2)+ r2 (x-a)2 + (y-b2)= r2

Juan Carlos Gutirrez Barquero____________________________________________

216

Bismarck Salvador Traa Lpez__________________________________________ UNI

El plano cambiado intercepta el paraboloide en una curva (una elipse) que proyecta a un crculo. Esto es ilustrado en la figura 5.27 y 5.28. Ahora revisemos desde un punto de vista para dirigirnos s la triangulacin Delaunay. Considere el plano a travs de tres puntos en el paraboloide = ( pi, pj, pk) que forma una cara del buque de convexo en tres dimensiones. Este plano parte de la paraboloide. Si traducimos verticalmente hacia abajo, entonces en algn punto cesar de intersecar el paraboloide. Digamos que el ltimo punto que toca es (a, b, a2 b2). Entonces podemos observar como un cambio ascendente de este plano contiguo; Llame a la cantidad de cambio r2. Ahora debera estar claro que el anlisis previo tiene aplicaciones. Desde esta en una cara inferior del buque, todo las otras puntos del paraboloide estn arriba. Desde que estn arriba , estn ms que el r2 arriba, cul es el r2 debajo. Por eso estos puntos se proyectan fuera del crculo de radio r en el plano x y. Por eso el crculo determinado adentro de los planos x y est vaco en todos los otros sitios. Por eso forma un tringulo Delaunay. Por eso cada cara triangular inferior del buque convexo es propia de un tringulo Delaunay. Por eso la proyeccin del fondo del buque convexo se proyecta para la triangulacin Delaunay! Otra vez evacue a Figure 5.26. Djeme explicar esta compenetracin importante otra vez de otra manera. Comience con el plano t contiguo para el paraboloide por encima de p = (a, b). Su punto de contacto se proyecta hacia abajo para p. Ahora muvase t arriba. La proyeccin de su interseccin con el paraboloide es un crculo en expansin puesto en el centro en p. Cuando los t golpes una punto q en el paraboloide que esta por encima de un sitio, las intercepciones del crculo en expansin en el sitio en el plano que es la proyeccin de q. As el crculo est vaco t hasta los lmites exteriores, cundo atraviese los tres sitios cuya proyeccin forma la cara del buque del tringulo soportada por . Un corolario til para el debate citado anteriormente es ste:

Juan Carlos Gutirrez Barquero____________________________________________

217

Bismarck Salvador Traa Lpez__________________________________________ UNI

Corolario 5.7.1 Cuatro puntos (xi, yi), i = 1, 2, 3, 4, consisten en una mentira del crculo si (xi, yi, xi2 yi2) en un plano. La coplanaridad de estas puntos puede ser comprobada viendo si el volumen del tetraedro que determinan (la Ecuacin 1.15 y 4.6) es cero.

La implicacin Teorema 5.7.2 La triangulacin de Delaunay de un grupo de puntos en dos dimensiones es precisamente la proyeccin para el Plano x y del buque convexo inferior de lo transformado apunta en tres dimensiones, transformado por mapeo arriba para el paraboloide z = x2 y2. Desde que el buque convexo en tres dimensiones puede ser computado en el tiempo O (la Seccin 4.2.2) (n log n), esto significa que la triangulacin de Delaunay puede ser computada en el mismo tiempo lmite. Una vez que la triangulacin Delaunay est en tus manos, es relativamente fcil computar el diagrama Voronoi (el Ejercicio 5.7.5[2 ] ). Esto conduce a otro algoritmo O (n log n) para construir el diagrama de Voronoi. Como se podra esperar, esta relacin entre diagramas Voronoi y podra abombar buques que yo una dimensin ms alta mantengo en dimensiones arbitrarias. As ambos el diagrama Voronoi y la triangulacin Delaunay en tres dimensiones pueden forjarse de un buque convexo en cuatro dimensiones. De hecho, puede ser que el ms uso comn de cdigo del buque del 4D es para construir mallas slidas de Delaunay tetradrico. En general, el diagrama de Voronoi dual para un grupo de puntos de d-dimensional es la proyeccin del buque inferior de puntos en d + 1 dimensin. La implementacin de la Triangulacin de Delaunay: El cdigo O (n4) Teorema 5.7.2 el cdigo conciso permite increblemente computar la triangulacin de Delaunay, si uno es indiferente sobre la complejidad de tiempo En particular, si O (n4) es aceptable (y raramente lo es), entonces la triangulacin de Delaunay puede ser computada con menos esas treinta lneas de cdigo de la C! Esto es presentado en cdigo 5.1 en parte como la curiosidad, pero tambin a enfatiza cmo la comprensin profunda de geometra puede conducir al cdigo limpio.

main() { int x[MAX],y[MAX],z[MAX];

/*Intreda de puntos x,y,z*/

Juan Carlos Gutirrez Barquero____________________________________________

218

Bismarck Salvador Traa Lpez__________________________________________ UNI


int n; int i,j,k,m; int flag; /*Numero dep puntos introducidos*/ /*induce de cuatro puntos*/ /*localizacion normal de (i,j,k)*/

/*Intrda de puntos y computar z=x^2+y^2*/ scanf("%d",&n); for(i=0; i<n; i++) { scanf("%d %d",&x[i],&y[i]); z[i]=x[i]*x[i]+y[i]*y[i]; } /*por cada tres (i,j,k)*/ for(i=0;i<=n-2;i++) for(j=0;j<=n-2;j++) for(k=0;k<=n-2;k++) if(j!=k) /*computar la triangulacion normal*/ xn=(y[j]-y[i]*z[k]-z[i])-(y[k]-y[i]*z[j]-a[i]); yn=(x[k]-x[i]*z[j]-z[u])-(x[j]-x[i]*z[k]-z[i]); zn=(x[j]-x[i]*y[k]-y[i])-(x[k]-x[i]*y[j]-y[i]); /*solo examina las caras del boton de la paraboloide zn <0*/ if(flag==(zn<0)) /*para otro punto m*/ for(m=0;m<n;m++) { /*revizar si m se acerca (i,j,k)*/ flag=flag&& ((x[m]-x[i]*xn+ (y[m]-y[i]*yn+ (z[m]-z[i]*zn<=0; if(flag) printf("%d\t%d\t%d\n",i,j,k);+ } } La estructura O (n4) del cdigo es evidente yo los cuatro de para lazos anidados. Para cada triple de puntos (i, j, k), el programa revisa y ve si todos los otros puntos m estn o por encima del plano conteniendo i, j, y k. Si es as, (i, j, k) es salida como tringulo Delaunay. (La smil arridad para el algoritmo del buque de dos dimensiones en Algoritmo 3.2 debera ser evidente).

Juan Carlos Gutirrez Barquero____________________________________________

219

Bismarck Salvador Traa Lpez__________________________________________ UNI


Triang. de Delaunay dual.

La prueba de por encima de plano es realizada chocheando la orientacin exterior normal para el tringulo, (xn, yn, zn), con un vector de punto para apuntar m. Aunque es interesante para ver tal cdigo sucinto computar un propsito guste la triangulacin Delaunay, es imprctica para varias razones: 1. El cdigo devuelve todos los tringulos dentro de una cara de triangulacin Delaunay cuyo lmite consta de cuatro o ms puntos del cocircular. As una mueca cuadrada resulta en salida cuatro de tringulo, representando las dos triangulaciones del cuadrado. Obtener ms salida til requerira el postprocesamiento. 2. Hay ineficiencias obvias en el cdigo (por ejemplo, la m-loop podra quebrarse cuando un punto es descubierto debajo del plano del I, j, k). Estos podran repararse fcilmente al precio de alargarle un poco, pero

3. La dependencia de tiempo del n4 es inaceptable. Pues dos prueban

carreras con n = 100 y n = 200 puntos, el tiempo de computar fue 12 y 239 segundos respectivamente, exhibiendo un ms de 24 incremento de 16 pliegues para el doble nmero de puntos. Esto indica 1,000 tan n tomaba varios das.

Triangulacin de Delaunay 3D cscara: O (el n2) el Cdigo Es una tarea fcil convertir el cdigo cuadrtico desarrollado en Captulo 4 para construir el buque del 3D en el cdigo cuadrtico para construir la triangulacin Delaunay. Toda la complejidad est en el cdigo del buque (cdigo de casi 1,000 lneas de ) acerca del razonamiento que entr en Teorema 5.7.2. Las modificaciones adicionales son relativamente menores.

Juan Carlos Gutirrez Barquero____________________________________________

220

Bismarck Salvador Traa Lpez__________________________________________ UNI


Primer, que la rutina ReadVertices (cdigo 4.10) debera leer en x, y y computar z= x2 +y2. En segundo lugar, despus del buque entero se forja, un procedimiento LowerFaces se siente llamado al lazo sobre todas las fases e identifique cules es en la carena (cdigo 5.2). Como en cdigo secreto 5.1, este est consumado computando las coordenadas de la z de un vector normal para cada f de la cara. Esta computar, encarnado en Normz, es justamente un cambio leve para Collinear (Cdigo 4.12). Si Normz (f) < z, entonces la cara est en la carena, y su proyeccin encima del Plano x y es un tringulo de Delaunay. Ilustramos con un ejemplo de n = 10 puntos cuyas coordenadas son ostentadas en la tabla 5.1. Note que las coordenadas de la z son infundidas arriba en la magnitud cuadrando. Esta parte pequea que el ejemplo detiene adecuadamente dentro del rango seguro de la computar de volumen discuti comparacin para el cdigo del buque del 3D. La salida Postscript del cdigo es mostrada en Figure 5.29. Como esperada, esta implementacin O (n2) es mucho ms rpida que el cdigo O (n4): En la misma n = 100 y n = 200 ejemplos que mientras cdigo ms lento us 12 y 239 segundos, el cdigo ms rpido usaron 0.2 y 1.3 segundos respectivamente. Adems, la aceleracin del randomizadas discuti en Seccin 4.5 vueltas as de en una O (n log n) esperado algoritmo de tiempo. 5.7.5 Ejercicio 1. El rango de dt2.c [programacin] . Encuentro un grupo del punto cuyas coordenadas son tan pequeas como sea posible, y para las cuales el cdigo del dt2.c (cdigo 5.2) devuelve un resultado incorrecto debido al derramamiento del clculo de volumen. void LowerFaces(void) { tFace f=faces; int Flower=0; /*numero total*/ do{ if(Normz(f)<0){ Flower++; f->vertex[0]->Vnum, f->vertex[1]->Vnum, f->vertex[2]->Vnum); } f=f->next; }while(f!=faces); printf("%d lower faces identificada\n",Flower); }

Juan Carlos Gutirrez Barquero____________________________________________

221

Bismarck Salvador Traa Lpez__________________________________________ UNI


int Normz (tFaces f) { tvertex a, b, c; a=f->vertex[0]; b=f->vertex[1]; c=f->vertex[2]; return (b->v[x]-a->v[x])*(c->v[x]-a->v[y])(b->v[y]-a->v[y])-(c->v[x]-a->v[x]); } 2. D V (P) (P) [programacin] . Modifique el cdigo del dt2.c para computar el diagrama de Voronoi de la triangulacin de Delaunay. (Vea ejercicio 5.5.6 [1]). Hay que repetidamente construir crculos a travs de tres puntos dadas a, b, c. Las coordenadas de la p central = (p0, p1) pueden ser computadas como sigue: A = b0 a0, B= b1 a1, C = c0 a0, D = c1 a1, E = A(a0 + b0 ) + B(a1 + b1 ), F = C(a0 + b0 ) + D(a1 + b1 ), G = 2(A(c1 b1 ) B(c0 b0 )), p0 = (DE BF)/G, p1 = (AF CE)/G. Tabla 5.1 Coordenadas de sitios de Delaunay, Incluyendo z= x2 +y2 I 0 1 2 3 4 5 6 7 8 X 31 -13 -63 -5 87 40 23 64 0 Y -76 21 -83 -66 -94 71 -46 -80 -57 X2+y2 6737 610 10858 4381 16405 6641 2645 10496 3249

Juan Carlos Gutirrez Barquero____________________________________________

222

Bismarck Salvador Traa Lpez__________________________________________ UNI


9 -14 2 200

5.8 Conexin a arreglos Tenemos que mostrar que la triangulacin de Delaunay puede ser derivada de la transformacin paraboloide e indican que es fcil de obtener el diagrama de Voronoi si es posible obtener el diagrama de Voronoi directamente de la transformacin del paraboloide. Aunque todo esto se entiende que tienes que esperar al siguiente capitulo (Seccin 6.7) y mostraremos la conexin que se realiza utilizando las ecuaciones mas relevante. 5.8.1 Diagrama de Voronoi unidimensional Considerando dos tangentes examinadas en la seccin 5.7.1 (ecuacin 5.4) siendo x=a y otro siendo x=b: z=2ax-a2 z=2bx b2 Donde se intersecan resolviendo las ecuaciones simultneas la solucin sera 2ax-a2 = 2bx b2, x(2a 2b)=a2 b2, x=(a+b)(a-b) 2(a-b) x= a+b 2 De esta manera la proyeccin de las intersecciones estn adyacentes al diagrama de Voronoi y al grupo de puntos

5.8.2 Diagrama de Voronoi bidimensinal

Juan Carlos Gutirrez Barquero____________________________________________

223

Bismarck Salvador Traa Lpez__________________________________________ UNI


Considere dos tangentes planas del paraboloide analizado en la Seccion (5.7.2) (ecuacin 5.8), donde estan a y b y otra donde esta c y b. z = 2ax + 2by a2 + b 2, z = 2cx + 2dy c2 + d2 donde estn los intersectos? Resolviendo la ecuacin simultanea 2ax + 2by a2 + b 2 = 2cx + 2dy c2 + d2 x(2a 2c) + y(2b 2d) = ( a2 - c 2) + (a2 + b 2 ) Esta ecuacin es precisamente la bisectriz perpendicular del segmento de (a,b) y (c,d) ver figura 5.31. Si observamos las tangentes opacas planas de z=+infinito (con el paraboloide transparente) debera ser visible en la primera interseccin su primera interseccin es la bisectriz entre los lugares que generan las tangentes planas la proyeccin de estas primeras tangentes es precisamente el diagrama de voronoi! Tambin tenemos que recordar la situacin al visualizar la proyeccin de puntos dentro del paraboloide de z=-infinito vea la triangulacin de Delaunay la observacin de las tangentes planas del paraboloide y estos puntos de z=+infinito vea el diagrama de Voronoi.

Bibliografa [1] M. Berg, M. Kreveld, M. Overmars, O. Schwarzkopf. Computational Geometry, Algorithms and Applications. Springer, 1997. [2] M. Kreveld, J. Nievergelt, T. Roos, P. Widmayer. Algorithmic Foundations of Geographic Information Systems. Springer, 1997. [3] J. O'Rourke. Computational Geometry in C. Cambridge University Press, 1994. [4] F. P. Preparata y M. I. Shamos. Computational geometry: an introduction. Springer-Verlag, New York, 1985. 73

Juan Carlos Gutirrez Barquero____________________________________________

224

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