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

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

Desconectado Marioguillote

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1926
    • Servisystem
Re: Estudio de Graficos en VB
« Respuesta #15 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

Desconectado PalitroqueZ

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Estudio de Graficos en VB
« Respuesta #16 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:



el adjunto



¿se acuerdan del ejemplo 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


¿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




¡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




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




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?




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

ejemplo8_5.rar


continuará...

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 #17 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




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




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





¡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




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
ejemplo9codigo2.rar

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 #18 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.

Desconectado PalitroqueZ

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Estudio de Graficos en VB
« Respuesta #19 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
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado Milo

  • PIC16
  • ***
  • Mensajes: 101
Re: Estudio de Graficos en VB
« Respuesta #20 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.
« Última modificación: 08 de Marzo de 2007, 14:21:19 por Milo »
"En tanto que haya alguien que crea en una idea, la idea vive" Ortega y Gasset

Desconectado PalitroqueZ

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Estudio de Graficos en VB
« Respuesta #21 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




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




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í

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





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




¡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

aquí 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
« Última modificación: 09 de Marzo de 2007, 16:11:02 por PalitroqueZ »
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 #22 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




un videito sobre el funcionamiento:

programa en ejecución.wmv


aquí está el programa para que vean como se puede hacer dibujar una señal con solo tener datos de 0 a 255


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 #23 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


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 #24 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:




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





Gracias Perdo por tan buena explicación  :-/ :-/

Desconectado PalitroqueZ

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Estudio de Graficos en VB
« Respuesta #25 en: 23 de Marzo de 2007, 17:35:11 »
¡Que barbaro!  :shock: Te felicito sinceramente Giovanni  :-/

y que pantallota, ¿de cuanto pixels son?

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 #26 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

Desconectado PalitroqueZ

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Estudio de Graficos en VB
« Respuesta #27 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  :-)
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 #28 en: 23 de Marzo de 2007, 18:21:39 »
Hola:

Está interesante, luego probaré a graficar entradas analógicas  :-/, claro, siguiendo tu tutorial  :mrgreen:

Desconectado PalitroqueZ

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Estudio de Graficos en VB
« Respuesta #29 en: 23 de Marzo de 2007, 18:24:29 »
espero con ansias el dibujo en modo dinámico :mrgreen: (digo si se puede)
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek