INTRODUCCION A LOS GRAFICOS

9.1.- FUNDAMENTOS DE LOS GRÁFICOS. ESCALAS DE LA PANTALLA.

 

INTRODUCCIÓN.

 

Lo que se puede hacer con las sentencias gráficas, depende de los controladores que Windows emplee para controlar la pantalla y la impresora. Sin embargo, el uso de estos controladores es automático. A menos que se establezca la propiedad AutoRedraw del formulario a True, será necesario gestionar el volver a dibujar los gráficos. Cuando esta propiedad está a True, se crea una copia del objeto en memoria para poder reproducir automáticamente los dibujos pintados con métodos gráficos cuando la ventana cambia de tamaño o es ocultada total o parcialmente por otra ventana. Esta operación tiene un coste de memoria. Si la propiedad tiene un valor False, los gráficos no serán reproducidos. Visual Basic activa el suceso Paint cada vez que se visualiza un formulario o una parte nueva del mismo. Si la propiedad ClipControls, que determina si los métodos gráficos contenidos en un procedimiento conducido por el suceso Paint perteneciente a un objeto, repintan el objeto entero o solo la parte que se vuelve a visualizar. Si está a False y AutoRedraw a False, Visual Basic vuelve a pintar sólo el área que se muestra nueva. Sólo se llama al procedimiento Paint cuando la propiedad AutoRedraw está a False.

 

EJEMPLOS:

 

  1.  

Sub Form_Load()

Print "Por favor, Haz clic para una demostración de AutoRedraw"

Print "Estas dos líneas permanecerán en la pantalla después de hacer doble clic"

End Sub

Sub Form_Click()

AutoRedraw = False

Cls

Print : Print : Print

Print "Pero esta línea desaparecerá después del doble clic"

End Sub

 

Sub Form_DblClick()

Cls

End Sub

 

  1. Crear un nuevo formulario que tenga dos controles picture : uno con la propiedad ClipControls establecida a True y el otro a False. Cuando se ejecute este proyecto, se deberá arrastrar algún formulario hasta tapar parcialmente los círculos que aparecerán en los cuadros de imagen. Al retirarlo de nuevo, el color del círculo de Picture1 se cambia totalmente y, el de Picture2, cambia sólo en la parte que se expone nuevamente.

 

Sub Picture1_Paint()

Dim color As Long

Picture1.ScaleMode = 3

color = &HFFFFFF * Rnd

Picture1.FillStyle = 0

Picture1.FillColor = color

Picture1.Circle (43, 41), 30, color

End Sub

 

Sub Picture2_Paint()

Dim color As Long

Picture2.ScaleMode = 3

color = &HFFFFFF * Rnd

Picture2.FillStyle = 0

Picture2.FillColor = color

Picture2.Circle (43, 41), 30, color

End Sub

 

El método Refresh obliga a un refresco inmediato del formulario o del control. Este procedimiento se utiliza normalmente en el procedimiento Form_Resize para volver a presentar cualquier gráfico que se haya calculado en el procedimiento Paint. Para guardar los gráficos que se han dibujado en un formulario o caja de figuras se utiliza la orden :

SavePicture [NombreObjeto.] Image, NombreArchivo

 

ESCALAS DE LA PANTALLA.

 

La escala por omisión para los formularios y cajas de figuras viene medida en Twips. El tamaño por omisión de un formulario en una VGA normal es de 7.485 Twips de largo por 4.425 Twips de ancho. Veamos un ejemplo de coordenadas posibles en el formulario.

 

COORDENADAS POSICIÓN
(0,0) Esquina superior izquierda
(7485,0) Esquina superior derecha
(0,4425) Esquina inferior izquierda
(7485,4425) Esquina inferior derecha
(3742,2212) Aproximadamente en el centro

 

Para cambiar la unidad de medida se utiliza la propiedad ScaleMode.

 

EJEMPLO

Simularemos el movimiento de un botón superponiendo diferentes dibujos del mismo. Se necesita un botón de comando con sus valores por omisión (hacer doble clic sobre la herramienta)

 

