Autor Tema: Estudio de Graficos en VB  (Leído 68786 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado PalitroqueZ

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Estudio de Graficos en VB
« en: 26 de Febrero de 2007, 12:12:57 »
Este tema está destinado al aprendizaje del manejos de graficos en visual basic. para ello emplearemos el objeto picturebox, que es tremenda herramienta para lograr buenos efectos.

siempre he querido meterle mano a este tópico, porque la visualización de datos se usa mucho en proyectos y para no quedarnos cortos en esta materia vamos ir analizando paso a paso, lo básico para crear un dibujo estático y dinámico, hasta donde se pueda llegar y hasta donde nos puedan ayudar :)).

Cualquiera que tenga conocimiento sobre este tema le invito a que participe y nos dé su aporte.

ya hemos visto varios codigos en este subforo dedicado a ver los datos de entrada en forma de señales. gracias a los aportes de varios foreros y al amigo Bruno en especial que es un verdugo en esto de trabajar con el picture box :)

primero vamos a estudiar el método Line

si buscamos en el MSDN, nos sale:

Código: [Seleccionar]

objeto.Line [Step] (x1, y1) [Step] - (x2, y2), [color], [B][F]


en este post aparece la explicación completa de cada uno de los argumentos

para nuestro propósito podemos resumir el método así

Código: Visual Basic
  1. picturebox.Line (x1, y1)  - (x2, y2), [color]

la clave de todo esto es aplicar un poco de geometría analítica e imaginación, es decir, jugar con las coordenadas x(1,2) e y(1,2) para lograr el efecto deseado.

vamos a montar un primer ejemplo, dibujar una línea recta.
la base para dibujar una línea, es tener las coordenadas de 2 puntos (que serian los extremos de la recta).


Código: Visual Basic
  1. Option Explicit
  2.  
  3. Private Sub Command1_Click()
  4.     Picture1.Line (0, 0)-(10, 15)
  5. End Sub

- cabe decir que para dibujar una línea recta hay que establecer ciertas propiedades al picturebox

por ejemplo, podemos colocar ScaleMode = Pixel (para ajustar a la resolución del monitor) y drawwidth = 5 (el ancho de la recta). hay otros que se iran develando.

una imagen:



allí vemos que el origen comienza desde la parte superior derecha. hay otra cosa curiosa, prueben alternando otra ventana (ocultando) y vuelvan otra vez, -¿que ven?- se borró la línea dibujada -¿porqué?- porque la propiedad autoredraw = false, esto significa que el picturebox no depende mantener el gráfico dibujado, si queremos mantenerlo  -> autoredraw = true

vamos a cambiarle las coordenadas:

Picture1.Line (0, 0)-(1000, 15000)




se observa que la línea se pierde por debajo del objeto, ¿y como podemos hacer para que no suceda esto?

siempre hay que tomar en cuenta las dimensiones del picturebox, para hacer los ajuste de lo que vayamos a dibujar y que queden dentro, estas lineas dependerá del alto, y ancho, con las propiedades scaleheight y scalewidth respectivamente.

aquí podemos escribir varias ecuaciones la mas común: restar al alto la variable y2 y el ancho la variable x2.ej:

Código: Visual Basic
  1. Dim cx As Integer, cy As Integer
  2.  
  3. Private Sub Command1_Click()
  4.     Picture1.Line (0, 0)-(cx - 150, cy - 100)
  5. End Sub
  6.  
  7. Private Sub Form_Load()
  8.    cy = Picture1.ScaleHeight
  9.    cx = Picture1.ScaleWidth
  10. End Sub

si hacemos x2 = Picture1.ScaleWidth - 1000 e y2 =  ScaleHeight estaremos calibrando las coordenadas para que siempre se mantengan ajustados dentro de la caja, pero siempre que estos sean de valor positivo.

para dibujar una recta de extremo a extremo, basta con hacer:

Código: Visual Basic
  1. Dim cx As Integer, cy As Integer
  2.  
  3. Private Sub Command1_Click()
  4.     Picture1.Line (0, 0)-(cx, cy)  
  5.     ' dibuja una recta en los extremos de la caja
  6. End Sub
  7.  
  8. Private Sub Form_Load()
  9. cy = Picture1.ScaleHeight
  10. cx = Picture1.ScaleWidth
  11.  
  12. End Sub




esto sería lo máximo visible para nuestro ejemplo1 y sería un dibujo estático, y ¿como es uno dinámico?

