E.
Programación de gráficos con RAPTORgraph
Por el Dr. Steve Hadfield, el Mayor Jason Moore y el Teniente Coronel
Tom Schorsch
En Computer Science 110, crearemos programas de gráficos usando un paquete de
gráficos simple llamado RAPTORgraph, que fue adaptado de Adagraph escrito por Jerry
van Dijk de los Países Bajos y modificado ligeramente para nuestro uso en USAFA. Esta
lectura explica cómo empezar a usar RAPTORgraph y describe las rutinas de
RAPTORgraph que necesitará este semestre.
Descripción general de RAPTORgraph
Todos los comandos de RAPTORgraph están relacionados con una ventana gráfica
especial, un ejemplo de la cual se muestra a continuación (Figura 1). En esta ventana
gráfica puede dibujar líneas, rectángulos, círculos, arcos y elipses de varios tamaños y
colores. También puede mostrar texto en la ventana gráfica. Si está viendo esto en línea,
puede descargar y ejecutar el programa haciendo clic aquí:RaptorGraph_Image1.rap
Figura 1. Ejemplo de salida de RAPTORgraph
Se han dibujado varias formas gráficas rellenas y sin rellenar en la ventana gráfica de
arriba. El “cilindro” de estructura de alambre verde se creó dibujando dos elipses y luego
trazando una línea entre la parte superior y la parte inferior de las elipses. El “cubo” de
estructura de alambre marrón se creó dibujando dos rectángulos y luego conectando las
cuatro esquinas de los rectángulos con líneas. El objeto amarillo con forma de luna que se
encuentra en el centro se creó al llenar un área cerrada con inundación.
MI-1
Puede interactuar con un programa gráfico determinando la posición del mouse en la
ventana gráfica y determinando si se hizo clic en un botón del mouse y dónde. También
puede simular el movimiento en la ventana de gráficos dibujando un objeto, borrándolo
(dibujándolo de nuevo en blanco - piense en “blanco”), y luego volviendo a dibujar el
objeto en una posición ligeramente diferente.
Introducción a RAPTORgraph
Para utilizar RAPTORgraph, debe crear una ventana gráfica. Esta ventana gráfica debe
crearse antes de llamar a cualquier otro procedimiento o función de RAPTORgraph.
Open_Graph_Window (X_Size, Y_Size)
Si utilizó la llamada al procedimiento anterior en su programa, se crearía una ventana
gráfica de 500 píxeles de ancho por 300 píxeles de alto. Esta ventana gráfica se
representa enFigura 2 abajo.
+ Eje Y
This corner is pixel (1, 300) This corner is pixel (500, 300)
This corner is pixel (1, 1) This corner is pixel (500, 1)
+ Eje X
Figura 2. Sistema de coordenadas de la ventana de gráficos
La ventana gráfica siempre comienza con un fondo blanco. El origen del sistema de
coordenadas (X, Y) de la ventana gráfica está en la esquina inferior izquierda de la
ventana. El eje X comienza desde 1 yendo de izquierda a derecha. El eje Y comienza
desde 1 y va de abajo hacia arriba.
Una vez que su programa haya terminado con todos los demás comandos gráficos, debe
eliminar la ventana gráfica con la siguiente llamada al procedimiento:
MI-2
Close_Graph_Window
Todas las demás llamadas a los procedimientos de RAPTORgraph deben estar entre las
llamadas que crean y destruyen la ventana gráfica. El siguiente programa de ejemplo
(Figura 3) ilustra dónde se colocan los distintos comandos en su programa RAPTOR
(Simple [Link]).
Figura 3. Programa simple RAPTORgraph
Salida de gráficos con RAPTORgraph
RAPTORgraph tiene una colección de procedimientos que dibujan formas en la ventana
gráfica. Todas estas rutinas permiten al programador especificar las ubicaciones (X, Y)
donde el elemento debe aparecer en la ventana gráfica.
Por ejemplo, el procedimiento Draw_Circle puede dibujar un círculo relleno que está
centrado en una coordenada (X, Y) en la ventana gráfica y que tiene un radio y un color
particulares.
MI-3
Las llamadas a Draw_Circle tienen el siguiente formato:
Draw_Circle (X, Y, Radio, Color, Relleno)
Donde X e Y son las posiciones horizontal y vertical del punto central del círculo, Radio
es la distancia (en píxeles) desde el punto central al borde del círculo, Color es el color
del círculo y Relleno es Verdadero / Lleno o Falso / Sin llenar. Un valor de Verdadero (o
Lleno) produce un círculo sólido, mientras que un valor de Falso (o Sin completar) solo
dibuja el borde exterior del círculo. Por ejemplo,
Draw_Circle (250, 150, 140, azul, relleno)
produce un círculo azul sólido centrado en (250, 150) con un radio de 140 píxeles.
El orden de los comandos de gráficos es importante porque cada forma se dibuja "sobre"
formas previamente dibujadas. Por ejemplo, se puede hacer una "diana" dibujando
círculos concéntricos comenzando con el círculo más grande y externo primero. El efecto
del programaConcentric_Circles.rap a continuación se puede ver en el Figura 4 ventana
gráfica.
MI-4
Figura 4. Círculos concéntricos dibujados desde el exterior hacia el centro
Las rutinas de dibujo de formas disponibles en RAPTORgraph son:
Put_Pixel Establece un solo píxel en el color deseado
Dibujar linea Dibuja una línea dadas sus dos coordenadas de punto final (X, Y)
Draw_Box Dibuja un rectángulo dadas las coordenadas de la esquina superior
izquierda e inferior derecha (X, Y)
Draw_Circle Dibuja un círculo dado su centro y radio.
Draw_Ellipse Dibuja una elipse dadas las coordenadas de la esquina superior
izquierda e inferior derecha (X, Y) del rectángulo que delimita la
elipse.
Draw_Arc Dibuja un arco (una sección de una elipse) dadas las coordenadas
de la esquina superior izquierda e inferior derecha (X, Y) del
rectángulo que delimita la elipse y las coordenadas inicial y final.
Ventana limpia Borra (borra) toda la ventana gráfica.
Con formas cerradas como rectángulos, elipses y círculos, opcionalmente podemos
especificar para rellenar la forma. Si se crea una forma cerrada mediante una serie de
llamadas gráficas (como una colección de Draw_Lines), entonces el comando Flood_Fill
se puede utilizar para rellenar el área encerrada.
Flood_Fill Rellena un área cerrada que contiene la coordenada (X, Y) dada
con el color dado.
El texto y los números se pueden mostrar en la ventana gráfica especificando una cadena
de caracteres (por ejemplo, "Las manzanas son rojas") y la posición del texto.
MI-5
Display_Text Dibuja una cadena de caracteres, donde la coordenada dada (X, Y)
marca la esquina superior izquierda del primer carácter de texto
Display_Number Dibuja un número, donde la coordenada dada (X, Y) marca la
esquina superior izquierda del primer dígito más a la izquierda del
número
Para especificar el color de un objeto, use uno de los siguientes valores:
Negro Magenta Verde claro Blanco
Azul marrón Cian claro
Verde Gris claro Luz roja
Cian Gris oscuro Magenta claro
rojo Azul claro Amarillo
Ejemplo de llamadas a rutinas de salida
1) Para hacer que el píxel en la posición (20,30) sea negro, llame al procedimiento
Put_Pixel como se muestra:
En general, Put_Pixel (X, Y, Color) hace que el píxel en la coordenada (X, Y) tenga el
valor de Color.
2) Para dibujar una línea azul claro desde la coordenada (15,99) a la coordenada (12,13),
llame a:
En general, Draw_Line (X1, Y1, X2, Y2, Color) crea una línea de un píxel de ancho
desde la coordenada inicial (X1, Y1) hasta la coordenada final (X2, Y2) con el color
especificado.
También podemos usar variables para pasar las coordenadas a los procedimientos de
dibujo. Por ejemplo, si se va a dibujar una línea marrón desde (1,1) hasta el punto cuyas
coordenadas xey están almacenadas en las variables My_X y My_Y, respectivamente,
usaríamos la siguiente llamada: Draw_Line (1, 1, My_X, Mi_Y, Marrón). Se dibujará una
línea diferente en función de los valores de las variables My_X y My_Y. El siguiente
MI-6
programa hace que el usuario ingrese valores para las variables My_X y My_Y, pero las
variables podrían haber obtenido sus valores a través de una instrucción de asignación o
de otras llamadas a procedimientos.
3) Para dibujar un cuadro sólido de color cian con esquinas en (38, 100) y (76,20), llame
a:
En general, Draw_Box (X1, Y1, X2, Y2, Color, Filled) dibuja un cuadro cuya esquina
superior izquierda está en la coordenada (X1, Y1) y cuya esquina inferior derecha está en
(X2, Y2). Esta es la primera forma que hemos discutido que encierra un área. Cuando
especificamos que un objeto se llene, sus píxeles interiores se cambian al valor de Color.
Si queremos que el objeto sea un "marco de alambre" (es decir, solo dibujar los bordes
del objeto), use Sin relleno para el valor final.
En la llamada a continuación, dibujamos un cuadro negro sólido usando ecuaciones para
calcular sus ubicaciones en las esquinas.
Si las variables Ancho y Alto se usaron para crear la ventana gráfica, ¿qué podemos
inferir sobre la ubicación y el tamaño de este cuadro?
4) Para dibujar un círculo verde relleno con un radio de 9 píxeles centrados en las
coordenadas (X_Circle, Y_Circle), use:
MI-7
En general, Draw_Circle (X_Center, Y_Center, Radius, Color, Filled) dibuja un círculo
cuyo tamaño se define como píxeles de radio y cuyo punto central está en la coordenada
(X_Center, Y_Center).
5) Dibujar elipses y arcos puede ser un poco menos intuitivo que las formas anteriores.
Para elipses, especificamos las coordenadas (X, Y) del rectángulo más pequeño que
delimita la elipse. La siguiente figura muestra la salida de los comandos RAPTOR a la
derecha. Tenga en cuenta que la elipse rellena se dibuja con las mismas coordenadas que
el cuadro sin rellenar.
Start
Open_Graph_Window(300, 100)
Caja superior izquierda Draw_Box( 50, 75, 250, 25, Blue, Unfilled)
(50, 75)
La ventana gráfica es de 300 Draw_Ellipse( 50, 75, 250, 25, Red, Filled)
x 100
Cuadro inferior derecho End
(250, 25)
6) Para los arcos especificamos el cuadro delimitador (como hicimos para una elipse), y
también especificamos los puntos de inicio y finalización - (startx, starty) y (endx, endy).
El arco dibujado comienza en la elipse en el punto de intersección de la elipse con una
línea desde el centro de la elipse hasta el punto (startx, starty). El arco termina en la
elipse en la intersección de la elipse con una línea del centro al punto (endx, endy). El
arco se dibuja en sentido antihorario. Start
La siguiente figura ilustra cómo se dibuja un arco; fue creado usando las llamadas
Open_Graph_Window(300, 100)al
procedimiento RAPTORgraph a la derecha de la figura.
Draw_Box( 50, 25, 250, 75, Blue, Unfilled)
Center point Draw_Line( 50, 25, 150, 50, Green)
Starting intersection
Draw_Line(200, 75, 150, 50, Green)
Ending intersection
The arc is drawn along the ellipse border in a counter-clockwise
Draw_Arc( 50, 25, 250, 75, 50, 25, 200, 75, Red)
direction from the starting intersection to the ending intersection
End
MI-8
7) Si hemos dibujado formas de tal manera que encerramos una región delimitada de la
ventana gráfica, podemos llenar esa área encerrada usando una rutina de relleno por
inundación. Debemos tener cuidado al usar un relleno de inundación, porque si el área no
está totalmente cerrada, el relleno se “filtrará” y posiblemente llenará toda la ventana
gráfica. El procedimiento Flood_Fill de RAPTORgraph comienza a llenar los píxeles
interiores de una región delimitada en una coordenada de píxeles especificada (X, Y) y
continúa llenándose hasta que se detiene en el límite circundante.
A continuación, vemos que se crea un triángulo de ejemplo y luego una inundación del
área dentro del triángulo. El código de la imagen está a la derecha. Start
Open_Graph_Window(300, 100)
Draw_Line( 150, 75, 50, 25, Black)
Draw_Line(150, 75, 250, 25, Black)
Draw_Line( 50, 25, 250, 25, Black)
Flood_Fill(150, 50, Yellow)
End
8) A menudo es bueno poner texto y números en nuestra ventana gráfica. Sin embargo, no
podemos usar nuestro comando de salida estándar para dibujar en la ventana gráfica. En
su lugar, usamos un procedimiento que nos permite especificar dónde colocar el texto y
los números en la ventana gráfica y de qué color deben ser. Tenga en cuenta que las
coordenadas (X, Y) pasadas a la rutina Display_Text especifican la esquina superior
izquierda de la posición del texto.
En general, Display_Text (X, Y, Text, Color) dibuja una cadena de caracteres
comenzando en la coordenada (X, Y) y continúa dibujando de izquierda a derecha. La
altura predeterminada del texto es de 8 píxeles. Por lo general, permita unos 12 píxeles en
la dirección vertical entre 2 líneas de texto del tamaño predeterminado. Para cambiar el
tamaño del texto, llame a Set_Font_Size (Height_in_pixels).
El procedimiento Display_Number es similar a Display_Text, excepto que recibe un
número para dibujar. Además, puede combinar texto y números utilizando una expresión
de cadena en Display_Text. Por ejemplo,
MI-9
Display_Text (10, 20, "La respuesta es" + Respuesta,
Negro)
9) Podemos borrar todos los dibujos en la ventana gráfica llamando al procedimiento
Clear_Window. El valor de Color enviado al procedimiento define el color de fondo
utilizado para llenar la ventana gráfica. Como ejemplo, el código siguiente borra la
ventana gráfica a todo negro.
Como resumen, aquí están los formatos para cada uno de estos procedimientos de dibujo:
Put_Pixel (X, Y, Color)
Draw_Line (X1, Y1, X2, Y2, Color)
Draw_Box (X1, Y1, X2, Y2, Color, relleno / sin relleno)
Draw_Circle (X, Y, Radio, Color, Relleno / Sin relleno)
Draw_Ellipse (X1, Y1, X2, Y2, Color, lleno / sin relleno)
Draw_Arc (X1, Y1, X2, Y2, StartX, StartY, EndX, EndY, Color)
Flood_Fill (X, Y, Color)
Display_Text (X, Y, Text_Expression, Color)
Display_Number (X, Y, Number, Color)
Clear_Window (color)
MI-10
Para ponerlo todo junto, el gráfico que se muestra a continuación en fue producido por el
programa RAPTOR a la derecha que usa todos estos procedimientos RAPTORgraph.
Figura 5. Salida de muestra de RAPTORgraph
Entrada con RAPTORgraph
Si bien RAPTORgraph es bastante simple, es lo suficientemente poderoso como para
dibujar algunas imágenes complicadas. Sin embargo, además de poder hacer dibujos
sofisticados, queremos que nuestros programas gráficos sean interactivos para que el
usuario pueda dirigir lo que sucede en la ventana. Ahora discutiremos las rutinas de
entrada tanto para el mouse como para el teclado. Las rutinas de entrada disponibles son:
Wait_For_Key Un procedimiento que simplemente espera hasta que se presiona una tecla
del teclado.
Key_Hit Una función que devuelve el valor booleano True si se ha presionado una tecla
desde la última llamada a Get_Key. Dado que Key_Hit es
una llamada de función, solo se puede usar en la parte "a" de
una instrucción de asignación o en bloques de decisión
(diamantes).
Get_Key Una función que devuelve el carácter escrito por el usuario. Si ningún carácter
está listo para ser procesado, Get_Key espera hasta que el
usuario presione una tecla.
Wait_For_Mouse_Button Un procedimiento que simplemente espera hasta que se
presiona el botón especificado del mouse (ya sea Left_Button
o Right_Button).
Por ejemplo: Wait_For_Mouse_Button (Left_Button)
Mouse_Button_Pressed Una función que devuelve el valor booleano Verdadero si el
botón especificado (Left_Button o Right_Button) ha sido
presionado desde la última llamada a Get_Mouse_Button.
Como función, solo se utiliza en construcciones de
asignación o decisión.
Get_Mouse_Button Un procedimiento que toma un botón (ya sea Left_Button o
Right_Button) y devuelve las coordenadas de un clic de ese
botón. Si no hay ningún clic listo para ser procesado,
Get_Mouse_Button espera hasta que el usuario presione el
botón deseado. Por ejemplo, Get_Mouse_Button
(Right_Button, My_X, My_Y) espera un clic del botón
derecho del mouse y luego coloca la ubicación del clic en las
variables My_X y My_Y.
Get_Mouse_XA función que devuelve la coordenada X de la ubicación actual del mouse.
Por lo general, se usa en una construcción de asignación para
guardar la ubicación X en una variable para su uso posterior.
Función Get_Mouse_YA que devuelve la coordenada Y de la ubicación actual del mouse.
Por lo general, se usa en una construcción de asignación para
guardar la ubicación Y en una variable para su uso posterior.
Es importante tener en cuenta que algunas de las llamadas anteriores detendrán su
programa hasta que se presione una tecla o un botón del mouse. Otras llamadas no
esperan, sino que simplemente devuelven un verdadero o falso o coordenadas (X, Y). Si
no desea que su programa espere a que se presione una tecla o se haga clic en el botón del
mouse, puede usar Key_Hit o Mouse_Button_Pressed para verificar si tal evento ha
ocurrido.
Ejemplo de uso de rutinas de entrada de RAPTORgraph
Para comprender cómo puede
utilizar estas rutinas de entrada
de RAPTORgraph, lea
atentamente el programa
RAPTOR a la derecha. El
programa abre una ventana
gráfica y muestra un mensaje
para que el usuario presione una
tecla. Luego espera hasta que el
usuario lo haga. Una vez que el
usuario pulsa una tecla, el
programa borra la ventana
gráfica y la llena con un fondo
amarillo. Luego, el programa
espera a que el usuario realice
dos clics izquierdos. Captura y
guarda las ubicaciones (X, Y) de
estos dos clics izquierdos en las
variables (My_X1, My_Y1) y
(My_X2, My_Y2)
respectivamente. Luego dibuja
un cuadro azul usando las dos
ubicaciones de clic izquierdo.
Finalmente, el programa espera
un clic derecho y luego cierra la
ventana gráfica y termina. Para
ejecutar la demostración, haga
clic
aquí:Graphics_Input_Demo.rap
Animación con RAPTORgraph
SA veces queremos hacer que un
objeto se mueva por la ventana
gráfica. Recuerde que el movimiento
se puede simular dibujando un objeto,
borrándolo (dibujándolo nuevamente
en blanco) y luego volviéndolo a
dibujar en una nueva posición. Para
hacer que los objetos se muevan
suavemente y a una velocidad
razonable, es posible que deseemos
intentar mover el objeto más de un
píxel a la vez y con un pequeño
retraso entre los momentos en que se
dibuja el objeto. Podemos lograr esto
con un bucle como el del programa de
la derecha, que mueve un círculo
verde verticalmente hacia abajo de la
ventana gráfica. Para ejecutar el
programa, haga clic aquí:
Animation_Demo.rap.
Resumen del comando RAPTORgraph
Procedimientos y funciones de apertura y cierre de ventanas gráficas
Open_Graph_Window (X_Size, Y_Size)
Close_Graph_Window
Get_Max_Width -> devuelve el ancho máximo de píxeles de la
pantalla
Get_Max_Height -> devuelve la altura máxima de píxeles de la
pantalla
Get_Window_Width -> devuelve el ancho de píxel de la ventana
actual
Get_Window_Height -> devuelve la altura de píxel de la ventana
actual
Is_Open -> devuelve True si hay una ventana gráfica abierta
Set_Window_Title (Título)
Procedimientos y funciones de entrada de teclado
Wait_For_Key
Key_Hit -> devuelve True / False
Get_Key -> devuelve el valor ASCII de la pulsación de tecla
Get_Key_String -> devuelve una cadena que define la tecla
presionada
Procedimientos y funciones de entrada del mouse
Wait_for_Mouse_Button (Which_Button)
Mouse_Button_Pressed (Which_Button) -> devuelve True / False
Mouse_Button_Released (Which_Button) -> devuelve True / False
Get_Mouse_Button (Which_Button, X, Y) -> devuelve Which_Button, X e Y
Get_Mouse_X -> devuelve X
Get_Mouse_Y -> devuelve Y
Procedimientos de dibujo
Put_Pixel (X, Y, Color)
Draw_Line (X1, Y1, X2, Y2, Color)
Draw_Box (X1, Y1, X2, Y2, Color, relleno / sin relleno)
Draw_Circle (X, Y, Radio, Color, Relleno / Sin relleno)
Draw_Ellipse (X1, Y1, X2, Y2, Color, lleno / sin relleno)
Draw_Arc (X1, Y1, X2, Y2, StartX, StartY, EndX, EndY, Color)
Clear_Window (color)
Flood_Fill (X, Y, Color)
Display_Text (X, Y, Text_Expression, Color)
Display_Number (X, Y, Number, Color)
Procedimientos de suavizado de animaciones
Freeze_Graph_Window -> a partir de ahora, las llamadas gráficas se
almacenan en búfer
Update_Graph_Window -> dibujar inmediatamente todas las llamadas de
gráficos almacenados en búfer
UnFreeze_Graph_Window -> de ahora en adelante, las llamadas gráficas se
dibujan inmediatamente
Funciones y procedimientos diversos
Get_Pixel (X, Y) -> devuelve el código numérico para el color del píxel en
(X, Y)
Set_Font_Size (Tamaño)
Get_Font_Height -> devuelve la altura en píxeles de la fuente actual
Get_Font_Width -> devuelve el ancho en píxeles de la fuente actual
Random_Color -> devuelve un color aleatorio (0-15, es decir, de negro a
blanco)
Random_Extended_Color -> devuelve un valor de color aleatorio 0-241
Closest_Color (R, G, B) -> devuelve un "color" basado en la intensidad de
la cantidad de rojo (R), verde (G) y azul (B) que desea en el color R, G y
B deben estar entre 0 y 255.