Sub Command1_Click()

'Movimiento de un cuadrado simulando un paseo aleatorio

Dim x As Single, y As Single

Dim i As Integer

Randomize

Form1.ScaleMode = 3 'Unidad de medida Pixels

x = Form1.ScaleWidth / 2

y = Form1.ScaleHeight / 2

For i = 0 To 50

xmove = 3 * Rnd

ymove = 2 * Rnd

If Rnd < 0.5 Then

x = x + xmove

y = y + ymove

Else

x = x - xmove

y = y - ymove

End If

If x < 0 Or x > ScaleWidth Or y < 0 Or y > ScaleHeight Then

'No hacer nada

Else

Command1.Move x, y

End If

Next i

End Sub

 

ESCALAS PERSONALIZADAS.

 

El método Scale establece un nuevo sistema de coordenadas para los formularios y las cajas de figuras que se pueden usar con cualquiera de los métodos gráficos. Su sintaxis es :

[objeto.] Scale (x1, y1)-(x2, y2)

donde x1 e y1 se corresponden con ScaleLeft y ScaleTop y x2 e y2 con las sumas ScaleWidth + ScaleLeft y ScaleHeight + ScaleTop respectivamente. P.e.

Scale (-320,100)-(320,-100)

establece el nuevo sistema de coordenadas en el que las coordenadas de la esquina superior izquierda es (-320,100) y las de la esquina inferior derecha es (320,-100). La sintaxis del método Scale es :

Scale (Xizquierda, Yarriba)- (Xderecha, Yabajo)

Si se establece Scale sin coordenadas, se restablecerán las coordenadas por omisión.

 

Otra forma de establecer coordenadas personalizadas consiste en establecer las coordenadas de la esquina superior izquierda de la forma en la que se deben medir las escalas vertical y horizontal, utilizando las propiedades ScaleLeft, ScaleTop, ScaleWidth, y ScaleHeight.

 

EJEMPLO

(0,0)   (1,0)   ScaleLeft = 0
        ScaleHeight = -1
        ScaleWidth = 1
        ScaleTop = 0
(0,-1)   (1,-1)    

 

(-40,40)   (40,40)   ScaleLeft = -40
        ScaleHeight = -80
  l     ScaleWidth = 80
  (0,0)     ScaleTop = 40
         
(-40,-40)   (40,-40)   Scale (-40,40)-(40,-40)

 

Para dibujar líneas se utiliza el método Line, cuya sintaxis es :

Line (ColumnaInicial, FilaInicial)-(ColumnaFinal, FilaFinal), CódigoColor

Visual Basic recuerda el último punto referenciado y sus coordenadas están guardadas en las variables CurrentX y CurrentY, de forma que, para dibujar a continuación de este punto se utiliza :

Line -(ColumnaFinal, FilaFinal), CódigoColor

 

EJEMPLO

Programa que dibuja la ecuación y = x2 - 3x + 12 en el dominio -10 <= x <= 10

 

Function FdeX(ByVal x As Single) As Single

FdeX = (x ^ 2) - (x * 3) + 12

End Function

 

Sub Form_Paint()

Dim x As Single

'Configura la pantalla

Cls

Scale (-150, 150)-(150, -150) 'Sistema de coordenadas cartesianas estándar

'Dibujar los ejes

Line (-150, 0)-(150, 0)

Line (0, -150)-(0, 150)

CurrentX = -10

CurrentY = FdeX(-10)

For x = -10 To 10

Line -(x, FdeX(x)) 'Dibujar la línea desde la última posición conocida

Next x

End Sub

 

 

9. 2.- COLORES Y PIXELS.

 

COLORES.

 

Se puede utilizar la función RGB cuya sintaxis es:

RGB (CantidadRojo, CantidadVerde, CantidadAzul)

Siendo cada cantidad un entero entre 0 y 255 aunque también se podrá incluir al proyecto el archivo Constant.Txt y utilizar los códigos allí definidos.

 