pues, dibujando la recta en tiempo de ejecución:

Código: Visual Basic
  1. Dim cx As Integer, cy As Integer
  2. Dim i As Integer, j As Integer
  3.  
  4.  
  5. Private Sub Command1_Click()
  6.     Timer1.Enabled = True
  7. End Sub
  8.  
  9. Private Sub Form_Load()
  10.     cy = Picture1.ScaleHeight ' 117
  11.    cx = Picture1.ScaleWidth   ' 253
  12.    Timer1.Interval = 10
  13.     Timer1.Enabled = False
  14. End Sub
  15.  
  16. Private Sub Timer1_Timer()
  17.     If Not i = cx Then  ' pregunta si i no ha llegado a cx
  18.    Picture1.Line (0, 0)-(i, i * (117 / 253))
  19.     i = i + 1  ' incrementa i
  20.    Else
  21.     Timer1.Enabled = False  ' ya llego, deja de dibujar
  22.    End If
  23. End Sub

aquí se usó un control timer para poder observarlo lentamente como se vá dibujando la recta. vean que la recta es en función de el ancho de la caja, o sea, ScaleHeight = f(ScaleWidth) en el tiempo.

la línea de programación crítica es:

Código: Visual Basic
  1. Picture1.Line (0, 0)-(i, i * (117 / 253))




¿y de donde salió que y2 = i * (117 / 253)? 

como en este picturebox se conocen las coordenadas de las esquinas, podemos trasladar nuestra recta al plano cartesiano. ¿cuál es la ecuación de una recta?

Y = (y2-y1)/x2-x1) * X

donde el cociente de las constantes viene siendo la pendiente, en nuestro ejemplo:

Y = (117-0)/(253-0) * X

que es precisamente Y = y2. ven como si se puede hallar una expresión matemática que se pueda aplicar a nuestro dibujo.

y a medida que el dibujo tenga más cosas, el cálculo se irá haciendo más complejo.

Salu2
Pedro
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado PalitroqueZ

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Estudio de Graficos en VB
« Respuesta #1 en: 26 de Febrero de 2007, 12:15:04 »
El ejemplo anterior, fué sencillo porque la verdadera variable fué y2 ya que i se incrementaba en una unidad todo el tiempo, pero imaginemos que necesitemos sacar una señal que no fuera una recta, ¿como se haría?

bueno una posible solución es visualizar la gráfica como un conjunto de puntos. de hecho, la recta es un conjunto de puntos, si vemos nuevamente el ejemplo anterior desde la perspectiva de puntos, graficamos una sucesión de rectas porque nuestro x1, y1 se mantenian constantes. si quieren comprobarlo, modifiquen esta línea así:

Código: Visual Basic
  1. Picture1.Line (0, 0)-(i, i * (117 / 253)), (&HFFFF& + i)

le añadí el parámetro de color y veran como cambia de color la recta completa.



pero esto tiene arreglo, vamos a dibujar la recta ahora como un conjunto de mini-rectas ó mejor dicho un infinitésimo de una recta, lo más pequeño como queramos hacerlo, para aquellos que recuerden la definición de límites jeje. ¿y como se hace eso?

volviendo al plano cartesiano, ¿como se dibuja una recta en base a mini-rectas?



para la mini-recta a tenemos 2 puntos (0,0)-(x1,y1)
para la mini-recta b tenemos 2 puntos (x1,y1)-(x2,y2)
para la mini-recta c tenemos 2 puntos (x2,y2)-(x3,y3)
...

aquí se ve claramente un patrón, que el primer extremo de la mini-recta siguiente coincide con el último extremo de la mini-recta anterior, y es ahí adonde quería llegar, porque así es que vamos a trabajar para construir una recta en el picturebox. un ejemplito (estático):

Código: Visual Basic
  1. Private Sub Command1_Click()
  2.     x = 0: y = 0
  3.     For i = 0 To cx
  4.         j = i * (cy / cx)
  5.          Picture1.Line (x, y)-(i, j), ((&HFFFFFF / (i + 1)))
  6.         x = i
  7.         y = j
  8.     Next i
  9.     'Timer1.Enabled = True
  10. End Sub




le agregué colores para que se observara con detalle la infinidad de minirectas dibujadas.

ahora en dinámica:

Código: Visual Basic
  1. Private Sub Timer1_Timer()
  2.     If Not i = cx Then  ' pregunta si i no ha llegado a cx
  3.        j = i * (cy / cx)
  4.         Picture1.Line (x, y)-(i, j), ((&HFFFFFF / (i + 1)))
  5.         x = i
  6.         y = j
  7.         i = i + 1
  8.     Else
  9.     Timer1.Enabled = False  ' ya llego, deja de dibujar
  10.    End If
  11. End Sub




se está cumpliendo el planteamiento geométrico expuesto arriba.

Salu2
Pedro
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado roc364

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 108
Re: Estudio de Graficos en VB
« Respuesta #2 en: 26 de Febrero de 2007, 22:26:18 »
Muy Interesante el Tutorial, sigue asi!
Hay solo 10 tipos de personas, los que entienden el codigo binario, y los que no.

Viva La Patagonia Argentina!!

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Estudio de Graficos en VB
« Respuesta #3 en: 26 de Febrero de 2007, 23:01:10 »
Hola Pedro. Gracias por mencionarme, pero no es para tanto tampoco  :D

Quiero agregar un comentario que tal vez olvidaste mencionar, y es que a la hora de dibujar en un PictureBox debemos tener en cuenta que su ejeY está invertido.

Todos estamos acostumbrados a que el cero absoluto se encuentra abajo a la izquierda.
En el PictureBox(al igual que la mayoria de los controles) el cero absoluto se encuentra arriba a la izquierda.
Por lo que puede por ahí confundir a la hora de dibujar en el PictureBox.

La imagen:


Matematicamente significa que: o bien nos adaptamos a usarlo invertido o bien lo corregimos sabiendo que:
nuestro 0 es en realidad Picture1.Height
y que nuestro Picture1.Height es 0



Otra cosa importante es dibujar texto en un PictureBox. Y puede que muchos siquiera saben o sabían que se puede "pintar" texto en un PictureBox.

He hecho aquí un ejemplo para que lo vayan masticando.
Simplemente copien y peguen el siguiente código dentro del evento Form_Load()

Código: Visual Basic
  1. 'Declaramos el objeto
  2. Dim Picture1 As PictureBox
  3. 'Variable que contendra la cadena de texto a dibujar en el PictureBox
  4. Dim Texto As String
  5.  
  6. 'Creacion de un control desde codigo
  7. Set Picture1 = Me.Controls.Add("vb.PictureBox", "NewPictureBox1")
  8.  
  9. With Picture1
  10.     'Movemos y redimensionamos el PictureBox dentro del Form1 a gusto
  11.    .Move 100, 100, 5000, 4000
  12.     'Seteamos que queremos fondo blanco
  13.    .BackColor = vbWhite
  14.     'Que "recuerde" lo que dibujaremos a continuacion
  15.    .AutoRedraw = True
  16.     'Lo hacemos visible
  17.    .Visible = True
  18. End With
  19.  
  20. Texto = "Picture1"
  21.  
  22. With Picture1
  23.     'Vamos a dibujar con Negrita
  24.    .Font.Bold = True
  25.     'Tamaño 14 px
  26.    .Font.Size = 14
  27.     'Color Rojo
  28.    .ForeColor = vbRed
  29.     'Indicamos posicion X dentro del PictureBox donde comenzaremos a dibujar el texto
  30.    .CurrentX = Picture1.Width / 2 - Picture1.TextWidth(Texto) / 2
  31.     'Indicamos posicion Y dentro del PictureBox donde comenzaremos a dibujar el texto
  32.    .CurrentY = Picture1.Height / 2 - Picture1.TextHeight(Texto) / 2
  33. End With
  34.  
  35. 'Finalmente, enviamos a dibujar el texto al PictureBox
  36. Picture1.Print Texto


El resultado es este:


Analicen también el código utilizado para centrar el Texto a dibujar en el PictureBox.

Saludos y seguí asi Pedro con buenos tutos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado PalitroqueZ

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Estudio de Graficos en VB
« Respuesta #4 en: 27 de Febrero de 2007, 11:46:54 »
- ¡Gracias!  roc364  :-/

- Bruno, tengo que decirte que estaba dentro de ese grupo de personas que desconocía lo de los textos en un picturebox.  :?

- efectivamente faltaba hablar sobre la ubicación del origen, muy buena tu explicación.

- voy a continuar con otros ejemplitos, para seguir avanzando  :mrgreen:



Después de analizar los ejemplos anteriores y como errar es de humanos, cometí un fallo respecto a lo de dibujar en estática y dinámica, ambos corren en tiempo de ejecución, porque existen 2 tiempos (el otro es tiempo de diseño). La diferencia radica que en la dinámica, se hace un retardo para poder observar con lentitud como se vá dibujando la imagen.

