Sei sulla pagina 1di 225

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

linesettingstype
palettetype

textsettingstype
viewporttype

errores
fuentes
lnea

modos
put_op
trama

Entre los macros se encuentran:


colores
drivers
enlazar

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

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

Juan Carlos Gutirrez Barquero____________________________________________

Bismarck Salvador Traa Lpez__________________________________________UNI


Color del modo CGA
Nmero Paleta

Color 1

CGA_LIGHT
GREEN

Verde Claro

CGA_LIGHTRED

Rojo Claro

CGA_YELLOW

Amarillo

CGA_LIGHT
CYAN
CGA_GREE
N
CGA_CYAN

Can Claro

CGA_LIGHTMAGENTA

Magenta Claro

CGA_WHITE

Blanco

Verde

CGA_RED

Rojo

CGA_BROWN

Marrn

Can

CGA_MAGENTA

Magenta

CGA_LIGHTGRAY

Gris Claro

2
3

Significado

Color 2

Significado

Color 3

Significado

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

Juan Carlos Gutirrez Barquero____________________________________________

Bismarck Salvador Traa Lpez__________________________________________UNI

Fuentes:
Fuentes para Texto
Constante
DEFAULT_FONT

Valor
0

Valor

TRIPLEX_FONT

Fuente escalable de tipo triple

SMALL_FONT
SANS_SERIF_FONT

2
3

Fuente escalable pequea


Fuente escalable de tipo sans serif

GOTHIC_FONT
SCRIPT_FONT

4
5

Fuente escalable de tipo gtico


Fuente escalable de tipo manuscrito

SIMPLEX_FONT
TRIPLEX_SCR_FONT

6
7

Fuente escalable de tipo manuscrito simple


Fuente escalable de tipo manuscrito triple

COMPLEX_FONT
EUROPEAN_FONT

8
9

Fuente escalable de tipo complejo


Fuente escalable de tipo europeo

BOLD_FONT

10

Fuente escalable en negrita

Fuente bitmap de 8x8

Direccin del Texto


Constante

Valor

Significado

HORIZ_DIR

Texto horizontal

VERT_DIR

Texto vertical

Justificacin de Texto en la Horizontal


Constante

Valor

Significado

LEFT_TEXT

Justificar a la izquierda

CENTER_TEXT

Centrar el texto

RIGHT_TEXT

Justificar a la derecha

Justificacin de Texto en la Vertical


Constante

Valor

Significado

BOTTOM_TEXT
CENTER_TEXT

0
1

Justificar debajo
Centrar el texto

TOP_TEXT

Justificar arriba

Juan Carlos Gutirrez Barquero____________________________________________

Bismarck Salvador Traa Lpez__________________________________________UNI

Tramas:
Tramas predefinidas
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

Juan Carlos Gutirrez Barquero____________________________________________

Bismarck Salvador Traa Lpez__________________________________________UNI


Grosores para Lneas
Constante Grosor

Valor

Modos de Escritura

Significado

NORM_THICK

Grosor es de 1 pxel

THICK_WIDTH

Grosor es de 3
pxeles

Constantes

Valor

COPY_PUT

XOR_PUT

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

MCGA

EGA
EGA64
EGAMONO
VGA

ATT400

HERC

Modo/Constante
CGAC0
CGAC1
CGAC2
CGAC3
CGAHI
MCGAC0
MCGAC1
MCGAC2
MCGAC3
MCGAMED
MCGAHI
EGALO
EGAHI
A64LO
EGA64HI
AMONOHI

0
1
2
3
4
0
1
2
3
4
5
0
1
0
1
3

Cdigo

Resolucin
320X200
320X200
320X200
320X200
640X200
320X200
320X200
320X200
320X200
640X200
640X480
640X200
640x350
640X200
640X350
640x200

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

VGALO
VGAMED
VGAHI
ATT400C0
ATT400C1
ATT400C2
ATT400C3
ATT400MED
ATT400HI
HERCMONOHI
PC3270HI
IBM8514LO
IBM8514HI

0
1
2
0
1
2
3
4
5
0
0
0
1

640X200
640x350
640X480
320x200
320x200
320x200
320x200
640x400
640x400
720X348
720X350
640X480
1024X768

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

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

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

Juan Carlos Gutirrez Barquero____________________________________________

Bismarck Salvador Traa Lpez__________________________________________UNI

Errores:
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

Valor
0

Significado
Sobrescribir los pxeles existentes

XOR_PUT

Operacin OR Exclusivo con los pxeles

OR_PUT
AND_PUT

2
3

Operacin OR Inclusivo con los pxeles


Operacin AND con los pxels

NOT_PUT

Invertir la imagen

Nota: Estas operaciones se usan exclusivamente con la funcin putimage. El cual


veremos en captulos posteriores.

Juan Carlos Gutirrez Barquero____________________________________________

Bismarck Salvador Traa Lpez__________________________________________UNI

Mtodos de Inicializacin del modo grafico.


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.

Juan Carlos Gutirrez Barquero____________________________________________

Bismarck Salvador Traa Lpez__________________________________________UNI

1. Mtodo de inicializacin del modo grafico a prueba de errores.


#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.

Juan Carlos Gutirrez Barquero____________________________________________

10

Bismarck Salvador Traa Lpez__________________________________________UNI

Qu son los primitivos grficos?


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.

Juan Carlos Gutirrez Barquero____________________________________________

11

Bismarck Salvador Traa Lpez__________________________________________UNI


Ejemplo:
#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();
}

Juan Carlos Gutirrez Barquero____________________________________________

14

Bismarck Salvador Traa Lpez__________________________________________UNI


ELIPSES.
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.

Juan Carlos Gutirrez Barquero____________________________________________

15

Bismarck Salvador Traa Lpez__________________________________________UNI


Ejemplo:
#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 */

Juan Carlos Gutirrez Barquero____________________________________________

17

Bismarck Salvador Traa Lpez__________________________________________UNI


closegraph();
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 };

Juan Carlos Gutirrez Barquero____________________________________________

20

Bismarck Salvador Traa Lpez__________________________________________UNI


char trama2[8] = { 0x0A, 0xF0, 0xF0, 0x0A, 0x0A, 0xF0, 0xF0, 0x0A };
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

Juan Carlos Gutirrez Barquero____________________________________________

23

Bismarck Salvador Traa Lpez__________________________________________UNI


direccin vertical. Estos valores pueden ser positivos o negativos. No se dibuja ya que el
cursor es mudado.
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();
}

Juan Carlos Gutirrez Barquero____________________________________________

24

Bismarck Salvador Traa Lpez__________________________________________UNI


Funcin getx.
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 );
}

Juan Carlos Gutirrez Barquero____________________________________________

25

Bismarck Salvador Traa Lpez__________________________________________UNI

Otras funciones de la librera graphics.h.


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();
}

Juan Carlos Gutirrez Barquero____________________________________________

26

Bismarck Salvador Traa Lpez__________________________________________UNI


Funcin clearviewport
void far clearviewport(void);
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();
}

Juan Carlos Gutirrez Barquero____________________________________________

27

Bismarck Salvador Traa Lpez__________________________________________UNI

Funcin detectgraph
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.

Juan Carlos Gutirrez Barquero____________________________________________

28

Bismarck Salvador Traa Lpez__________________________________________UNI


Ejemplo:
#include <graphics.h>
#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" );
}

Juan Carlos Gutirrez Barquero____________________________________________

29

Bismarck Salvador Traa Lpez__________________________________________UNI


Funcin getarccords
void far getarccoords(struct arccoordstype far *coordenadas_arco);
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

Juan Carlos Gutirrez Barquero____________________________________________

30

Bismarck Salvador Traa Lpez__________________________________________UNI


*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
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();

Juan Carlos Gutirrez Barquero____________________________________________

31

Bismarck Salvador Traa Lpez__________________________________________UNI


printf( "Color del permetro: %d\n", color );
getch();
}
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();
}

Juan Carlos Gutirrez Barquero____________________________________________

32

Bismarck Salvador Traa Lpez__________________________________________UNI


Funcin getdrivename
char *far getdrivername(void);
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" );

Juan Carlos Gutirrez Barquero____________________________________________

33

Bismarck Salvador Traa Lpez__________________________________________UNI


getfillpattern( trama2 );
bar( 50, 50, 150, 150 );
setfillpattern( trama1, 9 );
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();
}

Juan Carlos Gutirrez Barquero____________________________________________

34

Bismarck Salvador Traa Lpez__________________________________________UNI


Funcin getgraphmode
int far getgraphmode(void);
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.

Juan Carlos Gutirrez Barquero____________________________________________

35

Bismarck Salvador Traa Lpez__________________________________________UNI


La funcin getlinesettings no retorna ningn valor, directamente.
Ejemplo:
#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();
}

Juan Carlos Gutirrez Barquero____________________________________________

36

Bismarck Salvador Traa Lpez__________________________________________UNI


Funcin getmodename
char *far getmodename(int num_modo);
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;

Juan Carlos Gutirrez Barquero____________________________________________

37

Bismarck Salvador Traa Lpez__________________________________________UNI


initgraph( &driver, &modo, C:\\TC20\\BIN );
getmoderange( driver, &modo_bajo, &modo_alto );
closegraph();
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();
}

Juan Carlos Gutirrez Barquero____________________________________________

38

Bismarck Salvador Traa Lpez__________________________________________UNI


Funcin getpalettesize
int far getpalettesize(void);
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();

Juan Carlos Gutirrez Barquero____________________________________________

39

Bismarck Salvador Traa Lpez__________________________________________UNI


closegraph();
printf( "Colores\n\nEl color del pxel (%d,%d): %d\n", x, y, color );
getch();
}
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

Juan Carlos Gutirrez Barquero____________________________________________

40

Bismarck Salvador Traa Lpez__________________________________________UNI


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:
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 );

Juan Carlos Gutirrez Barquero____________________________________________

41

Bismarck Salvador Traa Lpez__________________________________________UNI


setviewport( 250, 150, 350, 250, 1 );
graphdefaults();
circle( 300, 200, 50 );
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.

Juan Carlos Gutirrez Barquero____________________________________________

42

Bismarck Salvador Traa Lpez__________________________________________UNI


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 );
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 ) {

Juan Carlos Gutirrez Barquero____________________________________________

43

Bismarck Salvador Traa Lpez__________________________________________UNI


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 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();
}

Juan Carlos Gutirrez Barquero____________________________________________

44

Bismarck Salvador Traa Lpez__________________________________________UNI

Funcin installuserdriver
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

Juan Carlos Gutirrez Barquero____________________________________________

46

Bismarck Salvador Traa Lpez__________________________________________UNI


Ejemplo:
#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 );

Juan Carlos Gutirrez Barquero____________________________________________

47

Bismarck Salvador Traa Lpez__________________________________________UNI


outtext( mensaje );
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

Valor
0

Significado
Sobrescribir los pxeles existentes

XOR_PUT

Operacin OR Exclusivo con los pxeles

OR_PUT
AND_PUT

2
3

Operacin OR Inclusivo con los pxeles


Operacin AND con los pxels

NOT_PUT

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.

Capitulo I. Inicializacin del modo grfico.

Introduccin.

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.
En un ciclo se suele determinar por el nmero de iteraciones
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:

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 algoritmos
aleatorios. Puede emplearse para construir la envolvente convexa, el diagrama
de Voronoi, etc.

Juan Carlos Gutirrez Barquero____________________________________________ 154

Bismarck Salvador Traa Lpez__________________________________________UNI

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
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

Juan Carlos Gutirrez Barquero____________________________________________ 155

Bismarck Salvador Traa Lpez__________________________________________UNI


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
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

Juan Carlos Gutirrez Barquero____________________________________________ 156

Bismarck Salvador Traa Lpez__________________________________________UNI


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
4.
Si Pk no est a la izqda de (Pi,Pj)
5.
entonces (Pi,Pj) no es extremo

Juan Carlos Gutirrez Barquero____________________________________________ 157

Bismarck Salvador Traa Lpez__________________________________________UNI

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
3. devolver concatenar(QuickHull(a,b,izquierda(a,b,S)),
QuickHull(b,a,izquierda(b,a,S)))

Juan Carlos Gutirrez Barquero____________________________________________ 158

Bismarck Salvador Traa Lpez__________________________________________UNI


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, | p1x | = | 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 pi que a pj. Ahora ordene el
regreso de que V (pi) es el grupo de todos los puntos ms cercano a pi 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) =

H (pi, pj)

(ecuacin 5.2)

i j

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 (p1), 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
EMBED

Equation.3 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

Juan Carlos Gutirrez Barquero____________________________________________ 192

Bismarck Salvador Traa Lpez__________________________________________UNI