Otra función que se puede utilizar es QBColor con la sintaxis :

QBColor (CódigoColor)

donde CódigoColor es un entero entre 0 y 15

 

EJEMPLO

Para dibujar los ejes del ejemplo anterior de color verde se modificarán las líneas siguientes:

Line (-150, 0)-(150, 0)

Line (0, -150)-(0, 150)

por estas otras

Line (-150, 0)-(150, 0), RGB(0,255,0)

Line (0, -150)-(0, 150), RGB(0,255,0)

 

CONTROL DE PIXELES.

 

La sintaxis para dibujar un pixel es :

PSet (Columna, Fila)[, Códigocolor]

Si se exceden los límites de la pantalla, se obtendrá un error de desbordamiento. Si se dibuja un punto fuera del formulario, Visual Basic guarda la posición si la propiedad AutoRedraw está a True. Si luego el formulario se maximiza, se dibujará el punto.

 

EJEMPLOS

  1. Trazado de una línea mediante Pset con un pequeño recorte.

 

Sub Form_Click()

Dim i As Integer

AutoRedraw = True

For i = 0 To 5000

PSet (3742, i) 'Dibujar una línea vertical

Next i

For i = 0 To 7485

PSet (i, 3500) 'Dibujar una línea horizontal

Next i

End Sub

 

  1. Vamos a construir un pequeño TeleSketch, para lo que necesitaremos utilizar el suceso KeyDown para detectar las teclas del cursor. Cuando el usuario se desplaza con las teclas de cursor, se van iluminando los pixeles por los que pasa. Se necesitarán un formulario para el área de dibujo con la propiedad AutoRedraw a True. Se necesita añadir el archivo Constant.Txt.

 

Dim AlturaPixel As Single, AnchuraPixel As Single

Dim XPunto As Single, YPunto As Single

 

Sub Form_Load()

AutoRedraw = True

ScaleMode = 3 'Pixels

AlturaPixel = ScaleHeight

AnchuraPixel = ScaleWidth

XPunto = AnchuraPixel / 2

YPunto = AlturaPixel / 2

End Sub

 

Sub Form_Resize()

AlturaPixel = ScaleHeight

AnchuraPixel = ScaleWidth

End Sub

 

Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)

Dim sino As Integer

Select Case KeyCode

Case Key_Left

If XPunto <= 0 Then

XPunto = 0

Else

XPunto = XPunto - 1

End If

Case Key_Right

If XPunto >= AnchuraPixel Then

XPunto = AnchuraPixel

Else

XPunto = XPunto + 1

End If

Case Key_Up

If YPunto <= 0 Then

YPunto = 0

Else

YPunto = YPunto - 1

End If

Case Key_Down

If YPunto >= AlturaPixel Then

YPunto = AlturaPixel

Else

YPunto = YPunto + 1

End If

Case Key_End

sino = MsgBox("¿Estás seguro de que quieres terminar", 4)

If sino = 6 Then End 'Clic en si

Case Else

Beep

End Select

PSet (XPunto, YPunto)

End Sub

 

  1. Simulación de la explosión de una estrella dibujando líneas aleatorias en colores aleatorios, desde el centro de la pantalla. Se utiliza una escala personalizada donde (0,0) es el centro de la pantalla. Puesto que el número de pixels en el tamaño por omisión de formulario es de 491 de ancho por 268 de alto, (-245,134) es la esquina superior izquierda y (245,134) la esquina inferior derecha.

 

Sub Form_Click()

Dim i As Integer, CodColor As Integer

Dim Columna As Single, Fila As Single

Randomize

Cls

Scale (-245, 134)-(245, -134)

For i = 1 To 100

Columna = 245 * Rnd

If Rnd < 0.5 Then Columna = -Columna

Fila = 134 * Rnd

If Rnd < 0.5 Then Fila = -Fila

CodColor = 15 * Rnd

Line (0, 0)-(Columna, Fila), QBColor(CodColor)

Next i

End Sub

 