ya aclarado ese punto continuamos...

en la naturaleza existen 2 señales que son de tipo puramente analógico, estas son: la señal senoidal (que tiene su ecuación matemática) y el ruido blanco (formado por niveles y frecuencias aleatorios)

la mejor forma de probar un dibujo en un picturebox, es aplicando cualquiera de estas 2 señales

para nuestro ejemplo, es obvio que hay que cambiar a y2, porque a fin de cuentas es y2 quien definirá el próximo punto

vamos aplicar la señal senoidal, modificando el ejemplo2, tenemos:

Código: Visual Basic
  1. Private Sub Timer1_Timer()
  2.     dato = Fix(cy * Sin(i * (3.14159265358979 / 180)))
  3.     Debug.Print "dato= " & dato
  4.     If Not i = cx Then  ' pregunta si i no ha llegado a cx
  5.        j = dato
  6.         Picture1.Line (x, y)-(i, j), ((&HFFFFFF / (i + 1)))
  7.         x = i
  8.         y = j
  9.         i = i + 1
  10.     Else
  11.     Timer1.Enabled = False  ' ya llego, deja de dibujar
  12.    End If
  13. End Sub

allí se observa que j (que es y2) toma el resultado de la ecuación senoidal de arriba multiplico por cy porque dato es del tipo long (entero largo) y además para que el nivel máximo de altura se ajuste al de scaleheight




¡epa! un momento, la onda me la dibujó de forma rara. yo quiero que empiece desde cero.

aquí es donde que hay que hacer los ajustes a j para tener nuestro dibujo como queremos.

que tal si restamos a dato, cy

j = cy - dato





¡ahh! ahora si empieza en la esquina inferior izquierda y desde cero. podemos subirla, ¿como? dividiendo a cy en 2 ->

j = (cy/2) - dato





¡ups! la onda se fué para arriba, entonces hay que ajustarla ¿como? bueno si el valor máximo de dato = cy , entonces hay que dividir a dato en 2 para que se ajuste a media escala

j = (cy/2) - (dato/2)




ya está arreglado, si alguien pregunta ¿podemos dividir a 2 dentro de la ecuación de dato:

dato = Fix((cy/2) * Sin...

también es válido, pero ya hice la prueba y la gráfica no se ve tan suavizada, la razón: porque el Fix anula cualquier aproximación, entonces es mejor hacer la división afuera en j.

a este ejemplo hay que seguir haciendole ajustes, uno de ellos: yo quiero ver la gráfica del período completo de la senoidal

sabemos que el timer culmina cuando i = cx  y como el argumento de la función seno está ajustado para 0 a 360 grados, bastaría con agregarle

360/cx

la ecuación quedaría así:

dato = Fix(cy * Sin((360/cx * i * (3.14159265358979 / 180))))

simplificando:

dato = Fix(cy * Sin((2* i * (3.14159265358979 / cx))))





que gusto dá saber que se pueden emplear calculos precisos en esto de los dibujillos jeje

también se deduce lo siguiente, ese 2 que está como parte del ángulo, viene siendo el número de semi-periodos visibles de la onda, ¿no me creen? :) vamos agregarle 7 semi-periodos visibles en el picturebox, la ecuación quedaría:

dato = Fix(cy * Sin((7* i * (3.14159265358979 / cx))))






aquí se puede poner a volar la imaginación, por ej: agregandole un scrollbar de manera que a cada ajuste me cambie el número de semi-periodos a voluntad.

aquí es donde decimos que la gráfica de algún modo debe ser independiente del tamaño del picturebox, es decir, no importa que dimensiones tenga, lo importante es que la gráfica siempre se ajuste al tamaño de la caja.

Salu2
Pedro
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado PalitroqueZ

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Estudio de Graficos en VB
« Respuesta #5 en: 27 de Febrero de 2007, 11:49:00 »
Analizando lo anterior, ¿que es lo que se está haciendo realmente?

se está aplicando la sencilla ecuación Y = f(x) donde Y = y2 y X es un incremento que va desde 0 hasta scaleheight (en el tiempo), pero adaptandolo al método Line, es algo parecido a lo que se hace en excel ó lo que hacen las calculadoras graficas.


faltó dibujar el otro tipo de señal: el ruido blanco

esto se puede hacer usando la función Rnd. la ayuda MSDN lo define:

"Devuelve un tipo Single que contiene un número aleatorio"

y

"Para producir enteros aleatorios en un intervalo dado, use esta fórmula:

Int((Límite_superior - límite_inferior + 1) * Rnd + límite_inferior)"


donde:

- límite superior = cy

- límite inferior = 0

entonces la ecuación quedará así:

dato = Int(Rnd * (cy + 1))

aquí también se ajusta la altura, modificando el ejemplillo anterior:

Código: Visual Basic
  1. Private Sub Timer1_Timer()
  2.     dato = Int(Rnd * (cy + 1))
  3.  
  4.     Debug.Print "dato= " & dato
  5.     If Not i = cx Then  ' pregunta si i no ha llegado a cx
  6.        j = dato 'senoidal
  7.        Picture1.Line (x, y)-(i, j), ((&HFFFFFF / (i + 1)))
  8.         x = i
  9.         y = j
  10.         i = i + 1
  11.         Debug.Print "i= " & i
  12.     Else
  13.     Timer1.Enabled = False  ' ya llego, deja de dibujar
  14.    End If
  15. End Sub










ahí tienen varias pantallas del ruido blanco, mas bien sería un ruido multicolor  :D

nota: no olviden usar la instrucción Randomize al inicio para que se produzca una aproximación aleatoria real.

pero esas imagenes se ven como muy pegadas ¿verdad? habría que ajustarle el time-division :) para ello basta con hacer un ajuste a la línea:

i = i + 1

por :

i = i + 3




la separación es notoria, otra vez vuelven las ideas. ej: se puede pegar un scroll-bar  de manera de hacerles esos ajustes automático.

Salu2
Pedro
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado LordLafebre

  • Moderador Global
  • DsPIC30
  • *****
  • Mensajes: 3529
    • Micros & micros
Re: Estudio de Graficos en VB
« Respuesta #6 en: 27 de Febrero de 2007, 13:28:23 »
Hola:

Gran trabajo Pedro, crees que nos puedas colaborar con los archivos para mirarlos?  :mrgreen:

Desconectado LABmouse

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3575
    • Juntos es mejor
Re: Estudio de Graficos en VB
« Respuesta #7 en: 27 de Febrero de 2007, 13:58:38 »
que buen tutorial amigo Pedro. Apalusos por tan buen trabajo.  :-)

Desconectado PalitroqueZ

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Estudio de Graficos en VB
« Respuesta #8 en: 27 de Febrero de 2007, 15:05:56 »
despitado que soy yo  :roll:, se me olvidó poner los adjuntos.

aquí vá el del ejemplo3 (dibujar la onda senoidal), voy a buscar los demás (esos no los copié al pen driver  :mrgreen:)

Salu2
Pedro
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado LordLafebre

  • Moderador Global
  • DsPIC30
  • *****
  • Mensajes: 3529
    • Micros & micros
Re: Estudio de Graficos en VB
« Respuesta #9 en: 27 de Febrero de 2007, 17:38:31 »
Hola:

Gracias por los archivos Pedro, excelente la explicacion en cada paso  :-/

Desconectado PalitroqueZ

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Estudio de Graficos en VB
« Respuesta #10 en: 28 de Febrero de 2007, 14:38:32 »
según lo visto del ejemplo anterior, con la señal de ruido blanco, se dijo que con variar el incremento de i = i + 3 el dibujo se expandiría, es cierto y desde el punto de vista geometrico, lo que se hace es aumentar el tamaño de la mini-recta (el infinitésimo).

si por ejemplo hacemos:  i = i + 90

tenemos:




el color delata el contenido de 3 mini-rectas, logrando el efecto que queremos.

-¿que podemos seguir haciendo?-

muchas cosas, podemos hacer que el picturebox sea múltiplo del tamaño del formulario -¿para que?- bueno, si queremos maximizar o cambiar el tamaño del form, el picture box debe cambiar de dimensiones.

un ejemplito (ejemplo5)

las dimensiones del form son:

height = 3600

width =  4800

y las del picturebox

height = 1815

width = 3855

entonces la proporción entre ambos es:

height = 3600 / 1815 = 1.98
width = 4800 / 3855 = 1.24

y el código para que se cumpla esto es:

Código: Visual Basic
  1. Private Sub Form_Resize() 'se invoca en cada cambio de dimension del form
  2.    Picture1.Height = Form1.Height / 1.98
  3.     Picture1.Width = Form1.Width / 1.24
  4. End Sub