diagrama Voronoi puede ser computado usando nuestro cdigo del buque
convexo.
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 (n2) 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

Juan Carlos Gutirrez Barquero____________________________________________ 194

Bismarck Salvador Traa Lpez__________________________________________UNI


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.
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 p1p2. 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.

Juan Carlos Gutirrez Barquero____________________________________________ 195

Bismarck Salvador Traa Lpez__________________________________________UNI


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
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 106 (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

Juan Carlos Gutirrez Barquero____________________________________________ 196

Bismarck Salvador Traa Lpez__________________________________________UNI


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
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

Juan Carlos Gutirrez Barquero____________________________________________ 197

Bismarck Salvador Traa Lpez__________________________________________UNI


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
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

Juan Carlos Gutirrez Barquero____________________________________________ 198

Bismarck Salvador Traa Lpez__________________________________________UNI


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

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:

Juan Carlos Gutirrez Barquero____________________________________________ 199

Bismarck Salvador Traa Lpez__________________________________________UNI

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
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

Juan Carlos Gutirrez Barquero____________________________________________ 200

Bismarck Salvador Traa Lpez__________________________________________UNI


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

Juan Carlos Gutirrez Barquero____________________________________________ 203

Bismarck Salvador Traa Lpez__________________________________________UNI

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.

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

Juan Carlos Gutirrez Barquero____________________________________________ 204

Bismarck Salvador Traa Lpez__________________________________________UNI


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
Ii + 1
El algoritmo 5.2 el algoritmo de Kruskal.
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 (n 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.
2

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

Juan Carlos Gutirrez Barquero____________________________________________ 205

Bismarck Salvador Traa Lpez__________________________________________UNI


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

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.

Juan Carlos Gutirrez Barquero____________________________________________ 206

Bismarck Salvador Traa Lpez__________________________________________UNI


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.

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,

Juan Carlos Gutirrez Barquero____________________________________________ 207

Bismarck Salvador Traa Lpez__________________________________________UNI


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.
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
optativo para cualquier
> 0, en un tiempo O (np), dnde la p son
proporcionales para 1/ . Vea a Arora (1996) y Mitchell (1996).
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).

Juan Carlos Gutirrez Barquero____________________________________________ 208

Bismarck Salvador Traa Lpez__________________________________________UNI


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
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 | }.
mi . 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

Juan Carlos Gutirrez Barquero____________________________________________ 209

Bismarck Salvador Traa Lpez__________________________________________UNI


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).

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?

Juan Carlos Gutirrez Barquero____________________________________________ 210

Bismarck Salvador Traa Lpez__________________________________________UNI


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
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

Juan Carlos Gutirrez Barquero____________________________________________ 211

Bismarck Salvador Traa Lpez__________________________________________UNI


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

Juan Carlos Gutirrez Barquero____________________________________________ 217

Bismarck Salvador Traa Lpez__________________________________________UNI


Un corolario til para el debate citado anteriormente es ste:
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()
{

Juan Carlos Gutirrez Barquero____________________________________________ 218

Bismarck Salvador Traa Lpez__________________________________________UNI


int
int
int
int

x[MAX],y[MAX],z[MAX];
/*Intreda de puntos x,y,z*/
n;
/*Numero dep puntos introducidos*/
i,j,k,m;
/*induce de cuatro puntos*/
flag;
/*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

Juan Carlos Gutirrez Barquero____________________________________________ 220

Bismarck Salvador Traa Lpez__________________________________________UNI


Teorema 5.7.2. Las modificaciones adicionales son relativamente menores.
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

X
31
-13
-63
-5
87
40
23
64

Y
-76
21
-83
-66
-94
71
-46
-80

X2+y2
6737
610
10858
4381
16405
6641
2645
10496

Juan Carlos Gutirrez Barquero____________________________________________ 222

Bismarck Salvador Traa Lpez__________________________________________UNI


8
9

0
-14

-57
2

3249
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

Juan Carlos Gutirrez Barquero____________________________________________ 223

Bismarck Salvador Traa Lpez__________________________________________UNI

5.8.2 Diagrama de Voronoi bidimensinal


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.

Juan Carlos Gutirrez Barquero____________________________________________ 224

Bismarck Salvador Traa Lpez__________________________________________UNI


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____________________________________________ 225

Potrebbero piacerti anche