En ocasiones resulta útil utilizar coordenadas relativas, en las que cada punto viene definido por cuánto de lejos está del último punto referenciado. P.e.

PSet (12,100)

PSet Step(50,10)

el nuevo punto será (62,110) o lo que es lo mismo, (12+50,100+10)

 

EJEMPLO

Crear un formulario con una caja de imágenes. Este proyecto dibujará en el formulario y en la caja, las curvas correspondientes a la función sen(x) y cos(x) para valores comprendidos entre 0 y 6.3. El sistema de coordenadas que se define permite mostrar valores de x entre 0 y 6.3 y, valores de y entre -1 y 1. Si se establece la propiedad AutoRedraw a False y, al ejecutar el propyecto, el formulario se minimza, al restauralo, las curvas no serán dibujadas.

 

Sub Curvas()

'Parámetros para el formulario

ScaleLeft = 0

ScaleTop = 1

ScaleWidth = 6.3

ScaleHeight = -2

DrawWidth = 2 'Grosor de la línea

FontSize = 18 'Tamaño de los caracteres

'Coordenadas del punto central del formulario

cx = ScaleWidth / 2 + ScaleLeft

cy = ScaleHeight / 2 + ScaleTop

Cls

msg = "Curvas"

'Coordenadas para escribir msg centrado

CurrentX = cx - TextWidth(msg) / 2

CurrentY = cy - TextHeight(msg) / 2

ForeColor = QBColor(2) 'Color verde

Print msg

ForeColor = QBColor(0) 'Color negro

'Parámetros para la imagen

Picture1.Scale (0, 1)-(6.3, -1)

Picture1.Cls

Picture1.CurrentX = cx - Picture1.TextWidth(msg) / 2

Picture1.CurrentY = cy - Picture1.TextHeight(msg) / 2

Picture1.ForeColor = QBColor(2)

Picture1.Print msg

Picture1.ForeColor = QBColor(0)

'Dibujar curvas

For x = 0 To 6.3 Step 0.05

yc = Cos(x)

ys = Sin(x)

PSet (x, yc): Picture1.PSet (x, yc) 'Coseno

PSet (x, ys): Picture1.PSet (x, ys) 'Seno

Next x

End Sub

 

Sub Form_Click()

Curvas

End Sub

 

ANCHURA Y ESTILO DE DIBUJO.

 

Para cambiar el grosor de los puntos o de las líneas, se utiliza la propiedad DrawWidth, cuya forma de empleo es :

Objeto.DrawWidth = Tamaño%

El ajuste de esta propiedad se mide en pixels.

 

Para cambiar el estilo de la línea, la propiedad a utilizar es DrawStyle, que se verá modificada cuando DrawWidth sea 1.

 

Para rellenar las cajas o círculos, se modificará las propiedades FillStyle y FillColor.

 

EJEMPLOS

  1. Demostración de la propiedad DrawWidth

 

Sub Form_Click()

WindowState = 2 'Maximizar

Dim i As Integer

For i = 1 To 10

DrawWidth = i

Line (0, i * ScaleHeight / 12)-(ScaleWidth - 15 * TextWidth("D"), i * ScaleHeight / 12)

Print "DrawWidth = ", i

Next i

End Sub

 

  1. Dibujar cajas anidadas.

 

Sub Form_Click()

Dim i As Integer

Scale (0, 0)-(639, 199)

For i = 1 To 65 Step 5

Line (5 * i, i)-(639 - 5 * i, 199 - i), , B 'Dibujar una caja

Next i

End Sub

 

  1. Demostración que no emplea líneas interiores.

 

Sub Form_Click()

WindowState = 2

DrawWidth = 10

Line (100, 100)-(ScaleWidth / 2, ScaleHeight / 2), , B

Line (ScaleWidth / 2, ScaleHeight / 2)-(ScaleWidth - 100, ScaleHeight - 100), , B

End Sub

 

  1. Demostración empleando líneas interiores para hacer que los límites de la caja queden la mitad dentro y la otra mitad fuera.

 

