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:Private Sub Timer1_Timer()
Randomize
dato(i + 1) = Int(Rnd * (cy + 1))
If Not i = cx Then ' pregunta si i no ha llegado a cx
'Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlack '((&HFFFFFF / (i + 1)))
Picture1.Line (x - 4 * cx + 5, dato(i))-(j - 4 * cx + 5, dato(i + 1)), vbBlack
x = j
i = i + 1
j = j + 5
Else
i = 0
Timer1.Enabled = False ' ya llego, deja de dibujar
Timer2.Enabled = True ' ya llego, deja de dibujar
End If
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í:
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:
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í:
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 ThenPrivate Sub Timer1_Timer()
dato(i + 1) = Int(Rnd * (cy + 1))
Label2.Caption = "i= " & i & " j= " & j
If Not i = cx Then ' pregunta si i no ha llegado a cx
Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlack
x = j
i = i + 1
j = j + 5
Else
MsgBox "terminó código1"
End
End If
End Sub
usando If Not j > cx + n ThenPrivate Sub Timer1_Timer()
dato(i + 1) = Int(Rnd * (cy + 1))
Label2.Caption = "i= " & i & " j= " & j
If Not j > cx + 5 Then ' pregunta si i no ha llegado a cx
Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlack
x = j
i = i + 1
j = j + 5
Else
MsgBox "terminó código1"
End
Timer1.Enabled = False ' ya llego, deja de dibujar
Timer2.Enabled = True ' ya llego, deja de dibujar
End If
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:
Private Sub Timer2_Timer()
Randomize
Picture1.Cls
x = 0: j = 0
dato(i) = Int(Rnd * (cy + 1))
For i = 0 To cx ' pregunta si i no ha llegado a cx
Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlack
x = j
j = j + 1 ' para lograr el ajuste time-division
dato(i) = dato(i + 1)
Next i
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
...
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:
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)
Private Sub Timer2_Timer()
Picture1.Cls
x = 0: j = 0
dato(i) = Int(Rnd * (cy + 1))
For i = 0 To cx ' pregunta si i no ha llegado a cx
Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlack
x = j
j = j + 5 ' para lograr el ajuste time-division
dato(i) = dato(i + 1)
Next i
Label2.Caption = "i= " & i & " j= " & j
End Sub
el después (asumiendo un n = 5)
Private Sub Timer2_Timer()
Picture1.Cls
x = 0: j = 0
dato(Int((cx / 5))) = Int(Rnd * (cy + 1))
For i = 0 To cx ' pregunta si i no ha llegado a cx
Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlack
x = j
j = j + 5 ' para lograr el ajuste time-division
dato(i) = dato(i + 1)
Next i
Label2.Caption = "i= " & i & " j= " & j
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ónaquí 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