Professional Documents
Culture Documents
En este pequeño tutor solo haremos énfasis en estas librerías, puesto que al final del libro
se encuentran las demás librerías que comúnmente encontramos con frecuencia en el
programa.
Muchos libros nos marean dándonos conceptos los cuales se aprenden conforme
programando; esto no significa, que no sean importan tantees los ejercicios que aquí te
enseñamos te ayudaran a darte todo el conocimiento así como también te los daremos
conforme avancemos así que dejemos de hablar y aventurémonos en el mundo de la
programación 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 versión
de video instalada. En el modo grafico estas dimensiones cambian dependiendo del tipo de
macro de inicialización se realice(ver Macro modos). Quedando la mas común de 640X480
modo VGA.
A la hora de desarrollar un programa gráfico se debe tener en cuenta los siguientes cuatro
puntos:
# include<graphics.h>
closegraph() o restorecrtmode()
Otra de las cosas importantes que debemos saber es que Funciones contiene graphics.h
Funciones de Graphics.h
Esta librería se encuentra los prototipos de las Funciones que manipulan la parte gráfica
en el entorno de MS-DOS.
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 más efectiva
nuestros gráficos.
Colores :
Colores de Fondo
Modo de 16 Colores
Valor asignado: 1 2 3
Nota: Color 0 se reserva para el color de fondo y se asigna con lo función setbkcolor, pero
los demás colores son fijos. Estas constantes se usan con setcolor.
Nota: Estas constantes se usan con las Funciones setpalette y setallpalette.el cual
veremos en capítulos posteriores
Fuentes:
Fuentes para Texto
Tramas:
Tramas predefinidas
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 Gráficos
Dispositivo/Constante Valor
DETECT 0
CGA 1
MCGA 2
EGA 3
EGA64 4
EGAMONO 5
IBM8514 6
HERCMONO 7
ATT400 8
VGA 9
PC3270 10
Líneas:
Estilos de Líneas
Modos:
Modos Gráficos
Errores:
Códigos de Errores
Put_op:
Operaciones con putimage
Función initgraph
void far initgraph(int far *driver, int far *modo, int far *path);
Esta función es usada para cargar o validar un dispositivo gráfico y cambiar el sistema de
vídeo a modo gráfico. La función initgraph debe ser llamada antes de cualesquier
Funciónes que generan una salida gráfica sean usadas. Existen varios valores a ser
usados para el argumento *driver. Si *driver es asignado a DETECT, ó 0, la
función detectgraph es llamada, y un dispositivo y modo gráfico apropiados son
seleccionados. Asignando a *driver cualquier otro valor predefinido inicia la carga del
dispositivo gráfico correspondiente. Existen varios valores a ser usados para el argumento
*modo. Estos valores deberían corresponder al dispositivo especificado en el argumento
*driver. El argumento *path especificad el directorio donde los dispositivos gráficos están
localizados. La función initgraph buscará el dispositivo primeramente en este directorio. Si
no es encontrado, la función 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 función initgraph no retorna ningún valor. Sin embargo, cuando la función initgraph es
llamada, el código de error interno es activado. Si la función initgraph termina con éxito, el
código es asignado un 0. Si no, el código es asignado así:
-2 grNotDetected La tarjeta gráfica no se encontró
-3 grFileNotFound El fichero del dispositivo no se encontró
-4 grInvalidDriver El fichero del dispositivo es inválido
-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 métodos de inicialización pero en este pequeño tutorial trataremos dos
que suelen ser los más utilizados hoy en día.
#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
#include <graphics.h>
void main() {
int driver = DETECT,modo;
initgraph(&driver,modo,” c:\\tc20\\bin”);
cuerpo del programa
modo: Es la dirección de la variable que contiene el código del modo en que se podrá
adaptar.
DETECT: Dispositivo grafico de auto detección del la tarjeta de video y del modo grafico.
Rasterop: Es una operación grafica que copia el área de una imagen para luego
dibujarla en cualquier región de la pantalla.
Texto Gráfico: Sirve para escribir texto en modo grafico, utilizando diferentes
fuentes.
Figuras geométricas:
LINEAS.
void far line(int x1, int y1, int x2, int y2);
Esta función es usada para conectar dos puntos con una línea recta. El primer punto es
especificado por los argumentos x1 e y1. El segundo punto es especificado por los
argumentos x2 e y2. La línea se dibuja usando el estilo de línea actual, el grosor, y el color
actual. La posición del cursor gráfico no es afectada por la función line.
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.
Esta función se utiliza para dibujar un círculo. Los argumentos x e y definen el centro del
círculo, mientras que el argumento radio define el radio del círculo. El círculo no es
rellenado pero es dibujado usando el color actual.
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();
}
RECTANGULOS.
Esta función dibujará un rectángulo sin rellenar su interior usando el color actual. La
esquina superior izquierda del rectángulo 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 rectángulo. El perímetro del rectángulo es dibujado usando el estilo y grosor
de línea actuales.
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 función 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 dirección contraria al
de las agujas del reloj hasta llegar al ángulo especificado por el argumento final_angulo.
La función arc usa el este (extendiéndose hacia la derecha del centro del arco en la
dirección horizontal) como su punto de 0 grados. La función setlinestyle puede usarse
para establecer el grosor del arco. La función arc, sin embargo, ignorará el argumento
trama de la función setlinestyle.
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.
Esta función es usada para colocar a un píxel en una posición en particular la cual es
cuestionada por los argumentos x e y. El argumento color específico el valor del color del
píxel.
Ejemplo:
#include <graphics.h>
#include <conio.h>
void main() {
int driver = EGA,modo = EGAHI,t;
initgraph( &driver, &modo, “c:\\tc20\\bin” );
for( t=0; t<200; t++ )
putpixel( 100+t, 50+t, t%16 );
getch();
closegraph();
}
ELIPSES.
void far ellipse(int x, int y, int comienzo_angulo, int final_angulo, int x_radio, int y_radio);
Esta función es usada para dibujar un arco elíptico en el color actual. El arco elíptico está
centrado en el punto especificado por los argumentos x e y. Ya que el arco es elíptico el
argumento x_radio especifica el radio horizontal y el argumento y_radio especifica el radio
vertical. El arco elíptico 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 función ellipse considera este - el eje
horizontal a la derecha del centro del elipse - ser 0 grados. El arco elíptico es dibujado con
el grosor de línea actual como es establecido por la función setlinestyle. Sin embargo, el
estilo de línea es ignorado por la función ellipse.
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();
}
Función setbkcolor
Esta función 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.
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();
}
Función getbkcolor.
Esta función 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
función setbkcolor. Existen varios valores para ciertos colores de fondo.
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();
}
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 ejecución del programa durante 30000 milisegundos*/
i=(i<16)?i:0;
i++;
}while(!kbhit());
}
Función cleardevices
Esta función es usada para despejar una pantalla gráfica. La función cleardevice usa el
color de fondo actual, como es establecido por la función setbkcolor, para rellenar la
pantalla. La posición del cursor gráfico es la esquina superior izquierda de la pantalla -
posición (0,0) - después de que la pantalla haya sido borrado.
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 );
Función getmaxx
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 máxima: %d\n", x_max );
getch();
}
Función getmaxy
#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();
Rellenos
Es el proceso de rellenar una región de la pantalla con un patrón o color. Turbo C utiliza
dos métodos para definir la región de rellenos. El primero relleno de polígonos, usa la lista
de vértices del polígono para calcular la geometría del interior, El segundo relleno es por
el método de inundación, 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 píxel que tiene.
Antes de estudiar los dos métodos estudiaremos la función setfillstyle que será de gran
importancia a la hora de realizar los dos tipos de rellenado y bar que es una función
similar a rectangle.
Función bar
void far bar(int izquierda, int superior, int derecha, int inferior);
Esta función 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 función setlinestyle.
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 patrón de relleno se define con las Funciónes setfillstyle y setfillpattern
Función setfillstyle
Esta función 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 debería usarse para asignar una trama
definida por el usuario. En su lugar, se debería usar la función setfillpattern.
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();
}
Función setfillpattern
Esta función 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 píxel correspondiente será asignado el
color de relleno actual. Un bit de 0 indica que el píxel correspondiente no será alterado. El
argumento color especifica el color de relleno que será usado para la trama.
Ejemplo:
#include <graphics.h>
#include <conio.h>
void main() {
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 función fillpoly dibuja
el perímetro del polígono con el estilo de línea y color actuales. Luego, el polígono es
rellenado con la trama de relleno y color de relleno actuales.
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*/
Esta función 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
función 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 función no Funciona con el driver IBM-8514.La función floodfill no retorna
ningún 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();
}
Entre ellas tenemos las Funciónes moveto, moverel, lineto, linerel, getx, gety.
Estudiaremos cada una de ellas para afianzar mas conocimientos.
Función moveto.
Esta función es usada para colocar el cursor gráfico al punto especificado por los
argumentos x e y. Ya que el cursor es movido desde su posición anterior al punto
especificado por los argumentos x e y, no hay dibujo alguno.
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();
}
Función lineto.
Esta función es usada para dibujar una línea recta desde la posición actual del cursor
gráfico hasta el punto especificado por los argumentos x e y. La línea se dibuja usando el
estilo de línea actual, el grosor, y el color actual. Después de que la línea recta haya sido
dibujado, la posición del cursor gráfico es actualizado a la posición especificado por los
argumentos x e y (el punto final de la línea).
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();
}
Función moverel.
Esta función es usada para mover la posición del cursor gráfico a una distancia relativa
como los argumentos dx y dy. El argumento dx define la distancia relativa a moverse en
la dirección horizontal. El argumento dy define la distancia relativa a moverse en la
dirección vertical. Estos valores pueden ser positivos o negativos. No se dibuja ya que el
cursor es mudado.
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();
}
Función linerel.
Esta función es usada para dibujar una línea recta a una distancia y dirección
predeterminadas desde la posición actual del cursor gráfico. El argumento dx especifica el
número relativo de píxels para atravesar en la dirección horizontal. El argumento dy
especifica el número relativo de píxels para atravesar en la dirección vertical. Estos
argumentos pueden ser tanto valores positivos como negativos. La línea se dibuja usando
el estilo de línea actual, el grosor, y el color actual desde la posición actual del cursor
gráfico a través de la distancia relativa especificada. Cuando la línea esté terminada, la
posición del cursor gráfico es actualizado al
último punto de la línea.
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();
Función getx.
Esta función es usada para obtener la posición, en la dirección horizontal, del cursor
gráfico. El valor retornado especifica el lugar del píxel horizontal del cursor gráfico (la
coordenada x), relativo a la pantalla del usuario actual.
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 gráfico\n\nX: %d\tY: %d\n", x, y );
}
Función gety.
Esta función es usada para obtener la posición, en la dirección vertical, del cursor gráfico.
El valor retornado especifica el lugar del píxel vertical del cursor gráfico (la coordenada y),
relativo a la pantalla del usuario actual.
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 gráfico\n\nX: %d\tY: %d\n", x, y );
}
En este capitulo describimos una a una las librerías de la librería graphics.h. Las funciones
serán explicadas mediante un orden.
Cuando sabemos como dibujar líneas, círculos, rectángulos, 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.
Función bar3d
void far bar3d(int izquierda, int superior,int derecha, int inferior, int profundidad, int banderin_tapa);
Esta función creará una barra rectangular y rellenada de tres dimensiones. La esquina
superior izquierda de la barra rectangular más frontal está definida por los argumentos
izquierdos y superiores. Estos argumentos corresponden a los valores x e y de la
esquina superior izquierda del rectángulo más frontal. Similarmente, los argumentos
derecha e inferior definen la esquina inferior derecha del rectángulo más frontal. La barra
tiene borde, en todas las tres dimensiones, rellenada con el color y estilo de línea
actuales. El rectángulo más frontal es rellenado usando la trama de relleno actual y el
color de relleno como es establecido por la función 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.
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();
}
Función clearviewport
Esta función es usada para rellenar la pantalla actual del usuario con el color de fondo
actual. El color de fondo puede ser establecido con la función setbkcolor. La posición del
cursor gráfico es la esquina superior izquierda de la pantalla actual del usuario. Esta
posición es (0,0) según la pantalla actual del usuario.
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();
}
Función closegraph
Esta función es usada para cerrar el sistema gráfico como es iniciada por la función
initgraph. La función closegraph libera toda la memoria usada por el sistema gráfico y
luego restaura el modo de vídeo al modo de texto que estaba en uso anteriormente a la
llamada a la función initgraph.
#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();
}
Función detectgraph
Esta función es usada para detectar el adaptador gráfico y el modo óptimo para usar con
el sistema en uso. Si la función detectgraph no puede detectar ningún dispositivo gráfico,
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 gráficos que pueden ser usados por el argumento *driver. Un valor
de 0, o DETECT, inicia la Funciónalidad de auto detección, el cual determina el driver
óptimo a usar. Para cada dispositivo existen varios valores que indican los diferentes
modos gráficos 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
automáticamente establecido al modo de resolución mas alto para el driver.
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();
}
Función drawpoly
Esta función es usada para crear un polígono con un número especificado de puntos. El
argumento numpuntos es usado para definir el número de puntos en el polígono. Para la
función drawpoly, el número de puntos debe ser el número actual de puntos más 1 para
poder crear un polígono cerrado. En otras palabras, el primer punto debe ser igual al último
punto. El argumento *puntos apunta a un array de números 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 función drawpoly dibuja el perímetro del polígono con el
estilo de línea y color actuales, pero no rellena el polígono.
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();
}
Función fillellipse
Esta función 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 perímetro en el color actual y rellenada con el color de relleno y la trama de relleno
actuales.
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" );
}
Función getarccords
Esta función es usada para recoger las coordenadas del centro, y los puntos del comienzo
y final de la última llamada con éxito a la función arc. El argumento *coordenadas_arco
apunta a la estructura de tipo arccoordstype que guarda la información 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.
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();
}
Función getaspectratio
Esta función es usada para obtener la proporción anchura-altura del modo gráfico actual.
La proporción anchura-altura puede definirse como la proporción de la anchura del píxel
del modo gráfico y la altura del píxel. Esta proporción, usando los modos gráficos
existentes, es siempre menor o igual que 1. El valor para determinar la proporción
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( "Proporción anchura-altura.\nFactor x: %d\tFactor y: %d\n",
x_proporcion, y_proporcion );
getch();
}
Función getcolor
Esta función obtiene el valor del color actual. El color actual es el color usado para dibujar
líneas, arcos, etc.. Este color no es el mismo que el color de relleno. El valor del color
obtenido es interpretado según el modo que esté en uso. Existen varios valores para
ciertos colores de fondo.
Ejemplo:
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
void main() {
int driver = EGA;
int modo = EGAHI,color;
initgraph( &driver, &modo, "C:\\Tc20\\BIN" );
setcolor( 4 );
circle( 300, 150, 50 );
color = getcolor();
getch(); /* Pausa */
closegraph();
printf( "Color del perímetro: %d\n", color );
getch();
}
Función getdefaultpalette
Esta función es usada para obtener una estructura que define la paleta según el
dispositivo en la inicialización - 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 tamaño de la paleta. El campo colors contiene los valores
numéricos que representan los colores que ofrece el dispositivo en su paleta de colores.
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\nTamaño: %d\nColores: %d",
palette->size, palette->colors[0] );
for( i=1; i<palette->size; i++ )
printf( ", %d", palette->colors[i] );
printf( "\n" );
getch();
}
Función getdrivename
Esta función es usada para obtener una cadena de caracteres que contiene el nombre del
dispositivo gráfico actual. Esta función debería ser llamada después de que un dispositivo
haya sido definido e inicializado – esto es, después de llamar a initgraph.
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 gráfico: %s\n", nombre );
getch();}
Función getfillpattern
Esta función es usada para obtener una trama de relleno definido por el usuario, como es
definida por la función 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 píxel correspondiente será asignado el color de relleno actual. Un
bit de 0 indica que el píxel correspondiente no será alterado.
Ejemplo:
#include <graphics.h>
#include <conio.h>
void main() {
int driver = EGA;
int modo = EGAHI;
char trama1[8] = { 0x33, 0xEE, 0x33, 0xEE, 0x33, 0xEE, 0x33, 0xEE };
char trama2[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
initgraph( &driver, &modo, "C:\\tc20\\bin" );
getfillpattern( trama2 );
bar( 50, 50, 150, 150 );
setfillpattern( trama1, 9 );
bar( 160, 50, 260, 150 );
setfillpattern( trama2, 4 );
bar( 105, 160, 205, 260 );
getch(); /* Pausa */
closegraph();
getch();
}
Función getfillsettings
struct fillsettingstype {
int pattern;
int color;
};
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();
}
Función getgraphmode
Esta función es usada para obtener el valor del modo gráfico actual. El dispositivo actual
debe ser considerado cuando se interprete el valor de retorno. Esta función sólo debería
ser llamada después de que el sistema gráfico haya sido inicializado con la función
initgraph. Existen varios valores para los modos de cada dispositivo.
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 gráfico: %d\n", modo );
getch();
}
Función getlinesettings
Esta función obtiene la información actual para las líneas. Esta información es guardada
en una estructura de tipo linesettingstype que es apuntado por el argumento *info. El
estilo de línea, trama, y grosor actuales son guardados en esta estructura. La sintaxis
para la estructura linesettingstype:
struct linesettingstype {
int linestyle;
unsigned upattern;
int thickness;
}
thickness es el grosor de la línea. Existen varios valores para los diferentes estilos y
grosores de líneas rectas.
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( "Líneas rectas.\nEstilo: %d\tTrama: %X\tGrosor: %d\n",
info.linestyle, info.upattern, info.thickness );
getch();
}
Función getmaxcolor
Esta función es usada para obtener el valor más 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.
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();
}
Función getmodename
Esta función es usada para obtener el nombre del modo gráfico especificado por el
argumento num_modo.
La función getmodename retorna el nombre del modo gráfico que está contenido en todos
los dispositivos gráficos.
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();
}
Función getmoderange
void far getmoderange(int driver, int far *modo_bajo, int far *modo_alto);
Esta función es usada para obtener los valores altos y bajos del modo gráfico del
dispositivo especificado por el argumento driver. El valor más bajo del modo es retornado
en *modo_bajo, y el valor más alto del modo es retornado en *modo_alto. Si el
dispositivo especificado es inválido, 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.
Ejemplo:
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
void main() {
Función getpalette
#define MAXCOLORS 15
struct palettetype {
unsigned char size;
signed char colors[MAXCOLORS+1];
}
El campo size indica el número de colores en la paleta. El campo colors contiene los
valores numéricos que representan los colores que ofrece el dispositivo en su paleta de
colores.
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\nTama¤o: %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();
}
Función getpalettesize
Esta función es usada para obtener el número de entradas de paleta válidas para la
paleta actual, considerando el modo gráfico en uso.
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\nNúmero de colores: %d\n", num_colores );
getch();
}
Función getpixel
Esta función es usada para obtener el valor del color del píxel especificado por los
argumentos x e y. Estos argumentos especifican las coordenadas de la pantalla del píxel
a ser evaluado. Cuando se evalúa el valor del color retornado, el modo gráfico en uso
debe ser considerado. Existen varios valores para describir colores.
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 );
Función gettextsettings
Esta función es usada para obtener información acerca de la fuente gráfica actual. Esta
información es guardada en una estructura de tipo textsettingstype, la cual es apuntada
por el argumento *info. Esta estructura contiene información de la fuente actual en uso, la
orientación del texto, el tamaño del carácter, y la justificación horizontal y vertical. La
síntaxis de la estructura textsettingstype es la siguiente:
struct textsettingstype {
int font;
int direction;
int charsize;
int horiz;
int vert;
};
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\tTamaño: %d\n""Justificación:\nHorizontal: %d,
Vertical: %d\n",
info.font, info.direction, info.charsize, info.horiz, info.vert);
getch();
}
Función getviewsettings
Esta función es usada para obtener información acerca del área gráfica actual. Esta
información es guardada en una estructura de tipo viewporttype, la cual es apuntada por
el argumento *info. Esta estructura contiene información acerca de las esquinas superior
izquierda e inferior derecha, también como el banderín de recorte del área gráfica. La
síntaxis de la estructura viewporttype es la siguiente:
struct viewporttype {
int left, top;
int right, bottom;
int clip;
};
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\tBander¢n: %d\n",
info.left, info.top, info.right, info.bottom, info.clip );
getch();
}
Función graphdefaults
Esta función es usada para reiniciar todos los datos gráficos a sus valores originales, o
por defecto. La función graphdefaults reinicia la pantalla del usuario para que cubra la
pantalla entera, mueve el cursor a la posición (0,0), y reinicia la paleta actual a sus colores
por defecto. También 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
justificación de texto.
Ejemplo:
#include <graphics.h>
#include <conio.h>
void main() {
int driver = VGA;
Función grapherrormsg
Esta función es usada para obtener una cadena de caracteres conteniendo el mensaje de
error para un código de error especificado. El argumento codigo_error específica el valor
del código de error. La función graphresult debe ser usada para obtener el código de error
usado para el argumento codigo_error.
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();
}
Función graphfreemem
Esta función es usada por la librería gráfica para desadjudicar memoria previamente
reservada mediante una llamada a la función _graphgetmem. Esta función es llamada por
la librería gráfica cuando se quiere liberar memoria. Por defecto, la función simplemente
llama a free, pero se puede controlar la administración de memoria de la librería gráfica.
La forma de hacer esto es simplemente creando la definición de la función, con el mismo
prototipo mostrado aquí.
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 montón (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 montón (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();
}
Función graphgetmem
Esta función es usada por la librería gráfica para adjudicar memoria gráfica para búferes
internos, dispositivos gráficos, y fuentes. Esta función tiene como intención ser llamada
por la librería gráfica cuando se quiere adjudicar memoria. Por defecto, la función
simplemente llama a malloc, pero se puede controlar la administración de memoria de la
librería gráfica. La forma de hacer esto es simplemente creando la definición
de la función, con el mismo prototipo mostrado aquí.
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 montón (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 montón (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();
}
Función graphresult
Esta función obtiene y retorna el código de error para la última llamada sin éxito. Además,
reinicia el nivel de error a 0, o grOk. Existen varios valores de códigos de error.
La función graphresult retorna el código de error de la última llamada gráfica 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();
Función installuserdriver
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 gráfica:
** Súper Mega Guay Graphics Array (SMGGA)
** Ya sé que suena muy cursi, pero esto sólo es un ejemplo :)
*/
driver = installuserdriver( "SMGGA", detectarSMGGA );
/* Forzamos a que use nuestra función para autodetectar */
driver = DETECT;
initgraph( &driver, &modo, “C:\\TC20\\BIN” );
closegraph();
getch();
}
Función installuserfont
Esta función carga un fichero de fuente escalable que no está provisto con el sistema BGI.
El parámetro *nombre especifica el nombre del fichero fuente a cargar, en el directorio de
inicio. El sistema gráfico puede tener hasta veinte fuentes instaladas a la vez.
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:
** Súper Mega Chula Fuente (SMCF)
** Ya sé que suena muy cursi, pero esto sólo es un ejemplo :)
*/
if( (fuente_SMGF = installuserfont( "SMGF.CHR" )) != grError ){
settextstyle( fuente_SMGF, HORIZ_DIR, 4 );
printf("Instalación completada");getch();}
else{
settextstyle( DEFAULT_FONT, HORIZ_DIR, 4 );
printf("Error de al instalar la aplicación");getch();}
closegraph();
getch();
}
Función kbhit
int kbhit(void);
Veremos el uso de esta función en el modo grafico; para utilizar esta función se tiene que
declarar la cabecera conio.h
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());
}
Función outtext
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: " );
Función outtextxy
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();
}
Función pieslice
void far pieslice(int x, int y,int comienzo_angulo, int final_angulo, int radio);
Esta función es usada para dibujar y rellenar un una cuña circular. La cuña circular está
centrada en el punto especificado por los argumentos x e y. La porción circular de la cuña
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();
}
Función registerbgidriver
Esta función es usada para cargar y registrar un dispositivo gráfico. 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 función registerbgidriver retorna número del dispositivo cuando tiene éxito. Un código
de error, un número negativo, es retornado si el dispositivo especificado es inválido.
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();
}
Función registerbgifont
Esta función 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 gráfico; no es necesario ligarlo al programa.
La función registerbgifont retorna número del dispositivo cuando tiene éxito. Un código de
error, un número negativo, es retornado si el dispositivo especificado es inválido.
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();
}
Función restorecrtmode
Esta función es usada para reiniciar el modo gráfico del vídeo al modo en uso anterior a la
inicialización del sistema gráfico. Esta función suele ser usada en conjunción con la
función setgraphmode para cambiar entre ambos modos de texto y de gráficos.
Ejemplo:
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
void main() {
int driver = EGA;
Función sector
void far sector(int x, int y, int comienzo_angulo, int final_angulo, int x_radio, int y_radio);
Esta función es usada para dibujar y rellenar la parte de una elipse. El centro de la cuña
elíptica 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 cuña elíptica. La
cuña elíptica comienza al ángulo especificado por el argumento comienzo_angulo y es
dibujado en la dirección contraria al de las agujas del reloj hasta llegar al ángulo
especificado por el argumento final_angulo. La cuña elíptica es dibujado con el perímetro
en el color actual y rellenada con el color de relleno y la trama de relleno actuales.
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();
}
Función setactivepage
Esta función es usada para especificar un número de página que representa una sección
de memoria del vídeo donde todos los datos gráficos para mostrar son enviados. Está
sección de memoria se denomina una página activa. El argumento pagina específica el
número de la página activa. Para usar esta función con eficacia, el adaptador de vídeo
usado debe ser EGA o VGA y tener suficiente memoria para soportar múltiples páginas
para gráficos. Esta función es usada con la función setvisualpage para dibujar páginas no
visuales y para crear animación.
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 "
"página, cualquier otra tecla para salir\n" );
printf( "(Pulsa cualquier tecla para entrar en modo gráfico)\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();
}
Función setallpalette
Esta función 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 aquéllos definidos en la estructura palettetype. La síntaxis de la
estructura palettetype es:
#define MAXCOLORS 15
struct palettetype {
unsigned char size;
signed char colors[MAXCOLORS+1];
}
Nota: Recuerda que todos los cambios hechos a la paleta tiene un efecto visual inmediato
y que la función setallpalette no debería usarse con el dispositivo IBM-8514.
La función setallpalette no retorna ningún valor; sin embargo, si los valores pasados son
inválidos, entonces la función 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();
}
Función setaspectratio
Esta función es usada para modificar la proporción anchura-altura del modo gráfico actual.
La proporción anchura-altura puede definirse como la proporción de la anchura del píxel
del modo gráfico y la altura del píxel. Esta proporción es usada por el sistema gráfico para
calcular círculos y arcos. Por ello, alterando la proporción anchura-altura afectará la
visualización de estas Funciones. La función getaspectratio puede ser usada para obtener
las opciones por defecto del modo actual anteriormente a ser modificados.
Ejemplo:
#include <graphics.h>
#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();
}
Función setgraphbufsize
Esta función es usada para cambiar el tamaño del búfer gráfico interno como es asignado
por la función initgraph cuando el sistema gráfico es inicializado. El búfer gráfico es usado
por varias Funciones gráficos; por ello, se debería tener un mayor cuidado cuando se
altera este búfer del tamaño por defecto de 4096. La función setgraphbufsize se debería
llamar antes de llamar a la función initgraph.
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( "Búfer inicial: %d\tBúfer nuevo: %d\n", buf_inicial, buf_nuevo );
getch();
}
Función setgraphmode
valores por defecto. Esta función suele usarse conjuntamente con restorecrtmode para
cambiar entre modos gráficos y de texto.
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 gráfico..." );
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();
}
Función setlinestyle
Esta función es usada para definir las características de líneas para líneas rectas.
El argumento estilo específica la trama de línea predefinida para su uso. El argumento
trama es una trama de 16 bits que describe el estilo de línea cuando el argumento estilo
es USERBIT_LINE, ó 4. Un bit 1 en esta trama indica que el píxel correspondiente será
asignado el color actual. Un bit 0 indica que el píxel correspondiente no será alterado. El
argumento grosor define el grosor de la línea. Existen varios valores para los diferentes
estilos y grosores de líneas rectas.
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();
}
Función setpalette
Esta función 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 función setpalette no debería usarse con el dispositivo IBM-8514.
La función setpalette no retorna ningún valor; sin embargo, si los valores pasados son
inválidos, entonces la función 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();
}
Función setrgbpalette
Esta función 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) sólo
los seis bits más significativos son cargados en la paleta. Por razones de compatibilidad
con otros adaptadores gráficos de IBM, el dispositivo BGI define las primeras dieciséis
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 función setrgbpalette no debería usarse con el dispositivo IBM-8514.
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();
}
Función settextjustify
La función settextjustify no retorna ningún valor; sin embargo, si los valores pasados son
inválidos, entonces la función 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;
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();
}
Función settextstyle
Esta función es usada para especificar las características 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
función. El argumento orientacion especifica la orientación en que el texto ha de ser
mostrado. La orientación 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 tamaño del
carácter definido por el usuario usando la función setusercharsize, solamente Funciona
con fuentes escalables. El argumento tam_caracter puede agrandar el tamaño de la
fuente hasta 10 veces su tamaño normal. Existen varios valores y constantes para las
justificaciones.
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();
}
Función setusercharsize
Esta función extablece las características de fuentes escalables. Para que esta función
afecte el tamaño del carácter, el argumento tam_caracter de la función settextstyle debe
ser 0. La anchura del carácter se establece con los argumentos x_dividendo y x_divisor
que representan la proporción. Similarmente, los argumentos y_dividendo e y_divisor
especifican la altura del carácter.
Función setviewport
void far setviewport(int izquierda, int superior,int derecha, int inferior, int recorte_banderin);
Esta función es usada para definir el área gráfico. La esquina superior izquierda del área
gráfica 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 gráfica. El
argumento recorte_banderin define si los datos para la salida gráfica serán recortados
por el borde del área gráfico. Un valor de 0 para recorte_banderin indica que los datos
de salida no serán recortados, mientras que un valor distinto a 0 indica que los datos
serán recortados. Cuando el área gráfica es inicializada, la posición del cursor será
mudado a la posición (0,0) (la esquina superior izquierda). Todos los datos de salida
después de que el área gráfica haya sido inicializada serán con relación a este punto. El
área gráfica por defecto cubre la pantalla entera.
La función setviewport no retorna ningún valor; sin embargo, si los valores pasados son
inválidos, entonces la función graphresult retorna grError (-11) y el área gráfica 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 );
Función setvisualpage
Esta función es usada para establecer la página visual como es especificado por el
argumento pagina. Una página es una sección de memoria donde se guarda la
información del vídeo. Cuando se usa con un sistema (EGA o VGA) con suficiente
memoria de vídeo para soportar múltiples páginas de gráficos, la función setvisualpage
(junto con la función setactivepage) permite al programador crear gráficos en páginas
escondidas y pasar de página entre las que se han definido con información gráfica. Esto
es la base para crear animación.
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 página, cualquier otra tecla para
salir\n" );
printf( "(Pulsa cualquier tecla para entrar en modo gráfico)\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();
}
Función setwritemode
Esta función es usada para establecer el modo lógico de escritura para líneas rectas. El
argumento modo especifica el modo de escritura, el cual determina la interacción entre
valores de píxeles existentes y los valores de píxeles en la línea. Existen dos valores para
los modos de escritura.
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();
}
Función textheight
La función textheight retorna la altura, en píxeles, del texto especificado por el argumento.
Ejemplo:
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
void main() {
int driver = EGA;
Función textwidth
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";
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 parámetro en la función 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
función 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 información 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.
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 información actual para las líneas mediante la función
getlinesettings. El campo linestyle es el estilo de la línea recta. El campo upattern es la trama
de la línea 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 línea definido por el
usuario de 16 bits. Un bit 1 en esta trama indica que el píxel correspondiente será asignado el
color actual. Un bit 0 indica que el píxel correspondiente no será alterado. El campo thickness
es el grosor de la línea.
Existen varios valores para los diferentes estilos y grosores de líneas 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 */
closegraph();
printf( "Líneas 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 según cada dispositivo.
El campo size indica el tamaño de la paleta. El campo colors contiene los valores numéricos
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\nTamaño: %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;
};
Esta estructura se usa para obtener información acerca de la fuente gráfica actual mediante la
función getextsettings. Esta estructura contiene información de la fuente actual en uso, la
orientación del texto, el tamaño del carácter, y la justificación horizontal y vertical.
Existen varios valores para describir el tipo, la orientación, y justificación 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\tTamaño: %d\n"
"Justificación:\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 información acerca del área gráfica actual mediante la
función getviewsettings. Esta estructura contiene información acerca de las esquinas superior
izquierda e inferior derecha, también como el banderín de recorte del área gráfica.
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\tBanderín: %d\n",
info.left, info.top, info.right, info.bottom, info.clip);
getch();
}
Estructura time
struct viewporttype {
int left, top;
int right, bottom;
int clip;
};
Esta estructura se usa para obtener información acerca del área gráfica actual mediante la
función getviewsettings. Esta estructura contiene información acerca de las esquinas superior
izquierda e inferior derecha, también como el banderín de recorte del área gráfica.
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\tBanderín: %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.
1. imagesize
2. malloc
3. getimage
4. putimage
Función imagesize
Esta función es usada para determinar el tamaño del búfer necesitado para almacenar
una imagen con la función 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.
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();
}
Función malloc
Talvez no comprenda lo que quiera dar a entender pero ala hora del ejercicio lo
entenderán.
Ejemplo:
#include <graphics.h>
#include <conio.h>
#include <stdlib.h>
void main() {
Función getimage
void far getimage(int izquierda, int superior,int derecha, int inferior, void far *imagen);
Esta función es usada para guardar una porción 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 búfer de memoria donde la imagen está
guardada.
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();
}
Función putimage
void far putimage(int izquierda , int superior, void far *image, int acción);
Esta función coloca una imagen que fue previamente guardada con la función 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
búfer de memoria donde la imagen está guardada. La imagen se coloca en la pantalla con
la acción definida en el argumento acción. Los valores y consonantes usados por el
argumento accion se describen a continuación ya que pudieron haberlos olvidado:
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();
}
# 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();
}
}
getch();
}
# 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
{
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);
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
{
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");
}
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
recomendación (pasarle parámetros a la funcion para ahorrar códigodentro de ese misno
for llama al arreglo bidimensional imprimiendo en las coordenadas del rectangulo y los
demas cálculos son los mismos.
El macro atoi() convierte una cadena a su valor entero. Retorna el valor convertido de la
cadena leída. Si el valor no puede ser convertido el valor de retorno es 0. Observación: es
usada para convertir cadenas que contengas valores numéricas 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 función itoa
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();
}
Las funciones rand() y random() son similares, ambas devuelve un valor seudo-aleatorio,
la primera no recibe parámetros 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).
#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
librería mouse.h; esta función 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 también como las
funciones contenidas dentro de ella.
La función mver
La función mver muestra el puntero del ratón no es necesario enviar ningún parámetro.
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 función mocultar
Esta función oculta el puntero del ratón no recibe ni retorna ningún 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 ratón muy vistoso.
La función mtest.
Esta función sirve para testear el ratón en esta no es necesario enviar ningún parametro
retorna: 0 si no esta instalado el ratón, y n si el número de botones del ratón.
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 función mxpos
La función mxpos regresa la posición horizontal de un entero que seria la posición del
ratón 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);
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 función mypos
La función mypos regresa la posición horizontal de un entero que seria la posición del
ratón 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);
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 función msituar
Esta función permite situar al curcor en una posición específica para su utilización es
necesario enviar tres parámetros modo, x,y.
X: posición horizontal.
Y: posición vertical.
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();
}
La función mclick
int mclick(void)
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 función mlimit
void mlimit(int modo, int x1, int y1, int x2, int y2)
Esta función limita el espacio de movilización del cursor (ratón), en esta función es
necesario enviar cinco parámetros modo,x1,y1,x2,y2.
Estas coordenadas formarán un rectángulo el cual sera el limite hasta donde podra llegar
el ratón.
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 función minlimit
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 bot¢n y veras el efecto");
mver();
rectangle(100,100,200,120);
if(minlimit(1,100,100,200,120)==1)
{
outtextxy(310,240,"Haz pulsado el rat¢n por encima del bot¢n");
delay(30000);
setcolor(BLACK);
outtextxy(310,240,"Haz pulsado el rat¢n por encima del bot¢n");
}
}while(!kbhit());
closegraph();
getch();
}
Ejemplos de la de la VGA.
# 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;
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);
/******************triangulo2****************************/
/* q eje x w eje y*/
{
/********************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");
/*************************Pol¡gono*****************************/
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);
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);
# 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)
{
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);
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);
setcolor(YELLOW);
arc(310,300,90,270,30);
ellipse(310,300,90,270,05,30);
setfillstyle(SOLID_FILL,YELLOW);
floodfill(300,300,YELLOW);
}
setcolor(*color);
rectangle(*x1,*y1,*x2,*y2);
}
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); /*linea del lago superior */
line(480,250,560,200); /*monta¤a / */
line(560,200,639,250); /* monta¤a \ */
line(480,250,639,250); /* monta¤a ___ */
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);
#include <mouse.h>
#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 Tra¤a L¢pez");
outtextxy(10+textwidth("Hecho por: "),450,"Juan Carlos Guti‚rrez 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);
}
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();
}
# 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)
{
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);
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");
}
Introducción.
Cuando aparecieron los primeros computadores existía una memoria de solo 640 Kb
(memoria convencional) y el procesador que dominaba en aquella época era el 8086 y
8088 el cual podía direccionar hasta 1 Mb de memoria, ya que el microprocesador era de
16 bits. Añadieron a este diferentes áreas de memoria, para la BIOS, el video, cartuchos
ROM, etc.
Organización de la memoria de un PC
A000: corresponde a la memoria de la pantalla en los modos gráficos de las tarjetas EGA
y VGA.
B000: Es para las tarjetas de video monocromo MDA y Hercules. También sirve para la
tarjeta CGA. Se utiliza como alojamiento de los modos alfanuméricos.
C000: Se depositan algunas rutinas BIOS, que no forman parte del núcleo original de
esta.
El Procesador .
Para hacer la programación del sistema, hay que conocer algunos conceptos que juegan
un papel importante, términos 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 definición un poco más acertada, sería decir
que los registros son como variables internas con las que el computador realiza
operaciones, y lleva el control de los programas.
El tamaño 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 más 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 aritméticas, 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 propósito general para el programador.
Registros de dirección (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 Bandera (Flag): Sirve para saber el estado y tener el control del procesador.
Con este registro podremos saber, si por ejemplo después 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 según su valor.
Las interrupciones .
Las interrupciones, tal y como indica su nombre, tienen como función interrumpir en medio
de un procedimiento, ejecutar un trozo de código y continuar con lo que se estaba
haciendo. De esta manera la CPU se ahorra de ir preguntado todo el rato a los diferentes
periféricos 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
una tabla que nos servirá de “índice” para así obtener la dirección de la rutina. Esta tabla
se aloja en la parte más baja de la memoria, es decir, en 0000:0000, y tiene una longitud
de 256 entrada de 4bytes cada una; 2 bytes de dirección (segmento) y 2 bytes de
desplazamiento (offset), o sea, 1 kb en total.
INTERRUPCION 0DH y INTERRUPCION 0FH: Estas son para el Control del Dispositivo
Paralelo.
Estas son las interrupciones del BIOS, pero hay más, las del sistema operativo, MS-DOS
en nuestro caso. Cada interrupción se divide en funciones, que son los diferentes
servicios a los que tenemos acceso. Para llamar a una interrupción utilizamos los
registros, donde en AX indicaremos por norma general el número de interrupción, y en los
demás registros los parámetros.
Resumiendo, tenemos que las diferentes capas a la que una aplicación puede acceder
son tres:
Para decidirnos por uno de los tres, se tendrá que pensar en el objetivo de la aplicación
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 aplicación en modo texto, simplemente usaremos las
funciones que nos pone a disposición nuestro lenguaje de programación favorito.
Introducción.
Los registros de las tarjetas constituyen el dispositivo de Entrada/Salida (E/S) de más bajo
nivel de los adaptadores gráficos. Es en ellos donde se almacena la información relativa a
como debe el computador representar los datos en la pantalla. Están conectados a
puertos de E/S que los hacen accesibles, permitiendo su modificación 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 gráficas, tendremos que acceder a estos registros, para
lo cual se emplea un índice de puerto o index port.
Un mismo controlador puede controlar más de un registro, por lo que la finalidad de este
índice es señalar cuál 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 aparición de la tarjeta de video VGA (Video Graphic Array) como en el año 1987, hizo
que se convirtiera en un estándar de los computadores IBM y compatibles.
Lamentablemente para usar los 256 colores solo se puede usar una resolución de
320x200 pixeles. Este modo de vídeo es el conocido Modo 13h, en el cual se han
programado la mayoría de los juegos, demos, aplicaciones gráficas, etc. Este modo es
uno de los más usados en la programación gráfica, debido a su facilidad de uso y rapidez.
Las tarjetas VGA tienen normalmente un mínimo 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 denominación
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
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.
El nombre 13h viene del parámetro que hay que pasarle a la interrupción 10h para iniciar
este modo. Esta ultima es un interrupción software que facilita al programador tomar el
control del hardware de un PC. La interrupción 10h esta encargado de dar los servicios de
video.
Ahora para iniciar el modo de video 13h debemos usar la función 00h de la interrupción
10h, y para esto se les pasa unos parámetros.
Qué significa todo esto, lo que sucede es que cada interrupción posee varias funciones y
a su vez cada función también puede tener sub-funciones. En este caso nosotros
queremos iniciar un nuevo modo de video, para esto utilizamos la función 00h de la
interrupción 10h, la cual esta encargada de activar modos de video específicos.
Como podemos ver en la tabla el Modo 13h es uno de los que tiene menor resolución de
los modos gráficos, pero es el que tiene mayor número de colores. Nosotros utilizaremos
dos modos, el 13h y el 03h, este último los usaremos por la sencilla razón, de que cuando
se termina un programa gráfico, 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)
Después 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 automáticamente con las características 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). Acuérdense de incluir la cabecera <dos.h> para
utilizar la función int86 y la union REGS.
void Modo13h(void)
{
union REGS r;
r.h.ah=0;
r.h.al=0x13;
int86(0x10, &r, &r);
}
Lo que hemos hecho con esta función es simplemente llamar a la interrupción 10h con los
parámetros necesarios para iniciar el modo 13h.
Otra rutina que nos será de mucha utilidad será la que regresa al modo texto, esta función
es similar al anterior, la única diferencia es que al registro AL se le debe pasar el valor
03h.
Podríamos crear una función general para que realice los cambios de modos de video,
esto quedaría así:
void SetMCGA(void)
{
_AX=0x0013 ;
geninterrupt(0x10) ;
}
Para volver al modo texto usamos la misma interrupción 10h, sólo que el servicio 03h :
void SetText(void)
{
_AX=0x0003 ;
geninterrupt(0x10) ;
}
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();
}
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");
getch();
ModoTexto();
printf("Regreso a modo VGA");
getch();
Un Ejemplo:
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++){
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:
Para poder ver estos ejemplos debes de tener intalada las librería que esta incluida en el
tc20 que te obsequiamos
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 instrucción:
installuserdriver(“Svga256”,DetectVGA256);
“Svga256” es nombre del dispositivo debes omitir la extensión .bgi
DetectVGA256 es una función 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:
#include<conio.h>
#include <graphics.h>
void main()
{ int modo = DETECT, tarj,TIPOLETRA;
int color=0,x=180,y=50;
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);
setcolor(55);
outtextxy(425,740,"Huacho - Peru");
getch();
closegraph();
}
Ahora si quieren ver un programa funcionando a qui lo tienen
#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; /* tama¤o 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 */
};
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;
void presentacion(void)
{
char control;
clrscr();
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);
}
if (!f)
return (FALLA);
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 Tama¤o del archivo: %ld bytes",bmp_cab.tam);
printf("\n Offset del archivo: %ld",bmp_cab.offset);
printf("\n Tama¤o 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 Tama¤o 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);
getch();
}
void paleta(void)
{
register int i,j;
char opcion;
clrscr();
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 */
modo_video(M320x200);
mver();
cambiar_pal(rgb);
modo_video(MTexto);
}
void mostrar_pal(void)
{
register int i,j;
modo_video(M320x200);
cambiar_pal(rgb);
modo_video(MTexto);
}
void despedida(void)
{
clrscr();
gotoxy(20,13);
printf("ESPERO QUE HAYA DISFRUTADO DEL PROGRAMA...");
getch();
exit(0);
}
memset(vga+x+(y*320),color,1);
}*/
/*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);
}
#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;
}
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);
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());
}
Ahora aremos un efecto que talvez les guste y lo estudien con detenimiento ya que
merece mucha atención.
#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
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
*/
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);
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);
xyz();
tecla=IZQUIERDA;
if(kbhit())
{
tecla=getch();
}
setfillstyle(1,0);
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);
}
#include<stdlib.h>
# include <dos.h>
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
#define bordear 40
#define bordeab 460 /*acotamos la parte valida de pantalla*/
#define bordeiz 20
#define bordede 620
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);
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*/
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");
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 ("Dise¤ado 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;
Lee_record();
superado=0;
vel=v*300;
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;
if(Choque())
{
printf("%c",pito); /*si se choca, pierde*/
Salir();
}
Pinta_pantalla();
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*/
cleardevice();
Pinta_serpiente();
gotoxy(37,15);
printf("Pausa");
t=getch();
cleardevice();
Pinta_serpiente();
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;
}
}
if((longitud)/(i*30)<0)
{
vel-=15;
i++;
}*/
delay(vel);
if(puntos>max)
{
max=puntos;
superado=1;
}
}while(1);
}
void Salir(void)
{
char opc;
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;
xa=ultimo->x;
ya=ultimo->y;
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;
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;
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));
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;
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);
setfillstyle(1,colorfondo);
fillellipse(xa,ya,radio,radio);
setfillstyle(1,c);
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);
}
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 diseñarse. Por el contrario es beneficioso en muchas
ocasiones realizar un buen diseño a pesar de utilizar gran cantidad de esfuerzo
y emplear estructuras de datos complejas, si se consigue finalmente un
método de resolución que realice buenos tiempos de ejecución para entradas
grandes de datos. Por otra parte, cuando nuestro algoritmo pretende resolver
un problema clásico, como puede ser en Geometría Computacional, se da por
supuesto que tiene que ser eficiente con grantes cantidades de datos y además
hay que suponer que dicho algoritmo va a ser ampliamente utilizado.
Para n > 2, tenemos que T(n) = c +T(n –1). El término T(n –1) se sustituye
por n –1:
T(n–1) = c+T(n–2), sustituyendo tenemos que T(n) = c+c+T(n–2). Siguiendo
este
proceso hasta el término i entonces T(n) = ic+T(n–i). Cuando i = n–1, T(n) =
nc+T(1) =
ncfi= O(n).
1.3.1. Introducción
En este curso utilizaremos varios de estos tipos de datos. Por ejemplo, el tipo
de dato TipoPunto, TipoPoligono, etc. En las clases de prácticas se definirán
muchos de ellos, ahora identificaremos los anteriores en Pascal para poder
trabajar con ellos a lo largo de este tema:
/************REPRESENTACION DE UN PUNTO*********************/
# define x 0;
# define y 0;
typedef enum{ FALSE, TRUE}bool;
# define DIM 2 /*Dimensión del punto*/
typedef int tpointi(DIM); /*Declaración de un arreglo de puntos*/
/*********REPRESENTACION DE UN PUNTO***********************/
El resultado de este cálculo será positivo siempre que los vértices abc sean
recorridos en orden inverso a las agujas del reloj. En caso contrario el valor
será igualmente válido y medirá el área, pero tendrá el signo negativo.
El cálculo del área de un polígono convexo es bien sencillo, basta con calcular
el área de todos los triángulos que se pueden formar lanzando diagonales
desde cualquier vértice, hasta el resto de los vértices del polígono convexo.
El triángulo p01 se traza en sentido inverso a las agujas del reloj, lo que
implicará siempre que el área de dicho triángulo es positiva. Se ha señalado
utilizando un símbolo + cuando el cálculo se realiza en el sentido antihorario y
con – cuando el área es negativa. Cuando el recorrido de los vértices del
triángulo siempre en la forma pvivi+1, sea en sentido horario, por ejemplo el
triángulo p67, el área correspondiente se resta. El resultado final, como
podemos observar en la figura, es que todas las áreas de los triángulos no
contenidas en el interior del polígonos 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 función AreaTriangulo2 tantas veces como
triángulos se vayan formando con el proceso anterior, sumando unas veces las
áreas y otras restándose automáticamente según sea la salida de dicha
función. Como de cada triángulo se calcula el doble de su área, finalmente será
necesario dividir por dos el resultado final.
Veamos el código:
embargo, y siguiendo con la dinámica de trabajar siempre que sea posible con
aritmética de enteros, el algoritmo de intersección de segmentos va utilizar
otra serie de subrutinas necesarias.
Si recordamos una de las propiedades de la función del cálculo del área del
triángulo, el resultado es positivo si la lectura ordenada de los vértices 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:
Veamos el codigo:
Veamos el codigo en C:
Debemos insistir en que el código anterior da por supuesto que todos los
cálculos se realizan únicamente utilizando aritmética de enteros. No quiere
decir ésto que no pueda migrarse dicho código a operaciones en coma fiotante,
pero en ese caso jamás debería realizarse una operación 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 más 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 próximo a cero.
1. no son colineales
2. si d está a la izquierda de ab y c está a la derecha (o al revés) y además
3. si a está a la derecha de cd y b lo está a la izquierda (o al revés)
Veamos el codigo en C:
Esta versión del algoritmo además cuenta con al ventaja de poder trabajar con
las intersecciones de forma propia o impropia. Una intersección impropia
ocurre cuando un extremo de uno de los segmentos está justo en en alguna
posición del otro. La siguiente función en Pascal detecta primero si existe la
posibilidad de colinealidad con la función Entre. Posteriormente hace el mismo
proceso que IntersectaSegmento.
Veamos el código:
Veamos el codigo:
Por tanto, una diagonal es aquel segmento interior que está dentro del
polígono. Pero el segmento i j es una diagonal si no intersecta con ninguna
otro de las aristas del polígono. Este cálculo necesita forzosamente un tiempo
de ejecución lineal. La función DiagonalfiIE se encargará de realizar este
chequeo, y que será invocado por la función Diagonal cuyo código resulta
bastante evidente: el segmento i j es una diagonal del polígono P de tamaño n
si es interior y además no intersecta con ninguna arista.
Veamos el código:
/*Esta function verifica si una diagonal se intersecta con una arista del
poligono */
Veremos que el siguiente método puede ser perfectamente válido para lograr
la triangulación de cualquier polígono P de tamaño n. Sin embargo, y a pesar
Contenedores secuenciales
Las secuencias más usuales son las listas enlazadas y los arrays. Las primeras
forman una sucesión 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
implícitos con acceso directo. Esta ventaja de acceso en tiempo constante se
ve mermada por poseer menor fiexibilidad. Por ejemplo, la operación de
inserción 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 dinámica. Esta consideración
también puede realizarse sobre arrays dinámicos.
Contenedores asociativos
Éste puede ser considerado como uno de los métodos más simples e intuitivos,
también conocido como el método iterativo. La idea sobre la que trabaja este
método consiste en construir la solución de modo iterativo, considerando que
la entrada se produce de modo incremental. Para cada una de las nuevas
entradas, el problema se resuelve convenientemente.
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
Algoritmo 1
Algoritmo 2
Es un ejemplote Voronoi.
2.1.1. Introducción
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 definición puede ser aplicada en cualquier espacio
euclídeo 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 fácil de entender en
cierto modo si consideramos a la envolvente convexa de un conjunto de puntos
en el plano, como la forma que adquiriría una goma elástica envolviendo a
todos los puntos del conjunto que están 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 cálculo de la envolvente
convexa.
Los algoritmos propuestos para este problema son realmente numerosos. Sin
duda es uno de los planteamientos de la Geometría Computacional que más
soluciones ha conseguido. Desde incluso antes del nacimiento oficial de esta
disciplina se conoce el trabajo de Graham en el año 1972. Se han propuesto
estrategias siguiendo los paradigmas más empleados como el método
incremental y el divide y vencerás. Todos estos algoritmos construyen la
envolvente convexa en tiempo (nlog n). El método propuesto por Preparata y
Shamos en 1985 fue denominado Quickhull por su similitud con el método de
ordenación Quicksort. Otra propuesta diferente se dió a conocer en 1973 como
.La marcha de Jarvis.. Este método, que estudiaremos en este curso, posee un
tiempo de ejecución cuadrático, 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 clásico de
algoritmos para la resolución de la envolvente convexa, al que habría que
añadir otras técnicas posteriores.
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 combinación final no podría
producirse. Este problema sería un problema 3D si cada mezcla tuviera tres
componentes, la solución sería la contrucción de la envolvente convexa
tridimensional.
Complejidad: O(n4 )
Complejidad: O(n3 )
QuickHull(a,b,S)
1. Si S={a,b} entonces devolver (a,b)
2. sino
3. c := índice del punto con máxima 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 más a la derecha de S;
2. b := punto más a la izquierda de S
3. devolver concatenar(QuickHull(a,b,izquierda(a,b,S)),
QuickHull(b,a,izquierda(b,a,S)))
La idea básica del quickhull (envolvente rápida) es que para la mayoría 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 cuadrilátero que ellos definen
(este cuadrilátero puede ser degenerado), ahora todos los puntos en el interior
de dicho cuadrilátero 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 más alejado a la recta que define dicha región
obteniendo así cuatro nuevos puntos y un polígono de a lo más ocho lados que
divididirá a los puntos que no hemos eliminado en ocho regiones que tratamos
individualmente siguiendo la misma regla anterior.
Ejemplo:
Este es sin duda uno de los algoritmos más importantes para el cálculo de la
envolvente convexa, no únicamente por su simpleza sino también por su
rapidez.
Ejemplo:
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 condición puede ser eliminada). Comenzamos encontrando el
primer punto con el orden lexicográfico, llamemosle p0. A continuación
ordenamos los puntos por el ángulo que forman con p0.
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:
La ventaja de unos métodos con respecto a otros a veces viene dada por su
velocidad computacional y otras veces por su fácil extensión a tres
dimensiones, lo que habitualmente llamamos problemas 3D. El método
incremental para el cálculo de la envolvente convexa es uno de estos casos.
Para añadir cada nuevo punto pi+1 basta con lanzar tangentes desde este
punto hasta el polígono 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 más bajo de tangencia es tal que pi, es tal
que q está a laizquierda de pi–1 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
j–1 pj pero a laizquierda de pj pj+1.
Pero obtener los dos puntos tangentes no implica de ningún modo que el
proceso ha finalizado. El punto q será parte ahora del nuevo polígono convexo,
así como lo serán los puntos pt1 y pt2. Sin embargo, es posible que algunos
otros vértices del polígono convexo desaparezcan. En el ejemplo de la figura,
la secuencia de vértices i+1; :::; j–1 claramente desaparece al añadir el nuevo
punto. El resultado final sería el polígono
P = p0; p1; :::; pi_1; pi;q; pj ; pj+1; :::; pn_1.
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 ] )
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
Veamos como funciona el algoritmo en sus primeros pasos para este ejemplo.
Al ordenar los puntos de mayor a menor obtenemos la numeración 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 aún
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 1–4;2–4;3–4. La idea básica del algortimo es
construir diagonales con el comienzo de la lista l o con el final de ésta ,
teniendo en cuenta que sólo se unen puntos visibles entre sí (ángulo < ) y
que no son adyacentes.
Algoritmo de triangulación
3 Intersecciones
Sin embargo, realizar esta operación con polígonos convexos puede hacerse en
tiempo O(n+m). Existe una propiedad importante para la intersección de
polígonos convexos: la intersección es también un polígono convexo.
fiNfiSI
Adv <– Adv + 1
ab <– (ab +1) mod n
fiN
Para hacer más fácil el cálculo y utilizar una recta r válida 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.
DIAGRAMA DE VORONOI
APLICACIONES PRELIMINARES
4. La facilidad de Localización
V (pi) = {x: | pi - x pj - x j }.
Note que hemos definido este grupo para ser cerrado. Algunas puntos no tienen
un único sitio próximo, o vecino próximo. El grupo de todos los puntos que tienen
más de un vecino cercano forman el diagrama de Voronoi V (P) para el grupo de
sitios.
Más tarde definiremos los diagramas de Voronoi para grupos de objetos más
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 triángulo (p1, p2, x) como se muestra en la Figura 5.2.
Por el teorema del lado - ángulo - lado de Euclides, | p1x | = | p2x |.
Tres sitios
Para tres sitios, es claro que fuera del triángulo (p1, p2, p3), el diagrama contenga
la bisectriz B12, B23, B31. Lo que no esta claro es que ocurre en los alrededores
del triángulo. Otra vez de Euclides las bisectrices perpendiculares de los tres
lados del triángulo todos atraviesan un punto, el circuncentro, el centro del único
círculo que pasa a través de los vértices del triángulo. Así el diagrama Voronoi
para tres puntos debe aparecer como en la Figura 5.3. (Sin embargo, el
circuncentro de un triángulo no está siempre dentro del triángulo como se
muestra).
Semiplanos
La generalización más allá de tres puntos quizá todavía no esta clara, pero es
ciertamente claro que la bisectriz Bij desempeñará un papel. Sea H el semiplano
cerrado con límite Bij y conteniendo pi. Entonces H puede ser visto como todos
los puntos que están cercanos a pi que a pj. Ahora ordene el regreso de que V
(pi) es el grupo de todos los puntos más cercano a pi que a cualquier otro sitio:
En otras palabras, los puntos más cercanos a pi que a p1, y más cercano a pi que
a p2, y más cercano a pi que a p3, etcétera. Esto muestra que podemos escribir
esta ecuación o V(pi):
V (pi) =
i j
H (pi, pj) (ecuación 5.2)
Donde la notación significa que la intersección debe estar ocupada sobre todo i
y j como i j. Note que esa conjunción inglesa “y” ha sido trasladada a
intersección de conjunto.
Figura 5.4 (a) Diagrama de Voronoi para cuatro puntos cocirculares; (b)
diagrama después de mover los puntos hacia la izquierda.
La ecuación (5.2) inmediatamente nos da una propiedad importante de los
diagramas de Voronoi: Las regiones de Voronoi son convexas, pues la
intersección de cualquier número de Semiplanos es un grupo convexo. Cuando
las regiones están rodeadas, son polígonos convexos. Los bordes de las regiones
de Voronoi son llamados bordes de Voronoi, y los vértices son llamados vértices
de Voronoi. Note que un punto en el interior de un borde de Voronoi tiene dos
sitios próximos, y un vértice de Voronoi tiene al menos tres sitios próximos.
Cuatro sitios
El diagrama de cuatro puntos formando las esquinas de un rectángulo es
mostrado en la Figura 5.4 (a). Note que el vértice 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
degeneración.
Muchos sitios
Un diagrama típico con muchos sitios es mostrado en la figura 5.5. Un vértice
de Voronoi no es mostrado en esta figura: Los dos rayos casi horizontales
Triangulación de Delaunay
En 1934 Delaunay probó que cuándo la gráfica dual se traza con líneas rectas,
produce una triangulación planar de los sitios de Voronoi P (si ninguno de los
cuatro sitios son cocirculares), ahora llamado la triangulación de Delaunay D (P).
Figura 5.6 muestra la triangulación de Delaunay para el diagrama de Voronoi en
Figura 5.5, y la figura 5.7 muestra que la triangulación de Delaunay
superpuesta en el diagrama correspondiente de Voronoi. Note que no es
inmediatamente que usando líneas 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 más bien esperaremos hasta que hayamos
recogido más propiedades de la triangulación Voronoi de diagramas y Delaunay,
cuándo la prueba será fácil.
pi punto generador.
adyacentes dos regiones se dice que son adyacentes si comparten algÿn eje.
Los conceptos anteriores son extensibles a tres dimensiones, teniendo en
cuenta que ahora las regiones de Voronoi serÌan poliedros y los ejes serÌan
polÌgonos.
La implicación inversa es más sutil. Suponga que hay un círculo vacío C (x) a
través de a y b, con centro en x. Tenemos la intención de poner a prueba que
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 ningún otro punto interfiera con “El sentido de
la hermandad próximo”. Pero ninguno es, porque el círculo está vacío. 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 límite
de C (x) de otra manera que a y b (por la hipótesis), allí deban ser libertad para
contonearse la x un poco y mantener vacío C (x). En particular, podemos mover
x a lo largo de Bab, la bisectriz entre a y b, y podemos mantener vacío al
conservar el círculo a través 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 intuición, los ejercicios, y
para la Sección. 5.7.2
Ejercicios
Los ALGORITMOS
Las muchas aplicaciones del diagrama de Voronoi y su belleza inherente les han
instado a los investigadores a que inventen una colección variada de algoritmos
para computarlo. En esta Sección 5.7.2 examinaremos cuatro algoritmos, cada
uno superficialmente, para ver que la Sección 5.7.2 que el diagrama Voronoi
puede ser computado usando nuestro código del buque convexo.
tiempo O(n log n) tiempo (Ejercicio 6.5.3 [5]). Hacer esto para cada sitio costaría
a O (n2 log n).
Construcción incremental
Suponga que el diagrama de Voronoi V para k puntos están ya construidos, y
ahora nos gustaría construir el diagrama V’ después de añadir uno o mas puntos
p. Suponga que p cae dentro de los círculos asociados con varios vértices de
Voronoi, dice C (v1),…, C (vm). Entonces estos vértices de V no pueden ser
vértices de V’, pues violan la condición de que los círculos del vértice de Voronoi
deben estar vacíos de sitios (V5, Sección 5.3.2). Resulta que éstos son los únicos
vértices de V que no están arrastrados sobre V’ También resulta que estos
vértices están todos localizados en un área del diagrama. Estas observaciones
vagas pueden ser hechas precisas, y forjan uno de los algoritmos más limpios
para construir el diagrama de Voronoi. El algoritmo gasta O (n) tiempo por
inserción de punto, para una complejidad total de O (n2). A pesar de esta
complejidad cuadrática, éste ha sido el método más popular de construir el
diagrama; Ver Field (1986) para los detalles de implementación.
El algoritmo incremental ha sido revitalizado recientemente con aleatorización,
el cual tocaremos en la Sección 5.7.4.
Divide y vencerás
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 computación. Esta vez la complejidad es asintóticamente óptima,
pero el algoritmo es bastante difícil para implementar. De cualquier forma puede
estar hecho con atención meticulosa para las estructuras de datos.
El algoritmo de Fortune
Los conos
Frente parabólico
Ahora finalmente podemos ver cómo solucionó Fortune el problema del problema
de la línea 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 parabólica, lo cual queda atrás de L un poco.
El Lo que es mantenido en todo tiempo por el algoritmo es la parte delantera
parabólica, cuyas uniones trazan el diagrama de Voronoi sobre el tiempo, Desde
que todas estas enroscaduchas permanecen en los bordes de Voronoi. Aunque
Finalmente, debería estar claro que el algoritmo sólo necesite almacenar la parte
delantera parabólica, que es de tamaño 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 más pequeño que el tamaño
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
información geográficos.
5.4.5 Ejercicios
Una aplicación del diagrama Voronoi para agrupamiento de los vecinos más
cercanos mencionado en Sección 5.1 Este problema puede verse como un
problema de consulta: ¿Cuál es el vecino mas cercano a un punto buscado? Otra
versión es la problema del vecino más cercano: Encuentras el vecino mas
cercano para cada punto en un grupo dado. Esto tiene un número de aplicación
en una variedad de campos, incluyendo biología, la ecología, la geografía, y
Física.
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 gráfico orientado,
Una forma sucinta a captar la esencia del algoritmo del vecino cercano
eficiente es a través del siguiente lema.
Un algoritmo de fuerza bruta para encontrar a los vecinos cercanos para cada
punto en un grupo requeriría O (n2), pero el lema de arriba nos deja registrar
solo los bordes O (n) de la triangulación de Delauny y por lo tanto logra O (n
log n).
sitios como sea posible. Ahora examinamos problema del círculo vacío más
grande en detalle.
El círculo Vacío más grande. Encuentre que un círculo vacío más grande cuyo
centro está en el buque convexo (cerrado) de un grupo de n sitios S, vacíos en
que no contiene sitios en su interior, y más grande que no hay otro semejante
con estrictamente radio mayor.
Sea a f (p) el radio del círculo más grande y vacío puesto en el centro en P del
punto. Entonces andamos buscando un máximo de esta función sobre toda p en
el buque de S, H=H(S). Pero hay un número aparentemente infinito de
candidatos apuntando a este máximo. Un tema común en la geometría
computacional es reducir un grupo infinito del candidato para una lista finita
pequeña, y entonces encontrar estos eficazmente. Seguimos esto en este
escenario en esta sección, comenzar por discutir informalmente que solamente
ciertos puntos p son candidatos verdaderos para un máximo de f.
Es única cuando el círculo incluye tres sitios que f (P) pudo estar en el máximo.
Si lo tres sitios “entrecruzados” el centro p, en el sentido que hizo girar más que
Si, sin embargo, el círculo centró en p contiene s1 de dos sitios y s2, entonces
es posible que la dirección a lo largo de la bisectriz de los sitios que aumenta
sus distancias sea la dirección que va fuera del buque. Así adecuadamente podría
ser que f (P) está en el máximo. Hemos mostrado este hecho:
El algoritmo
Note que no cualquier vértice de Voronoi está necesariamente dentro del buque
(la Figura 5.14), que necesita comprobar que v H dentro del algoritmo. Una
implementación ingenua de este algoritmo requeriría el tiempo cuadrático en n,
pero localizar un vértice 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.
Lo mínimo
que se extiende a lo largo un
árbol.
Algoritmo de Kruskal
MST D (p)
Así se supone que C está en este círculo, como se muestra en figura 5.16.
Entonces
| ac | < | ab |, y |bc|< |ab|; Estas desigualdades tienen aplicación aun si C está
en el círculo, puesto que la C es distinta de a y b. La extracción de ab
desconectará el árbol en dos árboles internos, con a en primera parte, Ta, y b
en el otro, Tb. Suponga sin la pérdida de generalidad que e esta en Ta. Elimine
ab y añada el borde bc para hacer un árbol nuevo,
T’ = Ta bc +Tb. Este árbol es mas corto, así el único único usado ab, no podría
serminimo. Hemos alcanzado una contradicción negando que ab está en D, así
es que debe ser ese ab D.
La idea es más 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. Debería estar claro que la excursión
construida por aquí tiene exactamente dos veces el largo del MST, desde que
cada borde del árbol se cruza una vez en cada dirección.
Ahora obtenemos un límite dentrote que esta mal este doble-MST recorrido
podría ser. Sea M la longitud de Lo mínimo 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.
T1 < T,
M T1,
M < T,
M2 < 2T.
Este resultado puede ser mejorado con heurísticas diversas. Esbozaré sólo el
más simple tan heurístico, lo cual se basa en la determinación comprensible para
no volver a visitar un sitio dos veces. El recorrido del camino doble-MST de
entrada, con la modificación que si el próximo sitio ya se ha visitado hasta ahora
por el camino, salte el sitio y considera conectarse al próximo uno a lo largo del
doble-MST recorrido. Esto hace el efecto de tomar una ruta más 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 podría conectar
para Sj por un segmento de la línea recta o un atajo al recorrido, considerando
que el recorrido doble-MST sigue un camino encorvado Si, Si+1 , …, Sj-1,Sj..
Heurístico puede ser único acorta el camino. Un ejemplo es mostrado 5.18. Note
que el camino fue acortado.
2. NNG y D [Fácil] . Encuentran un ejemplos que muestre ese NNG pueden ser
un subconjunto correcto de D (p).
6. El algoritmo del círculo vacío. El detalle (en el código pseudo) cómo llevar a
cabo el algoritmo del círculo vacío (Algoritmo 5.1) con el fin de que su
complejidad de tiempo es O (n log n).
b. Ponga a prueba a ese RNG: Cada borde del RNG es también borde de la
triangulación de Delauny. (Compárese con Teorema 5.5.5).
9. El tamaño del gráfico del barrio relativo (RNG) en dimensiones del árbol.
Ejercicio[7] anteriormente establecido ese RNG D (P) en dos dimensiones, y esta
relación contiene dimensiones arbitrarias. Se ha demostrado el tamaño que
tiene el RNG en dimensiones del árbol es O (n3/2) (Jaromezyk y Toussaint
1992), así es que es más pequeña que la triangulación de Delaunay. Pero parece
que este salto superior es débil: Jaromezyk y Kowaluk (1991) suponen que el
tamaño es O (n). Confirmar esta conjetura es un problema.
10. MST RNG Pruebe que cada borde de un MST es un borde del RNG.
(Compárese con Teorema 5.5.5)
11. Los puntos más remotos de Voronoi. Defina el diagrama de puntos más
remotos de Voronoi F (P) asociado cada punto del plano para el sitio que es su
“vecino más remoto”, el sitio que está más 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.
Ejes Medios
A veces los ejes medios de P están definidos como el sitio central de los
círculos máximos: los círculos dentro de P estos no son los mismos encerrados
en algunos otros sitos dentro de P. El proceso de transformación dentro de los
ejes medios son en ocasiones llamados “Transformación de Bosques Quemados”
por si una imagen del polígono P tal como un césped 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 dirección. La conexión entre esta analogía y la
quema del bosque discutido en la sección 5.1 debería ser evidente.
Los ejes medios fueron introducidos por Blum en 1967 para el estudio en
forma biológica, el observo de manera semejante a un esqueleto (eje) las
amenazas bajo el medio (mediana) de alguna forma. Esta es menos aparente
para un polígono convexo que para un no convexo y formas planas que era el
principal interés de Blum, uno puede caracterizar la forma de cierta sección de
la estructura de estos ejes medios y esto va incluido un interés 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 mandíbula normales y los deformados. Puede ser usada
para calcular una compensación interior de un polígono, todos de cuyas fronteras
son compensaciones interiores por una distancia fija. Expandidas o externas
compensaciones cuentan en la versión exterior del eje medio. Calcular
compensaciones es un importante problema en la manufacturación, donde la
tolerancia de ingeniería es llevada naturalmente a formas de compensación.
Ejercicios
El 1986 Ellels Brunner & Seidel decubrió una bella conexión entre la
triangulación de Delaunay y el convex hulls en una de las más altas dimensiones:
primero explicaré entre el convex hull bidimensional y la triangulación
unidimensional de Delaunay (que son admitimademente triviales) y entonces
generaliza la triangulación bidimensional de Delaunay y el tridimensional convex
hull.
z-a2= 2a (x-a)
z= 2a x-a2
z=2a x-a2 + r2
Desde esta en una cara inferior del buque, todo las otras puntos del
paraboloide están arriba. Desde que están arriba , están más que el r2 arriba,
cuál es el r2 debajo. Por eso estos puntos se proyectan fuera del círculo de radio
r en el plano x y. Por eso el círculo determinado adentro de los planos x y está
vacío en todos los otros sitios. Por eso forma un triángulo Delaunay. Por eso
cada cara triangular inferior del buque convexo es propia de un triángulo
Delaunay. ¡Por eso la proyección del “fondo” del buque convexo se proyecta para
la triangulación Delaunay! Otra vez evacue a Figure 5.26.
La implicación
main()
{
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];
}
La estructura O (n4) del código 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 están o por encima del plano conteniendo i, j, y k. Si es así, (i, j, k)
es salida como triángulo Delaunay. (La símil arridad para el algoritmo del buque
de dos dimensiones en Algoritmo 3.2 debería ser evidente).
Aunque es interesante para ver tal código sucinto computar un propósito guste
la triangulación Delaunay, es impráctica para varias razones:
5.7.5 Ejercicio 1.
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);
}
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 ),
p0 = (DE – BF)/G,
p1 = (AF – CE)/G.
I X Y X2+y2
0 31 -76 6737
1 -13 21 610
2 -63 -83 10858
3 -5 -66 4381
4 87 -94 16405
5 40 71 6641
6 23 -46 2645
7 64 -80 10496
8 0 -57 3249
9 -14 2 200
z=2bx – b2
x= a+b
2
De esta manera la proyección de las intersecciones están adyacentes al
diagrama de Voronoi y al grupo de puntos
z = 2ax + 2by – a2 + b 2,
z = 2cx + 2dy – c2 + d2
Bibliografía
[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