Sub Form_Click()

WindowState = 2

DrawStyle = 6

DrawWidth = 10

Line (100, 100)-(ScaleWidth / 2, ScaleHeight / 2), , B

Line (ScaleWidth / 2, ScaleHeight / 2)-(ScaleWidth - 100, ScaleHeight - 100), , B

End Sub

 

  1. Modificación del ejemplo 2 para que las cajas se rellenen.

 

Sub Form_Click()

Dim i As Integer

Scale (0, 0)-(639, 199)

For i = 1 To 65 Step 5

CodigoColor = QBColor(i Mod 16) 'Dibujar siguiendo el orden de los colores

Line (5 * i, i)-(639 - 5 * i, 199 - i), CodigoColor, BF

Next i

End Sub

 

  1. Demostración de FillStyle

 

Sub Form_Click()

Dim i As Integer

Scale (0, 0)-(25, 25)

For i = 0 To 7

FillStyle = i

Line (0, 3 * i)-(4, 3 * (i + 0.8)), , B

CurrentX = 4.1

CurrentY = 3 * i + 0.5

Print "Este está hecho con FillStyle #"; i

Next i

End Sub

 

  1. Este proyecto crea una tabla de información sobre algunos artículos.

 

Private Sub Form_Load()

AutoRedraw = -1

Print: Print: Print

Print Tab(12); "Artículo"; Tab(32); "Precio"

'Tab indica la posición donde se desea que comience la impresión de

‘una determinada expresión

Print

Print Tab(12); "Garbanzos"; Tab(32); 500

Print Tab(12); "Lentejas"; Tab(32); 300

Print Tab(12); "Manzanas"; Tab(32); 400

Print Tab(12); "Plátanos"; Tab(32); 200

DrawWidth = 2

Line (700, 350)-(3650, 1950), , B

Line (700, 880)-(3650, 880)

End Sub

 

 

9.3.- CÍRCULOS, ELIPSES Y GRÁFICOS DE SECTORES.

 

CÍRCULOS.

 

Para describir un círculo se dará su centro y su radio y la función que dibuja los círculos es :

Circle (Centro), Radio, CódigoColor

 

EJEMPLO

Dibujar círculos anidados

Sub Form_Click()

Static CodColor As Integer

Dim i As Single

WindowState = 2

Scale (-1, 1)-(1, -1)

For i = 0.1 To 0.7 Step 0.5

CodColor = 15 * Rnd

Circle (0, 0), i, CodColor

Next i

End Sub

 

Un sector es una parte de un gráfico y un arco es el límite exterior de un sector. Para dibujar un sector o un arco hay que decirle a Visual Basic dónde tiene que empezar y dónde tiene que terminar, para lo que se tendrá que emplear los radianes como unidad de medida. Para transformar grados en radianes se multiplica por 180/p . Para dibujar un arco de circunferencia comenzando en el punto dado en radianes en AnguloInicial y terminando en AnguloFinal, se utilizará :

Circle (Xrad, Yrad), Radio, CódigoColor, AnguloInicial, AnguloFinal

Para obtener un sector se usan signos negativos.

 

EJEMPLO

Dibujaremos un sector y un arco.

Sub Form_Click()

Pi = 4 * Atn(1) 'Calcular el valor de Pi

Scale (-1, 1)-(1, -1)

Circle (-0.4, 0), 0.5, , -Pi / 4, -3 * Pi / 4 'Dibujar el sector

Circle (0.4, 0), 0.5, , Pi / 4, 3 * Pi / 4 'Dibujar el arco

End Sub

 

ELIPSES.

 

Para dibujar elipses se modificará el método Circle de la siguiente manera :

Circle [Paso] (Xcentro, Ycentro), radio,,,, aspecto

Si el parámetro aspecto es menor que 1, el radio se toma en la dirección de las columnas y la elipse tendrá su eje menor en dirección vertical.

 

EJEMPLOS

1.- Sub Form_Click()

Scale (-2, 2)-(2, -2)