si tenemos otros objetos en el formulario, hay que cambiar su posición, para que no se solape con el picture box, pero esto lo dejaremos pendiente, lo principal es la caja de pintura

video1 ejemplo5.wmv

otro detalle es que lo dentro del picturebox no cambiará, porque existe otra escala interna

me refiero a scaleheight y scalewidth

de nuevo vamos a sacar una proporción

picture1.scaleheight =  117

picture1.scalewidth =  253

1815 / 117 = 15.51

3855 / 253 = 15.23

en mismo resize, ajustamos:

Código: Visual Basic
  1. Private Sub Form_Resize()
  2.     Picture1.Height = Form1.Height / 1.98
  3.     Picture1.Width = Form1.Width / 1.24
  4.    
  5.     Picture1.ScaleHeight = Picture1.Height / 15.51
  6.     Picture1.ScaleWidth = Picture1.Width / 15.23
  7.     cy = Picture1.ScaleHeight
  8.     cx = Picture1.ScaleWidth
  9.    
  10. End Sub

¿creen ustedes que es una solución elegante?  porque entonces tenemos que estar sacando cuentas para cada caso, también se puede hacer mediante variables:

Código: Visual Basic
  1. Private Sub Form_Load()
  2.     Randomize
  3.     cy = Picture1.ScaleHeight ' 117
  4.    cx = Picture1.ScaleWidth   ' 253
  5.    
  6.     cy1 = Picture1.ScaleHeight ' 117
  7.    cx1 = Picture1.ScaleWidth   ' 253
  8.    
  9.     pcx = Picture1.Width
  10.     pcy = Picture1.Height
  11.    
  12.     fcx = Me.Width
  13.     fcy = Me.Height
  14.    
  15.     Timer1.Interval = 1
  16.     Timer1.Enabled = False
  17. End Sub
  18.  
  19. Private Sub Form_Resize()
  20.     Picture1.Cls
  21.  
  22.     Picture1.Height = Form1.Height / (fcy / pcy)
  23.     Picture1.Width = Form1.Width / (fcx / pcx)
  24.    
  25.     Picture1.ScaleHeight = Picture1.Height / (pcy / cy1)
  26.     Picture1.ScaleWidth = Picture1.Width / (pcx / cx1)
  27.     cy = Picture1.ScaleHeight
  28.     cx = Picture1.ScaleWidth
  29.    
  30. End Sub

esta luce mas elegante, pero se consume mas memoria (por las nuevas variables)eso depende si estamos considerando los recursos de la máquina
(la ventaja de este último es que nos olvidamos de numeros)


video2 ejemplo5

en el adjunto estan el fuente del ruido blanco y del senoidal


nota:
- les recomiendo para leer Visual Basic - Guía del Estudiante no lo he terminado de leer, estoy aprendiendo mucho de los pequeños detalles, que salen ahí.

- Bruno probé el código que posteaste pero no me sale nada :( (ver el adjunto texto_en_picture.rar) debe ser que me faltó algo.


salu2
pedro
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Estudio de Graficos en VB
« Respuesta #11 en: 28 de Febrero de 2007, 20:27:32 »
Jejeje Pedro, fijate que tenes como comentario al final de todo la linea critica: Picture1.Print Texto.

Agregue este tutorial a las noticias del foro. Gracias por tu esfuerzo.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado todopic

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3495
    • http://www.todopicelectronica.com.ar
Re: Estudio de Graficos en VB
« Respuesta #12 en: 02 de Marzo de 2007, 00:10:19 »
Muy buen trabajo Pedro!  :-/
Felicitaciones!, y seguimos leyendo  :mrgreen:

Norberto
Firmat - Santa Fe - Argentina

www.TodoPic.net

Solo se tiran piedras, al arbol que tiene frutos...

Desconectado PalitroqueZ

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Estudio de Graficos en VB
« Respuesta #13 en: 02 de Marzo de 2007, 11:59:18 »
Jejeje Pedro, fijate que tenes como comentario al final de todo la linea critica: Picture1.Print Texto.

Agregue este tutorial a las noticias del foro. Gracias por tu esfuerzo.

Saludos.


te cuento que me pasé de listo, y no leí esa parte, el código se pegó al formulario en una sola línea, entonces tuve que ir 'entereando' en secciones  :?



todas estas explicaciones son cuantitativas, pero nosotros podemos aprender también empíricamente, vamos a ver los efectos que ocurren al cambiar ligeramente los valores en las coordenadas:

usando el ejemplo1, el de la recta, ¿que pasa si hacemos variable a x1?

cambiaría (en el timer)

Picture1.Line (i, 0)-(i, i * (117 / 253))

el efecto:




- otro cambio (en el timer)

Picture1.Line (0, i)-(i, i * (117 / 253))

el efecto:




- tercer cambio

Picture1.Line (cx * Sin(2 * i * 3.1415927 / 180), 0)-(i, i * (117 / 253))





¡guau! que carteluo. :)

