Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
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()
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
linesettingstype
palettetype
textsettingstype
viewporttype
errores
fuentes
lnea
modos
put_op
trama
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.
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
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.
Valor
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Constante (EGA/VGA)
EGA_BLACK
EGA_BLUE
EGA_GREEEN
EGA_CYAN
EGA_RED
EGA_MAGENTA
EGA_LIGHTGRAY
EGA_BROWN
EGA_DARKGRAY
EGA_LIGHTBLUE
EGA_LIGHTGREEN
EGA_LIGHTCYAN
EGA_LIGHTRED
EGA_LIGHTMAGENTA
EGA_YELLOW
EGA_WHITE
Valor
0
1
2
3
4
5
7
20
56
57
58
59
60
61
62
63
Nota: Estas constantes se usan con las Funciones setpalette y setallpalette.el cual
veremos en captulos posteriores
Fuentes:
Fuentes para Texto
Constante
DEFAULT_FONT
Valor
0
Valor
TRIPLEX_FONT
SMALL_FONT
SANS_SERIF_FONT
2
3
GOTHIC_FONT
SCRIPT_FONT
4
5
SIMPLEX_FONT
TRIPLEX_SCR_FONT
6
7
COMPLEX_FONT
EUROPEAN_FONT
8
9
BOLD_FONT
10
Valor
Significado
HORIZ_DIR
Texto horizontal
VERT_DIR
Texto vertical
Valor
Significado
LEFT_TEXT
Justificar a la izquierda
CENTER_TEXT
Centrar el texto
RIGHT_TEXT
Justificar a la derecha
Valor
Significado
BOTTOM_TEXT
CENTER_TEXT
0
1
Justificar debajo
Centrar el texto
TOP_TEXT
Justificar arriba
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
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
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
OR_PUT
AND_PUT
2
3
NOT_PUT
Invertir la imagen
10
11
12
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.
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.
13
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();
}
14
#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();
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.
15
16
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 */
17
18
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
19
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.
20
/*Este programa te muestra los diferentes colores con una misma trama trata de
modificarlo para que obtengas todas las tramas con todos los colores*/
21
22
23
24
25
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();
}
26
27
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.
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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.
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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.
64
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 */
65
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;
};
66
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();
}
67
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
68
69
70
Valor
0
Significado
Sobrescribir los pxeles existentes
XOR_PUT
OR_PUT
AND_PUT
2
3
NOT_PUT
Invertir la imagen
71
72
73
74
75
76
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.
77
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.
78
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.
79
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);
80
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);
81
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();
}
82
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.
83
84
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;
85
86
/******************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)
87
88
89
# 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)
{
90
setcolor(BROWN);
rectangle(30,365,110,400);
setfillstyle(SOLID_FILL,BROWN);
floodfill(50,385,BROWN);
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);
91
92
93
94
95
96
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.
97
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
98
99
Introduccin.
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:
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++){
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);
struct valor_rgb {
unsigned char azul;
unsigned char verde;
unsigned char rojo;
unsigned char reservado;
};
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 */
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 */
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;
}
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);
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
*/
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);
*/
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);
tecla=IZQUIERDA;
if(kbhit())
{
tecla=getch();
}
setfillstyle(1,0);
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);
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");
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();
}
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*/
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);
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++;
}
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;
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.
1.3.
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.
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
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.
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 ) ) )
}
return TRUE;
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.
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.
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
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 )
Complejidad: O(n3 )
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.
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
Triangulacin de polgonos
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
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 )
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:
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.
APLICACIONES PRELIMINARES
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
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
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.
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
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
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.
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
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.
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.
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)
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.
Ejercicios
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()
{
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)*/
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
0
-14
-57
2
3249
200