Static I As Single

Cls

Circle (0, 0), 0.5, , , , I + 0.1

CurrentX = -2

CurrentY = 2

Print "Esta es la relación de aspecto "; Format$(I + 0.1, "#.#");

Print ". Haga clic para ver el siguiente tamaño de elipse"

I = I + 0.1

End Sub

 

2.- Dibujaremos un círculo, una elipse y un círculo con un sector desplazado.

 

Sub Form_Load()

Pi = 4 * Atn(1) ‘Definir el valor de Pi

C1 = RGB(0, 0, 255) 'Azul

C2 = RGB(0, 255, 0) 'Verde

C3 = RGB(255, 0, 0) 'Rojo

AutoRedraw = -1

ScaleMode = 3 ‘Pixels

Circle (60, 70), 30, C1 'Círculo

Circle (150, 70), 30, C2, , , 5 / 11 'Elipse

Circle (240, 70), 30, C3, -Pi / 2, -2 * Pi 'Sector

Circle Step(5, -5), 30, C1, -2 * Pi, -Pi / 2 'Sector

End Sub

 

3.- Rellenaremos el círculo, la elipse y el círculo con un sector desplazado del ejemplo anterior.

 

Sub Form_Load()

Pi = 4 * Atn(1) ‘Definir el valor de Pi

C1 = RGB(0, 0, 255) 'Azul

C2 = RGB(0, 255, 0) 'Verde

C3 = RGB(255, 0, 0) 'Rojo

AutoRedraw = -1

ScaleMode = 3 ‘Pixels

FillStyle = 0

FillColor = C1

Circle (60, 70), 30, C1 'Círculo

FillColor = C2

Circle (150, 70), 30, C2, , , 5 / 11 'Elipse

FillColor = C3: FillStyle = 4

Circle (240, 70), 30, C3, -Pi / 2, -2 * Pi 'Sector

FillColor = C1: FillStyle = 5

Circle Step(5, -5), 30, C1, -2 * Pi, -Pi / 2 'Sector

End Sub

 

 

4.- Simulación de una pelota rodando sobre una línea.

 

Sub Form_Click()

D = 100 ‘Radio de la pelota

BackColor = RGB(255, 255, 255) 'Blanco

ForeColor = RGB(0, 0, 255) 'Azul

CY = ScaleHeight / 2

'Línea sobre la que rueda la pelota

Line (0, CY + D)-(ScaleWidth, CY + D), QBColor(2)

FillStyle = 0 ‘Color sólido

FillColor = ForeColor ‘Color pelota

DrawMode = 10

'Animación

For I = 0 To ScaleWidth Step 30

Circle (I, CY), D ‘Dibujar la pelota

For retar = 0 To 1000

Next retar ‘Control de velocidad

Circle (I, CY), D ‘Borrar la pelota

Next I

End Sub

 

5.- Simulación de una pelota que rebota al chocar contra una barrera.

 

Sub Form_Click()

ScaleMode = 3 'Pixels

D = 5 'Radio de la pelota

BackColor = QBColor(15) 'Blanco

ForeColor = QBColor(1) 'Azul

CX = ScaleWidth / 4 * 3

CY = ScaleHeight / 2

'Barrera sobre la que rebota la pelota

Line (CX, 10)-(CX + 20, ScaleHeight - 10), QBColor(2), BF

FillStyle = 0 'Color sólido

FillColor = ForeColor 'Color pelota

DrawMode = 10

'Animación. Mover la pelota. Si choca, rebota

direccion = 1 '1=derecha, -1=izquierda

i = 3

Do While (i > 3 Or direccion = 1)

Circle (i, CY), D 'Dibujar la pelota

'Point da el color de la barrera cuando hay contacto. Devuelve el color RGB

‘ de un punto

If Point(i + 6, CY) <> BackColor Then direccion = -1

For retar = 0 To 300

Next retar 'Control velocidad

Circle (i, CY), D 'Borrar pelota

i = i + direccion

Loop

End Sub