hay otro método para graficar en el picturebox, hemos venido haciendolo con variables de nombres distintos para guardar ciertos datos.

también podemos usar arrays de datos, además de estructurar mejor la programación, nos será muy útil mas adelante, ¡ya lo veran!

vamos a usar el ejemplillo2, el de la recta, pa´ ir cogiendo mínimo.

el código en el timer, rezaba así:

Código: Visual Basic
  1. Private Sub Timer1_Timer()
  2.     If Not i = cx Then  ' pregunta si i no ha llegado a cx
  3.        j = i * (cy / cx)
  4.         Picture1.Line (x, y)-(i, j), ((&HFFFFFF / (i + 1)))
  5.         x = i
  6.         y = j
  7.         i = i + 1
  8.     Else
  9.     Timer1.Enabled = False  ' ya llego, deja de dibujar
  10.    End If
  11. End Sub


podemos sustituir x e y por un arrays de datos long, como este caso cx=253, entonces declaremos dato[253]

Código: Visual Basic
  1. Dim dato(253) As Long
  2.        ...
  3.        ...
  4.  
  5. Private Sub Timer1_Timer()
  6.     If Not i = cx Then  ' pregunta si i no ha llegado a cx
  7.        dato(i + 1) = i * (cy / cx)
  8.         Picture1.Line (i, dato(i))-(i, dato(i + 1)), ((&HFFFFFF / (i + 1)))
  9.         i = i + 1
  10.     Else
  11.       Timer1.Enabled = False  ' ya llego, deja de dibujar
  12.    End If
  13. End Sub

se nota que es más legible para leer, pero también más dificil de entender, y creanme que uno se pierde haciendo una corrida en frío. (una depuración manual)

lo que hice fué sustituir x e y, j por un array, donde dato(i) es valor anterior almacenado y dato(i+1) es el nuevo valor.

el resto es jugar, lease bien, con los subindices, por eso es que esta forma tiende a confundir mucho, pués por una lado estan los calculos de los subindices y por el otro estan los valores almacenados en esos subindices. para resumir estamos tratando con una variable de puntero nulo (que es la otra definición para una matriz).


vamos a modificar el resto de los ejemplitos que se habian hecho en base a este método:

el ejemplito de la senoidal con semi-período variable:

Código: Visual Basic
  1. Dim dato(1000) As Long
  2. ...
  3. ...
  4.  
  5. Private Sub Timer1_Timer()
  6.     j = Fix(cy * Sin((12 * i * (3.14159265358979 / cx))))
  7.     If Not i = cx Then  ' pregunta si i no ha llegado a cx
  8.        dato(i + 1) = (cy / 2) - (j / 2) 'senoidal
  9.        Picture1.Line (i, dato(i))-(i, dato(i + 1)), ((&HFFFFFF / (i + 1)))
  10.         i = i + 1
  11.         Debug.Print "i= " & i
  12.     Else
  13.     Timer1.Enabled = False  ' ya llego, deja de dibujar
  14.    Command1.Enabled = True
  15.     Command1.Caption = "Dibuje"
  16.     End If
  17. End Sub

noten que dato llega hasta 1000, para saber cuantos subindices se pueden crear, eso dependerá de los maximos valores de dimensiones del formulario, porque en este caso cx depende indirectamente de Form1.Height y Form1.Width

falta el del ruido muticolor :)

Código: Visual Basic
  1. Dim dato(1000) As Long
  2. ...
  3. ...
  4.  
  5. Private Sub Timer1_Timer()
  6.     dato(i + 1) = Int(Rnd * (cy + 1))
  7.     If Not i = cx Then  ' pregunta si i no ha llegado a cx
  8.        Picture1.Line (i, dato(i))-(i, dato(i + 1)), ((&HFFFFFF / (i + 1)))
  9.         i = i + 1
  10.     Else
  11.     Timer1.Enabled = False  ' ya llego, deja de dibujar
  12.    End If
  13. End Sub

