TODOPIC

Lenguajes de programación para PC => Visual Basic => Mensaje iniciado por: PalitroqueZ en 26 de Febrero de 2007, 12:12:57

Título: Estudio de Graficos en VB
Publicado por: PalitroqueZ 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  (http://www.todopic.com.ar/foros/index.php?topic=7187.msg41452#msg41452) 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:

(http://img167.imageshack.us/img167/6830/e1i1bx2.jpg)

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)


(http://img378.imageshack.us/img378/8167/e1i2oa8.jpg)

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


(http://img378.imageshack.us/img378/7079/e1i3ec4.jpg)

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))


(http://img341.imageshack.us/img341/4417/e1v1wk5.gif)

¿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
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ 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.

(http://img378.imageshack.us/img378/5583/e2i0ij5.jpg)

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?

(http://img378.imageshack.us/img378/4210/e2i1qd7.jpg)

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


(http://img378.imageshack.us/img378/6060/e2i2at5.jpg)

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


(http://img83.imageshack.us/img83/6291/e2v1yx2.gif)

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

Salu2
Pedro
Título: Re: Estudio de Graficos en VB
Publicado por: roc364 en 26 de Febrero de 2007, 22:26:18
Muy Interesante el Tutorial, sigue asi!
Título: Re: Estudio de Graficos en VB
Publicado por: BrunoF 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:

(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=16233.0;attach=4045)

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:

(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=16233.0;attach=4047)

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

Saludos y seguí asi Pedro con buenos tutos.
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ 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


(http://img296.imageshack.us/img296/7111/e3i1wh8.jpg)

¡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


(http://img329.imageshack.us/img329/3204/e3i2pj4.jpg)


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

j = (cy/2) - dato


(http://img264.imageshack.us/img264/9892/e3i3lr4.jpg)


¡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)


(http://img154.imageshack.us/img154/9461/e3i4ls6.jpg)

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))))



(http://img329.imageshack.us/img329/7617/e3i5sa8.jpg)

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))))



(http://img329.imageshack.us/img329/3972/e3i6vi1.jpg)


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
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ 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


(http://img154.imageshack.us/img154/1227/e4i1ju9.jpg)


(http://img329.imageshack.us/img329/2599/e4i2go3.jpg)


(http://img329.imageshack.us/img329/3069/e4i3rl1.jpg)

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


(http://img154.imageshack.us/img154/8371/e4i4os4.jpg)

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
Título: Re: Estudio de Graficos en VB
Publicado por: LordLafebre en 27 de Febrero de 2007, 13:28:23
Hola:

Gran trabajo Pedro, crees que nos puedas colaborar con los archivos para mirarlos?  :mrgreen:
Título: Re: Estudio de Graficos en VB
Publicado por: LABmouse en 27 de Febrero de 2007, 13:58:38
que buen tutorial amigo Pedro. Apalusos por tan buen trabajo.  :-)
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ 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
Título: Re: Estudio de Graficos en VB
Publicado por: LordLafebre en 27 de Febrero de 2007, 17:38:31
Hola:

Gracias por los archivos Pedro, excelente la explicacion en cada paso  :-/
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ 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:


(http://img395.imageshack.us/img395/1386/e5i1mh8.jpg)

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 (http://www.4shared.com/file/11452598/1b8d7d22/e5v1.html)

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 (http://www.4shared.com/file/11452668/9e53dfb4/e5v2.html)

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


nota:
- les recomiendo para leer Visual Basic - Guía del Estudiante (http://www.todopic.com.ar/foros/index.php?topic=7080.msg92624#msg92624) 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
Título: Re: Estudio de Graficos en VB
Publicado por: BrunoF 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.
Título: Re: Estudio de Graficos en VB
Publicado por: todopic en 02 de Marzo de 2007, 00:10:19
Muy buen trabajo Pedro!  :-/
Felicitaciones!, y seguimos leyendo  :mrgreen:

Norberto
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ 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:


(http://img364.imageshack.us/img364/8614/e6v1dm4.gif)

- otro cambio (en el timer)

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

el efecto:


(http://img46.imageshack.us/img46/3364/e6v2hp5.gif)

- tercer cambio

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



(http://img364.imageshack.us/img364/760/e6v3rt6.gif)

¡guau! que carteluo (http://www.todopic.com.ar/foros/index.php?topic=15715.msg104989#msg104989). :)

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 (http://www.4shared.com/file/11568111/4ec0ae43/todos_ejemplo_cambiados.html)


Salu2
Pedro
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ 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



(http://img480.imageshack.us/img480/7896/e7i1rj8.jpg)

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:


(http://img480.imageshack.us/img480/2990/e7i2fu4.jpg)

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


(http://img480.imageshack.us/img480/6061/e7i3li4.jpg)

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


(http://img480.imageshack.us/img480/4916/e7i4my3.jpg)

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



(http://img370.imageshack.us/img370/6008/e7v1ut7.gif)

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 


(http://img370.imageshack.us/img370/7224/e7v2hz1.gif)


el adjunto con el avance:

ejemplo7.rar (http://www.4shared.com/file/11568253/c6e4b432/ejemplo7.html)

Salu2
Pedro
Título: Re: Estudio de Graficos en VB
Publicado por: Marioguillote en 04 de Marzo de 2007, 00:19:58
Realmente digno de encuadernar .....
Que buen trabajo Pedro !
Felicitaciones por tu espíritu docente
Gracias

Saludos
Mario
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ en 06 de Marzo de 2007, 12:46:32
Gracias Mario, ¿pero docente yo? que vá, si me oyeras hablando, el propio loco e´carretera  :D

bruno ya le dí una ojeada a tu programa y pude hacer unos cambios para añadirle efectos:

(http://img87.imageshack.us/img87/3579/lodebrunotr5.gif)

el adjunto (http://www.4shared.com/file/11794454/d943d441/texto_moviendose.html)



¿se acuerdan del ejemplo (http://www.todopic.com.ar/foros/index.php?topic=16233.msg106093#msg106093) donde variando el incremento de i en pasos > 1, se aumentaba el time-division? bien, esto no aplica para los arrays de datos, porque ahora la variable i invloucra aparte de las coordenadas, los valores almacenados en datos(x). así que hay que hallar la manera de lograr ese ajuste.

una manera que encontré fué separar las coordenadas de el arrays, con una variable aparte, llamemosla j.

entonces tomando el ejemplo de ruido multicolor, quedaría:

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

con esto aseguramos una buena separación de la señal.

e8i1.jpg
(http://img410.imageshack.us/img410/7429/e8i1qs8.jpg)

¿qué es eso?

¿y porqué esa imagen se vé así?

es lógico que sea así ya que x1 = x2, para arreglar esto veremos unos de los primeros ejemplos, creando una nueva variable para almacenar el valor anterior de x1, es decir que para tener la secuencia de rectas concatenadas por un mismo punto hay que aplicar que:

x1 = valor anterior de x2

x2 = nuevo valor


reescribiendo el código:

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


(http://img410.imageshack.us/img410/8836/e8i2jv4.jpg)

¡ahora si! ;)     ver adjunto al final ejemplo8_5.rar

vamos adentrarnos un poquito más, el caso que quiero plantear es el desplazamiento de la señal de derecha a izquierda, para ver si podemos darle una aplicación prática.

ya sabemos como dibujar una señal dinamicamente, pero después que llega al otro extremo ¡ya se acabó!. nop, así no nos sirve de mucho. La idea principal es poder ver la evolución de la señal continuamente todo el tiempo que queramos.

hay que analizar primero como vamos a desplazar una señal en sentido "<-". el dibujo debe barrerse de cx a 0

también nos podemos imaginar dibujar toda la señal de 0 a cx, como lo veniamos haciendo, solo que esta vez, la variación del dibujo tendrá lugar al final de la escala.

entonces en cada "pintada" habrá un cambio en el cuadro de pintura.

pintada 1 -> variación en cx
pintada 2 -> variación en cx-1
pintada 3 -> variación en cx-2
...

no olviden que estamos pintando desde la esquina inferior izquierda

para emepezar tomemos un código de los ejemplos anteriores:

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

aquí hay que hacer muchas modificaciones, por ej: si vamos a dibujar un desplazamiento, tendremos que usar un ciclo FOR, dentro del timer. para explicar esto mejor, nada mejor que compararlo con la generación de una imagen en un TRC de una pantalla de TV, que es lo que sucede allí: una imagen nueva y completa en un intervalo de tiempo muy pequeño.

en el picturebox se aplica lo mismo, una pintada completa y nueva en un intervalo de tiempo.

Código: Visual Basic
  1. Private Sub Timer1_Timer()
  2.     Randomize
  3.     Picture1.Cls
  4.     x = 0
  5.     j = 0
  6.     dato(i) = Int(Rnd * (cy + 1))
  7.  
  8.     For i = 0 To cx   ' pregunta si i no ha llegado a cx
  9.        Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlack
  10.         x = j
  11.         j = j + 1  ' para lograr el ajuste time-division
  12.    Next i
  13. End Sub


(http://img410.imageshack.us/img410/7496/e8v2nb5.gif)

notas:

- antes que pregunten, picture1.cls es para limpiar el picturebox después de cada pintada, porque sino se montará una linea sobre la otra y no habrá efecto.

- se está usando el array de dato.

- se mantuvo el uso de j para hacer uso del time-division posteriormente.

en el gif animado se puede apreciar como va cambiando los puntos de dato(n) en el tiempo, y ¿como la variación se pinta al extremo derecho?

fijense que aparece una línea en el extremo izquierdo y después se vá al extremo derecho, lo del medio permanece vacio. ¿porqué?

la unica vez que dato(n) contiene un valor distinto de 0 es cuando: n = 0 y n = cx, porque es allí cuando dato(n) toma el valor de:

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

cuando n = 0, es porque inicialmente i = 0, y después del barrido i = cx.

habría que aplicar una validación que para cuando i = 0 no me dibuje nada ó dato(0)=0
pero eso vamos a dejarlo así por los momentos.

-¡ajá PalitroqueZ!- pero -¡eso no se desplaza!-. un momento por favor, hay que ir despacito, para no perder la secuencia (Pedro dialogando con PalitroqueZ) jaja

para poder desplazar esa variación que se vé en el extremo derecho, hay que ir rellenando los dato(n), donde:  0 < n < cx ¿como?

metiendo:

dato(i) = dato(i+1) en el bucle FOR

Código: Visual Basic
  1. Private Sub Timer1_Timer()
  2.     Randomize
  3.     Picture1.Cls
  4.     x = 0
  5.     j = 0
  6.     dato(i) = Int(Rnd * (cy + 1))
  7.  
  8.     For i = 0 To cx   ' pregunta si i no ha llegado a cx
  9.        Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlack
  10.         x = j
  11.         j = j + 1 ' para lograr el ajuste time-division
  12.        dato(i) = dato(i + 1)
  13.     Next i
  14. End Sub


(http://img87.imageshack.us/img87/757/e8v3te9.gif)

todavía tenemos que arreglar el detalle de la recta inicial, y la recta que vá para el otro extremo, que apenas se nota en la parte superior. ya hicimos funcionar esto como queriamos. las rectas se ven gruesas porque DrawWidth = 2, lo cambiaré a 1

y si variamos el time-division j = j + 10 , ¿hará lo mismo?


(http://img410.imageshack.us/img410/2941/e8v4dp6.gif)

esa espera inicial, es cierta y es debido a que la señal está por allá muy lejos de cx, de hecho 10 * cx a través de j que no es mas que x2.

este detalle no lo veré todavía porque falta empatar este código con el otro ¿cuál otro?
es que al inicio del programa se tiene que haber la primera pintada, es decir, pintarse de izquierda a derecha, cuando i = cx se ejecuta este código y comienza el desplazamiento hablado anteriormente.

los adjuntos:

ejemplo8.rar (http://www.4shared.com/file/11794222/7bec9b01/ejemplo8.html)

ejemplo8_5.rar (http://www.4shared.com/file/11794242/2db63c87/ejemplo8_5.html)


continuará...

Salu2
Pedro
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ en 07 de Marzo de 2007, 11:09:47
antes de continuar quiero hacer énfasis nuevamente en el código del desplazamiento:

- lo que llamo desplazamiento de la señal, es pintar continuamente a través de un ciclo for, toda el área interna del picturebox.

- cuando se pinta en el picturebox, dicha pintura (valga la redundancia) se queda allí.

- la pintura anterior hay que quitarla, porque habrá un manchón y no se verá nada.

- existen 2 formas de refrescar al picturebox, una es usando el método cls, el cuál borra toda el área. es el código puesto anteriormente.

- existe otra forma y es usando el método line para dibujar del mismo color del fondo, de manera que a nuestro ojos parezca que se borró la imagen anterior.


Código: Visual Basic
  1. Private Sub Timer2_Timer()
  2.     Randomize
  3.     x = 0
  4.     j = 0
  5.     dato(i) = Int(Rnd * (cy + 1))
  6.  
  7.     For i = 0 To cx   ' pregunta si i no ha llegado a cx
  8.        Picture1.Line (x, dato(i))-(j, dato(i + 1)), &H8000000F
  9.         'dibuja la imagen anterior pero en gris
  10.        Picture1.Line (x, dato(i + 1))-(j, dato(i + 2)), vbBlack
  11.         x = j
  12.         j = j + 2 ' para lograr el ajuste time-division
  13.        dato(i) = dato(i + 1) ' rellenar el dato(n) : 0 < n < cx
  14.    Next i
  15.    
  16.     Label2.Caption = "j= " & j & " cx= " & cx
  17.    
  18. End Sub

hay una cosa curiosa con estos dos casos, en el primero debemos tener autoredraw = true
para evitar un parpadeo entre pintadas, mientras que en el segundo caso podemos colocar autoredraw = false

¿cuál de los casos será mejor en cuanto a rapidez?, no lo sé aún. tengo una Pentium 4 y no he notado diferencias en ambos.


continuando...

como podremos empatar los dos codigos.

el código 1 -> pinta de 0 a cx
el código 2 -> pinta y "desplaza" la gráfica de cx a 0

una forma que se me ocurre es usar 2 control timer, activo uno primero y después el otro

el código1 es el del ejemplo8_5:

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

ya he escrito estas lineas varias veces. pero no importa, así no nos perdemos ;)

reescribiendo el código tenemos:

Código: Visual Basic
  1. Private Sub Form_Load()
  2. ...
  3.     Timer1.Interval = 10
  4.     Timer2.Interval = 10
  5.     Timer1.Enabled = False
  6.     Timer2.Enabled = False
  7. End Sub
  8.  
  9. Private Sub Command1_Click()
  10.     x = 0: y = 0:  i = 0: j = 0
  11.     Picture1.Cls
  12.     Timer1.Enabled = True
  13. End Sub
  14.  
  15. Private Sub Timer1_Timer()   'pinta de 0 a cx
  16.    dato(i + 1) = Int(Rnd * (cy + 1))
  17.     If Not i = cx Then  ' pregunta si i no ha llegado a cx
  18.        Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlack '((&HFFFFFF / (i + 1)))
  19.        x = j
  20.         i = i + 1
  21.         j = j + 1
  22.     Else
  23.     Timer1.Enabled = False  ' ya llego, deja de dibujar
  24.    Timer2.Enabled = True  '
  25.    End If
  26. End Sub
  27.  
  28. Private Sub Timer2_Timer()  ' pinta de cx a 0
  29.    Randomize
  30.     Picture1.Cls
  31.     x = 0
  32.     j = 0
  33.     dato(i) = Int(Rnd * (cy + 1))
  34.  
  35.     For i = 0 To cx   ' pregunta si i no ha llegado a cx
  36.        Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlack '((&HFFFFFF / (i + 1)))
  37.        x = j
  38.         j = j + 1 ' para lograr el ajuste time-division
  39.        dato(i) = dato(i + 1) ' rellenar el dato(n) : 0 < n < cx
  40.    Next i
  41.    
  42.     Label2.Caption = "j= " & j & " cx= " & cx
  43.    
  44. End Sub


(http://img72.imageshack.us/img72/9881/e9v1lz0.gif)

esto vá de lujo.

ni se crean, basta cambiar el time-division y empiezan los problemas.

el problemita que no se resolvió anteriormente y es que si tenemos j = j + n
cuando n = 1,2,3,... hay que esperar mucho tiempo para que aparezca la onda, entonces hay que tratar de que la onda empiece en cx independientemente del valor de j.

entonces tendremos que dividir el código nuevamente y tomar el que vá de derecha a izquierda:

sin mucho rodeo, después de varios ensayos concluí que había que restar al x1,x2 a cx para que me colocara la gráfica exactamente en cx, añadiendo unos multiplos de n
(n viene de j = j + n).

el código quedaría así:

Código: Visual Basic
  1. Private Sub Timer2_Timer()
  2.     Randomize
  3.     Picture1.Cls
  4.     x = 0
  5.     j = 0
  6.     dato(i) = Int(Rnd * (cy + 1))
  7.    
  8.     For i = 0 To cx   ' pregunta si i no ha llegado a cx
  9.        Picture1.Line (x - 19 * cx + 20, dato(i + 1))-(j - 19 * cx + 20, dato(i + 2)), vbBlack
  10.         'Picture1.Line (x - (n-1) * cx + n, dato(i + 1))-(j - (n-1) * cx + n, dato(i + 2)), vbBlack
  11.        x = j
  12.         j = j + 20  ' para lograr el ajuste time-division
  13.        'j = j + n
  14.        dato(i) = dato(i + 1)   ' rellenar el dato(n) : 0 < n < cx
  15.    Next i
  16.     Label2.Caption = "j= " & j & " cx= " & cx
  17.    
  18. End Sub

allí tenemos la relación entre x1, x2 y n.

para cada j = j + 1 -> x1 = x - (n-1) * cx + n ^ x2 = j - (n-1)*cx + n


(http://img72.imageshack.us/img72/4717/e9v2md3.gif)

ya tenemos resuelta esta parte. el otro problema que se presenta es si esto afectará cuando se concatene con el otro código.

Código: Visual Basic
  1. Private Sub Timer1_Timer()  ' corresponde al código 1
  2.    Randomize
  3.     dato(i + 1) = Int(Rnd * (cy + 1))
  4.     If Not i = cx Then  ' pregunta si i no ha llegado a cx
  5.        Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlack
  6.         x = j
  7.         i = i + 1
  8.         j = j + 5
  9.     Else
  10.     i = 0
  11.     Timer1.Enabled = False  ' ya llego, deja de dibujar
  12.    Timer2.Enabled = True  '
  13.    End If
  14. End Sub
  15.  
  16. Private Sub Timer2_Timer() ' corresponde al código 2
  17.    Randomize
  18.     Picture1.Cls
  19.     x = 0
  20.     j = 0
  21.     dato(i) = Int(Rnd * (cy + 1))
  22.  
  23.     For i = 0 To cx   ' pregunta si i no ha llegado a cx
  24.        Picture1.Line (x - 4 * cx + 5, dato(i))-(j - 4 * cx + 5, dato(i + 1)), vbBlack
  25.         x = j
  26.         j = j + 5 ' para lograr el ajuste time-division
  27.        dato(i) = dato(i + 1) ' rellenar el dato(n) : 0 < n < cx
  28.    Next i
  29.    
  30.     Label2.Caption = "j= " & j & " cx= " & cx
  31.    
  32. End Sub



(http://img72.imageshack.us/img72/310/e9v3qs0.gif)

¡Brrrr! que frustación, parece que cada vez que le arreglo un problema al código, este introduce otro.

los codigos por separado funcionan chévere, pero juntos nop. sigue el retardo

si le aplico la misma fórmula al código1 miren lo que pasa:

Código: Visual Basic
  1. Private Sub Timer1_Timer()
  2.     Randomize
  3.     dato(i + 1) = Int(Rnd * (cy + 1))
  4.     If Not i = cx Then  ' pregunta si i no ha llegado a cx
  5.        Picture1.Line (x - 4 * cx + 5, dato(i))-(j - 4 * cx + 5, dato(i + 1)), vbBlack
  6.         x = j
  7.         i = i + 1
  8.         j = j + 5
  9.     Else
  10.     i = 0
  11.     Timer1.Enabled = False  ' ya llego, deja de dibujar
  12.    Timer2.Enabled = True  ' ya llego, deja de dibujar
  13.    End If
  14. End Sub
  15.  
  16. el otro timer queda igual


(http://img145.imageshack.us/img145/7184/e9v4gn1.gif)

se quitó el retardo entre ambos graficos, pero se pasó para el inicio del gráfico 1, y y es lógico pues la fórmula lo que hace es mover el eje de las abscisas

pero así no debe ser, yo quiero que empiece desde origen y que al llegar a cx continue el otro gráfico sin retardos en la imagen ¿se entiende?

en la próxima parte veremos si se puede hallar la solución a este inconveniente.  :?

los adjuntos con los avances.

ejemplo9.rar (http://www.4shared.com/file/11852528/8fbb6492/ejemplo9.html)
ejemplo9codigo2.rar (http://www.4shared.com/file/11852535/e811296e/ejemplo9codigo2.html)

Salu2
Pedro
Título: Re: Estudio de Graficos en VB
Publicado por: LordLafebre en 07 de Marzo de 2007, 18:41:12
Hola:

Sigo con la boca abierta  :shock:, es un exelente trabajo, y si me lo permites Pedro, iré guardando tus mensajes uno a uno y luego los imprimiré y encuadernaré como lo dice Mario, es un trabajo que hay que tener a la mano, no solo sirve para VB y los Pictures, a ver si lo aplico a Proton y GLCD  :P

Gracias por el excelente trabajo.
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ en 08 de Marzo de 2007, 10:53:50
quiero rectificar unas palabras que dije anteriormente

Cita de: PalitroqueZ
Gracias Mario, ¿pero docente yo? que vá, si me oyeras hablando, el propio loco e´carretera 

si me tocara dar clases el algún momento, lo haría. eso si, hablar correctamente y ser muy pedagogico en la materia  :)

---------------------

Hola Giovanni. tienes toda la libertad de ampliar, modificar, mejorar como quieras este tema.  :mrgreen:

Salu2
Pedro
Título: Re: Estudio de Graficos en VB
Publicado por: Milo en 08 de Marzo de 2007, 14:19:38
Eres un crack Pedro, te felicito sinceramente por el estupendo tutorial que nos estas brindando,

Gracias,

Emilio.
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ en 09 de Marzo de 2007, 16:06:24
Amig@s traigo buenas nuevas.

pude resolver el problema, presentado anteriormente. voy intentar explicar como lo resolví.

voy a tomar el código1 y el código2 y analizarlo nuevamente por separado.

analizando el código1:

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

primero que nada vamos a olvidarnos de la relación de n: x1,x2 porque ya no nos servirá, o sea, que el método line quedará así:

Código: Visual Basic
  1. Picture1.Line (x , dato(i))-(j , dato(i + 1)), vbBlack

si analizamos detenidamente esta parte, se puede decir lo siguiente:

- el control timer conforma el bucle del pintado.

- es a través de este bucle que i, j se incrementan

- la variable i tiene el único objetivo de manejar los subindices del array.

- con la introducción de j estamos cambiando los valores de x1, x2

si i no depende de x1,x2 como se había comprobado en los ejemplos probados, entonces no tiene sentido esta línea:

Código: Visual Basic
  1. If Not i = cx Then  ' pregunta si i no ha llegado a cx

de hecho esta debe incluir a j, porque si hacemos una depuración del código, veremos que cuando i = cx -> j llega hasta n * cx (la gráfica sigue mucho después de haber pasado cx)

y aquí es donde está el error, porque la condición debe culminar cuando la pintura llegue hasta cx. ¿ya ven cuál era el problema?

una vez localizado el problema, se resuelve así:


Código: Visual Basic
  1. If Not j > cx Then ' pregunta si j pasó a cx

con esto se garantiza que no importa el valor de n el timer1 terminará cuando j > cx

traducido a terminos de pintura -> no importa el time-division que apliquemos, la gráfica del código1 siempre culminará en el extremo derecho del picturebox.


y para que no quede la menor duda, vamos a explicar visualmente el efecto:

usando If Not i = cx Then

Código: Visual Basic
  1. Private Sub Timer1_Timer()
  2.     dato(i + 1) = Int(Rnd * (cy + 1))
  3.     Label2.Caption = "i= " & i & " j= " & j
  4.     If Not i = cx Then  ' pregunta si i no ha llegado a cx
  5.        Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlack
  6.         x = j
  7.         i = i + 1
  8.         j = j + 5
  9.     Else
  10.     MsgBox "terminó código1"
  11.     End
  12.     End If
  13. End Sub


(http://img19.imageshack.us/img19/4403/e10v1xj1.gif)

usando If Not j > cx + n Then

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


(http://img261.imageshack.us/img261/9608/e10v2ar5.gif)

ven como esta última opción dibuja solo la parte visible. ¡así es como debe ser!

ahh pero ahí se ve que cambió la línea:  If Not j > cx + n ¿y ese 5 sumando a cx?

bueno ese 5 en forma general es n, el n que vá en j = j + n y lo coloqué en el condicional, porque si n es muy grande entonces la gráfica puede NO llegar a cx, ej: supongamos que n = 200, entonces en un momento dado j=80 y en el siguiente j = 80+200. obviamente será mucho mayor que cx y llegará hasta allí nada mas.

claro esto es en caso de un time-division muy grande, eso es parte de los ajustes para una aplicación en particular.


analizando el código2:

el problema en esta parte ya no es con j, es decir con los valores de las coordenadas x1,x2, mas bien es un problema de subindices.

el código2 originalmente:
Código: Visual Basic
  1. Private Sub Timer2_Timer()
  2.     Randomize
  3.     Picture1.Cls
  4.     x = 0: j = 0
  5.     dato(i) = Int(Rnd * (cy + 1))
  6.     For i = 0 To cx   ' pregunta si i no ha llegado a cx
  7.        Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlack
  8.         x = j
  9.         j = j + 1 ' para lograr el ajuste time-division
  10.        dato(i) = dato(i + 1)
  11.     Next i
  12. End Sub


analizando detenidamente:

- el ciclo For es un bucle dentro de otro bucle (control timer)

- el ciclo For hace un barrido pintando el área del picturebox

- en cada ciclo del timer, el área interna del picturebox es pintada con una gráfica nueva y desplazada hacia la izquierda.

- quien se encarga de hacer el desplazamiento es la línea:

dato(i) = dato(i + 1)

se acuerdan que cuando estudiamos este código y subiendole el time-division (j = j + n ) había un retardo


Cita de: PalitroqueZ
...
esa espera inicial, es cierta y es debido a que la señal está por allá muy lejos de cx, de hecho 10 * cx a través de j que no es mas que x2.
...
este detalle no lo veré todavía porque falta empatar este código con el otro
...

esta cita de viene de aquí (http://www.todopic.com.ar/foros/index.php?topic=16233.msg107270#msg107270)

bueno este detalle hay que resolverlo.

para hacer que los valores del array no queden tan lejos de cx, sin cambiar mucho el programa, hay que correr para atras, estos valores EN EL PROPIO INDICE DEL ARRAY.

¿como?

dijimos que 10 veces cx

y que tal si cambiamos a i por cx / n quedando el subindice:

Código: Visual Basic
  1. dato(Int((cx / n))) = Int(Rnd * (cy + 1))

estariamos llevando los datos de la señal de entrada cercano a los valores de las coordenadas x1,x2

y además estamos haciendo independiente el time-division de los datos de entrada de dato()

¿se entiende ahora?

vamos a explicar esto: el antes y el después

el antes: (asumiendo un n = 5)

Código: Visual Basic
  1. Private Sub Timer2_Timer()
  2.     Picture1.Cls
  3.     x = 0: j = 0
  4.     dato(i) = Int(Rnd * (cy + 1))
  5.     For i = 0 To cx   ' pregunta si i no ha llegado a cx
  6.        Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlack
  7.         x = j
  8.         j = j + 5 ' para lograr el ajuste time-division
  9.        dato(i) = dato(i + 1)
  10.     Next i
  11.     Label2.Caption = "i= " & i & " j= " & j
  12.    
  13. End Sub


(http://img235.imageshack.us/img235/6380/e10v3tt6.gif)


el después (asumiendo un n = 5)

Código: Visual Basic
  1. Private Sub Timer2_Timer()
  2.     Picture1.Cls
  3.     x = 0: j = 0
  4.     dato(Int((cx / 5))) = Int(Rnd * (cy + 1))
  5.     For i = 0 To cx   ' pregunta si i no ha llegado a cx
  6.        Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlack
  7.         x = j
  8.         j = j + 5 ' para lograr el ajuste time-division
  9.        dato(i) = dato(i + 1)
  10.     Next i
  11.     Label2.Caption = "i= " & i & " j= " & j
  12.    
  13. End Sub


(http://img101.imageshack.us/img101/5253/e10v4ib5.gif)

¡ven como comienza al inicio de la ejecución!. estamos contrarestando el efecto de n * cx  graficando los nuevos datos en cx / n, es decir, mucho antes que j

también se nota algo extraño cuando el gráfico está en cx, parece que línea pintada proviene de arriba, y es que así es, lo que sucede que estamos viendo como se origina la línea. para evitar esto nada mas ajustar el subindice de dato:

 dato(Int(cx / 5)+ 2) = Int(Rnd * (cy + 1))
 
se corre un pelin a la derecha.

haciendo los respectivos ensayos, se determinó que:

si n = 1 -> dato(Int(cx / n))

si n > 1 -> dato(Int(cx / n) + 2)


bueno, ¡ya está por fin! :) ya no le encontré mas nada hasta ahora (esperemos que no exista mas detalles)

generalizando todo el código:

- llevando el time-division a n

- haciendo una relación entre n y el tiempo de los control timer. la relación para un desplazamiento aceptable que encontré fué:

timer.interval = 3 * n

- para evitar la línea del lado izquierdo en la pintura, basta con hacer inicialmente x = j = - 1

- ya se podran imaginar a estas alturas que n es la base de tiempo (time-division)


video del programa en tiempo de ejecución (http://www.4shared.com/file/11983753/dfdc8fc2/e10v51.html)

aquí (http://www.4shared.com/file/11983772/9aedddd6/ejemplo10.html) está el código completo para graficar un onda del tipo aleatoria y con posibilidad de ajustar dinamicamente la base de tiempo de la señal. ¿¡Queé!? estoy construyendo un osciloscopio en visual basic, no es para tanto pero vá en camino jeje

me disculpan si estuvo larga esta parte, pero es que en verdad me costó entender el problema que había en ambos casos y el como resolverlo.

Salu2
Pedro
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ en 12 de Marzo de 2007, 11:15:20
...
 iré guardando tus mensajes uno a uno y luego los imprimiré y encuadernaré como lo dice Mario, es un trabajo que hay que tener a la mano
...

si yo también voy a imprimir los apuntes de PalitroqueZ  :D para tenerlos a mano, quién sabe si dentro de 1 ó 2 años me acordaré de esto.

---------------------
yo creo que deberiamos ir probando esto con un ejemplo práctico, porque está a nivel general, es decir, hay que ajustarlo a una situación específica.

¡y como no! que mejor que probarlo con un pic enviando datos de un CAD al PC.

vamos asumir un Convertidor Analógico Digital con una resolución a 8 bits, tenemos pues, 256 posibilidades, ó datos que van de 0 a 255.

eso se puede hacer con un vertical scroll bar ajustando las propiedades

Min = 0
Max = 255

y el dato que necesitaremos, lo tomaremos de su propiedad value (que es el cambia cuando movemos clicamos en la barrita)

bueno del código pasado se haran modificaciones, por ejemplo, nosotros estabamos usando como datos de entrada la función random

Código: Visual Basic
  1. dato(xxx) = Int(Rnd * (cy + 1))

lo cambiaremos por  VScroll1.Value.

ahh pero no se crean que la cosa es así de fácil, hay que cuadrar los nuevos valores, es decir, llevaremos el rango de 0 - 255 a 0 - cy que es la escala vertical de nuestro picturebox.

no se cuanto vale cy, y no importa, mejor es hacerlo independiente.

¿se acuerdan que el amigo BrunoF nos dijo que el origen del picturebox estaba en la parte superior?, en nuestro caso ya sabemos que debe estar en la parte inferior. nada mas debemos restar VScroll1.Value a cy

cy - VScroll1.Value

pero todavía falta para no perder la señal fuera del área visible (cambiamos solo la ubicación)

sabemos que tenemos a 0 <= VScroll1.Value <= 255. podemos hacer como en post anteriores: dividir

tenemos cy / VScroll1.Value

recuerden cy = scaleheight

entonces el valor máximo que podemos tener para scaleheight (con VScroll1.Value = 255)

cy /255 = x -> esta es la referencia


si este x lo multiplicamos por el VScroll1.Value en un determinado momento tendremos la escala ajustada al picturebox ( scaleheight = 0 a cy )

ejemplos en valores extremos:

VScroll1.Value= 0

dato = 0 * cy / 255 = 0

VScroll1.Value = 255

dato = 255 * cy / 255 = cy

en definitiva:

dato(xxx) = cy - VScroll1.Value * cy / VScroll1.Max

otro detalle es que si VScroll1.Value = 0 se pierde la gráfica del área visible, quiere decir que debemos agregar un condicional que vigile cuando tengamos esa unica situación

   
Código: Visual Basic
  1. If VScroll1.Value = 0 Then
  2.      valor = 1
  3.     End If
  4.    
  5.     dato(xxx) = cy - valor * cy / VScroll1.Max

¡recuerden que el CAD puede arrojar 0 volts en ADRESL!

bueno creo que eso es toda la modificación que se le puede hacer.

un ventanazo del programa


(http://img145.imageshack.us/img145/8537/ventanazoey5.jpg)

un videito sobre el funcionamiento:

programa en ejecución.wmv (http://www.4shared.com/file/12126495/3899abc1/e11v1_wmv.html)


aquí (http://www.4shared.com/file/12126534/b4b319ea/ejemplo11_vb.html) está el programa para que vean como se puede hacer dibujar una señal con solo tener datos de 0 a 255


Salu2
Pedro

Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ en 12 de Marzo de 2007, 11:33:27
bueno amig@s, la aplicación práctica al ejemplo anterior la pueden encontrar en Mis primeros pasos con el 18F4550 (http://www.todopic.com.ar/foros/index.php?topic=15208.msg108020#msg108020)


Salu2
Pedro
Título: Re: Estudio de Graficos en VB
Publicado por: LordLafebre en 23 de Marzo de 2007, 17:07:36
Hola:

Pues gracias al excelente trabajo de Pedro, he podido hacer también mis gráficas, pero no en un monitor, ni tampoco en VB, mas bien en un GLCD y con MKB.

Una bien formada onda Senoidal:

(http://img231.imageshack.us/img231/2498/glcdsenoqv4.jpg)


Claro, como siempre, acompañada de mi inseparable GTP +


(http://img231.imageshack.us/img231/5863/glcdsenogtpps6.jpg)


Gracias Perdo por tan buena explicación  :-/ :-/
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ en 23 de Marzo de 2007, 17:35:11
¡Que barbaro!  :shock: Te felicito sinceramente Giovanni  :-/

y que pantallota, ¿de cuanto pixels son?

Título: Re: Estudio de Graficos en VB
Publicado por: LordLafebre en 23 de Marzo de 2007, 17:51:25
Hola:

Pedro, pues las felicitaciones van para tí, yo solo cambien ciertas funciones a las del MKB, nada más, el GLCD es uno de 240x128 con controlador T6963C
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ en 23 de Marzo de 2007, 17:59:53
tendré que conseguirme una GLCD de esas un dia de estos, yo también quiero hacer pruebas  :-)
Título: Re: Estudio de Graficos en VB
Publicado por: LordLafebre en 23 de Marzo de 2007, 18:21:39
Hola:

Está interesante, luego probaré a graficar entradas analógicas  :-/, claro, siguiendo tu tutorial  :mrgreen:
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ en 23 de Marzo de 2007, 18:24:29
espero con ansias el dibujo en modo dinámico :mrgreen: (digo si se puede)
Título: Re: Estudio de Graficos en VB
Publicado por: LordLafebre en 23 de Marzo de 2007, 18:41:48
Hola:

Claro, no te preocupes, pero será en unos pocos dias, hay algo que tengo que hacer primero  :D y luego si con el GLCD  :mrgreen:
Título: Re: Estudio de Graficos en VB
Publicado por: Blanca Sánchez en 07 de Abril de 2008, 17:09:53
Hola muchachos!:

Yo también estoy haciendo algunas gráficas de datos con Visual Basic 6.0 y todo va perfecto. Sin embargo tengo una duda, porque a la hora de imprimir el formulario (con form1.printform) donde se encuentra la gráfica (dentro de un picturebox) se imprimen las líneas auxiliares pero la línea que trazo con el picture1.line se mueve de lugar... es decir, cuando en pantalla veo la gráfica dentro del picturebox en la hoja impresa se mueve...

(http://img148.imageshack.us/img148/9812/dibujo4oy2.png)


Leí en el manual de "Aprenda Visual Basic 6.0 como si estuviera en primero" lo siguiente:

"El método PrintForm permite imprimir un formulario con sus controles y con los resultados de los
métodos gráficos (PSet, Line y Circle) y del método Print. Para ello la propiedad AutoRedraw del
formulario tiene que estar puesta a True, y los métodos citados tienen que estar llamados desde un
evento distinto del Paint."

Claro que tengo la propiedad AutoRedraw = True...  porque el problema no es que no lo haga (porque si lo hace)... mi problema es que se mueve de lugar :? :?
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ en 08 de Abril de 2008, 13:03:18
hola blanca

seguramente tiene que ver con las coordenadas internas del picturebox, éstas son aparte de las coordenadas del form

picturebox tiene las 2 propiedades

Picture1.ScaleHeight
Picture1.ScaleWidth

debes hacer que el cálculo de dibujar lineas coincida siempre dentro del picture (los que quieras que se muestrer) y para ello el resultado de tu cálculo debe estar en los margenes de ScaleWidth y ScaleHeight



Título: Re: Estudio de Graficos en VB
Publicado por: MARKUS en 26 de Octubre de 2008, 06:07:21
Saludos!!
Gran, gran tutorial señor PalitroqueZ. Muchas gracias!
Título: Re: Estudio de Graficos en VB
Publicado por: IAO en 22 de Diciembre de 2008, 18:20:04
Holaaaaa:

Quería dejarles un regalo para esta navidad del 2008, pero se me complicó un poco el asunto.
De todas maneras como era un regalo y a caballo regalado no se le mira los defectos, aquí está en .Zip.

Recuerde que para ver la onda hay que hacer un puente en el conector rs232. Los pines 2-3 un cablecito y ya.

Gracias a Palitroquez, por su explicación en todo este tema.
Unas Capturas de muestra...
En esta no se ve la forma de la onda en el VB programa, por no estar conectados los pines 2-3 del rs232.
Pero se vé un dispositivo externo, recibiendo señal rs232 y graficando la onda senidal.

(http://img377.imageshack.us/img377/8323/captura1fp8.png) (http://imageshack.us)

---
Aquí se puede apreciar el defecto y la forma de la onda, no pude quitarle esos trazos en los extremos. Hice cuanto pude.
Por lo demás trabaja bién.

(http://img377.imageshack.us/img377/381/captura2tw6.png) (http://imageshack.us)
(http://img377.imageshack.us/img377/captura2tw6.png/1/w438.png) (http://g.imageshack.us/img377/captura2tw6.png/1/)


Gracias a Palitroquez!!!!!! ------ Gracias a Palitroquez!!!!!! ------- Gracias a Palitroquez!!!!!!


Feliz Navidad a Todos...Jojojojojojojojojo   :-/ :-/ :-/



Bye('_').....
Título: Re: Estudio de Graficos en VB
Publicado por: kriskmilo en 02 de Enero de 2009, 13:49:40
Oye que buen regalo, muchas gracias a todos :)!!!
Título: Re: Estudio de Graficos en VB
Publicado por: BrunoF en 25 de Enero de 2009, 06:37:25
Buenas!

Para eliminar la linea incorrecta a la izquierda, reemplazar esto:

Private Sub Timer1_Timer()     '''Este es el que grafica en el PictureBox
    Picture1.Cls
    x = -1
    y = -1

por esto:

Private Sub Timer1_Timer()     '''Este es el que grafica en el PictureBox
    Picture1.Cls
    x = 0
    y = n




Y para eliminar las de la derecha, lo que debes hacer es en este bucle:


    For i = 0 To cx 'Int(cy - y * (cx / 2))
        Picture1.Line (x, dato(i))-(y, dato(i + 1)), vbBlue
        x = y
        y = y + n             ' para lograr el ajuste time-division
        dato(i) = dato(i + 1) ' rellenar el dato(n) : 0 < n < cx
    Next i

es no usar cx como limite del for. El limite del for debe ser la cantidad de datos presentes en el buffer dato() menos dos elementos. Es decir que si en dato() existen actualmente 50 elementos útiles el for debería ser hasta 48(inclusive). Utiliza una variable para contar la cantidad de datos en buffer y utilizarla entonces luego en el for.

Un saludo.
Título: Re: Estudio de Graficos en VB
Publicado por: IAO en 26 de Enero de 2009, 11:51:10
Holaaa:

Sr. maestro BrunoF:
Gracias por su explicación, si mejoró pero relativamente. En lo que tenga un chance
coloco una captura.

Respecto a la error derecho:
Debo ajustar el eje x, porque la onda se desplazo como 2cm hacia la izquierda, pero ese defecto
de la derecha se quitó.
Respecto a la error izquierdo:
El de la izquierda está practicamente igual.

Bye('_')...
Título: Re: Estudio de Graficos en VB
Publicado por: gera en 26 de Enero de 2009, 12:29:08
Muy bueno PalitroqueZ!!! Jamas se me hubiera ocurrido hacer algo asi en mis epocas de programador en VB jaja. Aun q creo q existen librerias y otras herramientas para graficar. He visto compañeros usar algunas, pero nunca supe cuales eran.
Muchas gracias por compartir esto con nosotros! saludos!
Título: Re: Estudio de Graficos en VB
Publicado por: BrunoF en 26 de Enero de 2009, 13:42:04
Hola IAO. Espero esa captura y codigo fuente de ser posible..Yo tuve que simular una onda porque carezco de puerto serie, tal vez por eso  tenemos discrepancias.
Título: Re: Estudio de Graficos en VB
Publicado por: IAO en 29 de Enero de 2009, 20:23:44
Holaaa:

Sr. maestro BrunoF:
Aquí está la captura que prometí. He estado un tanto ocupado y la inalambrica se me cae a cada rato.
(http://img140.imageshack.us/img140/7889/captura3bl2.png) (http://imageshack.us)
(http://img140.imageshack.us/img140/captura3bl2.png/1/w443.png) (http://g.imageshack.us/img140/captura3bl2.png/1/)

Código: [Seleccionar]
Private Sub Timer1_Timer()     '''Este es el que grafica en el PictureBox
    Picture1.Cls
    x = 0
    y = 0   
    For i = 0 To 380 '''<---Aquí
        Picture1.Line (x, dato(i))-(y, dato(i + 1)), vbBlue
        x = y
        y = y + n             ' para lograr el ajuste time-division
        dato(i) = dato(i + 1) ' rellenar el dato(n) : 0 < n < cx
    Next i
   Timer1.Enabled = False  ' ya llego, deja de dibujar
   Timer2.Enabled = True   ' ya llego, deja de dibujar
   
End Sub

380 es el valor -2 que me arroja, la variable según sus comentarios.
Voy a tener que abrir otra publicación para no llenarle de basura esta publicación al compañero
Palistroquez.

Bye('_').....
Título: Re: Estudio de Graficos en VB
Publicado por: Suky en 19 de Enero de 2010, 18:08:09
Hola a todos! Estoy aprendiendo a manejar el tema de gráficos en VB pero .net, es más o menos lo mismo, lo único es que por ejemplo para un rectángulo sin relleno será algo así:

Código: [Seleccionar]
PictureBox.DrawRectangle(New Pen(Color.Blue,1),New Point(10,10), New Point(50,100))
Eso genera un rectángulo de color azul con linea de grosor 1, con el extremo superior izquierdo en (10,10), de ancho 50 y alto 100.

Si quieren un rectángulo relleno sería:

Código: [Seleccionar]
PictureBox.FillRectangle(New SolidBrush(color.Blue),New Point(10,10), New Point(50,100))

Pero tengo un problema  :mrgreen: Cuando coloco otra ventana sobre el dibujo se borra  :( Como soluciono eso? Osea, como mantengo lo dibujado  :?


Saludos!
Título: Re: Estudio de Graficos en VB
Publicado por: BrunoF en 19 de Enero de 2010, 18:50:05
Esa propiedad se llama Autoredraw. Tiene que estar a TRUE.
Título: Re: Estudio de Graficos en VB
Publicado por: BrunoF en 19 de Enero de 2010, 18:53:34
Peero en .NET no existe mas, por lo que hay que rebuscarselas un poco.

Este link puede ayudar:

http://www.c-sharpcorner.com/UploadFile/rmeyer/AutoRedrawInVBdotNET11162005064540AM/AutoRedrawInVBdotNET.aspx

Suerte.
Título: Re: Estudio de Graficos en VB
Publicado por: Suky en 19 de Enero de 2010, 20:56:14
Esa propiedad se llama Autoredraw. Tiene que estar a TRUE.

 :( :(

Leyendo el link para ver como solucionarlo.

Muchas gracias!

Saludos!
Título: Re: Estudio de Graficos en VB
Publicado por: PalitroqueZ en 19 de Enero de 2010, 21:55:19
bueno yo no conozco como maneja el net el tema del gráfico, pero debería existir un método llamado repaint o update.


Título: Re: Estudio de Graficos en VB
Publicado por: albermillan69 en 13 de Abril de 2010, 12:56:04
Como puedo leer un dato de 10bits via serial (del pic a la pc) para luego grficarlo??

Gracias ppor su ayuda!!!
Título: Re: Estudio de Graficos en VB
Publicado por: Suky en 13 de Abril de 2010, 13:01:22
Envíalo en 2 bytes, y en VB trabajan con una variable de 16-bits para reconstruirlos.


Saludos!