en los adjuntos estan todos los ejemplillos modificados en base a esta forma, pueden hacer los ensayos, hagan pruebas haciendo sumas en los subindices !a ver que dibujo se pinta!


todos_ejemplo_cambiados.rar


Salu2
Pedro
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado PalitroqueZ

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Estudio de Graficos en VB
« Respuesta #14 en: 02 de Marzo de 2007, 12:03:30 »
continuando con los arreglos, seguiremos analizando los efectos que producen al hacer cambios en los subindices

vamos a quitar por un momento al timer, de momento quiero dibujar sin retardos, así que pegemos todo en un command button

Código: Visual Basic
  1. Private Sub Command1_Click()
  2.     j = 0
  3.     Picture1.Cls
  4.     Command1.Caption = "Dibujando..."
  5.     Command1.Enabled = False
  6.    
  7.     For i = 0 To cx
  8.         j = Fix(cy * Sin((12 * i * (3.14159265358979 / cx))))
  9.         dato(i + 1) = (cy / 2) - (j / 2) 'senoidal
  10.        Picture1.Line (i, dato(i))-(i, dato(i + 1)), vbBlue
  11.     Next i
  12.  
  13.     Debug.Print "cx= " & cx
  14.    
  15.     Command1.Enabled = True
  16.     Command1.Caption = "Dibuje"
  17.    
  18. End Sub





es la senoidal común y silvestre que hemos venido trabajando (ahora monocolor)

ya se había explicado que con un arreglo:

dato(x)  -> sustituye a x (dato anterior)
dato(x+1)  -> sustituye a y (nuevo dato)


ahora prestar atención a esta línea:

Picture1.Line (i, dato(i))-(i, dato(i + 1)), vbBlue

tenemos el mismo valor para x1, x2. ¿que significa que tengan el mismo valor?

desde el punto de vista geométrico es un punto de la abscisas, es decir que en ambos puntos (los extremos de la recta) son el mismo valor para x. vamos a visualizar la explicación

supongamos que tenemos:

x1 = 1
x2 = 1

y1 = 5
y2 = 10

en el plano cartesiano:




para la siguiente mini-recta x1 = x2 = 2 y después ambos se irian incrementando por igual, a lo que quiero llegar es que el gráfico no es mas que la sumatoría de mini-rectas dispuestas en forma vertical, que al ser tan pequeñas no se nota la diferencia.

para demostrar esto simplemte cambiemos los valores de x1 y x2


Picture1.Line (i + 5, dato(i))-(i + 10, dato(i + 1)), vbBlue




ajá, ¿que se vé allí? las mini-rectas estan inclinadas. y si seguimos ampliando el margen entre x1, x2 -> las mini-rectas se iran haciendo planas y eso no es todo, también seran mas largas, pudiendo solapar el gráfico.

y ¿que pasa si cambiamos el valor de x1, x2 en igual proporción?

por ej:

Picture1.Line (i + 10, dato(i))-(i + 10, dato(i + 1)), vbBlue




ignorando la línea vertical, se puede decir que la señal se desplazó en el eje de las abscisas hacia la derecha.

esto es un dato interesante porque significa que podemos mover la gráfica (la señal a partir de ahora) desplazandola adonde queramos.

comprobaremos esto con un ejemplo:

Código: Visual Basic
  1. dim desplazar as long
  2. ...
  3. ...
  4. Private Sub Command1_Click()
  5.     j = 0
  6.     Picture1.Cls
  7.     Command1.Caption = "Dibujando..."
  8.     Command1.Enabled = False
  9.    
  10.     For i = 0 To cx
  11.         j = Fix(cy * Sin((12 * i * (3.14159265358979 / cx))))
  12.         dato(i + 1) = (cy / 2) - (j / 2) 'senoidal
  13.        Picture1.Line (i + desplazar, dato(i))-(i + desplazar, dato(i + 1)), vbBlue
  14.     Next i
  15.  
  16.     desplazar = desplazar + 1
  17.     Command1.Enabled = True
  18.     Command1.Caption = "Dibuje"
  19.    
  20. End Sub





clicando y/o dejando el botón presionado vemos la animación de la onda "moviendose"

¿ya adivinan por donde vengo verdad?  :)

también podemos observar un efecto explicado anteriormente si modificamos:

Picture1.Line (i + desplazar, dato(i))-(i, dato(i + 1)), vbBlue 





el adjunto con el avance:

ejemplo7.rar

Salu2
Pedro
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek


 

anything