|
-
Dec 19th, 2001, 03:44 PM
#1
line scroller
well, okay, this is exactly what I want to do...
lets take a tredmill for example.
I want to make, say a training program, where I tell the runner how fast he has to run. let say this speed is going to vary. So, I have a speed versus time line. with the left edge being zero and the right being 100 feet per second, the line will start at the top and scroll down. This is theoretical speed. Now, we take the cursor which is actual speed of the tredmill (I can handle all the hardware to get the speed from the transducer into a variable). This will scroll left to right (left zero right 100). The name of the game is for the runner to keep his cursor over the line as it varies. If he is off the line, say by 2 fps, the cursor turns red. I can deal with all the hardware and all the other logic behind it, its just this graphical subroutine that has me stumped.
-
Dec 20th, 2001, 03:23 AM
#2
If I get you right, you want to do:
First show the desired speed.
Do that by printing a point or a small line segment at the actual time line (left/rigth for speed differences up/down for time) in PictureBox.
Second you want that line to show also the old values of the speed (i.e. the history).
To do that just "bitBlt" the whole PictureBox nearly onto itself (move it for one Timestep). By that you will see the last time/speed Line/Point moved ontop or under itself. Now you can erase the last printed value and print a new one (each time at the same timeline!). Use "GetTickCount" for the time-schedule.
Now you will have a "waterfall" display of the desired speed.
The next is your "Cursor". Take your value of the tredmill and use the it to place a line object ontop of the picturebox. The Time position should never change.
If you need more help, call back. I used that technic the make a waterfall-display in another application, it works!!
Bye the way, the better running-training is doing it for real! You get fresh air and sometimes even a good look onto other runners (hopefully from the other sex).
My Marathon PB 3:08!!
You're welcome to rate this post!
If your problem is solved, please use the Mark thread as resolved button
Wait, I'm too old to hurry!
-
Dec 20th, 2001, 04:52 AM
#3
PowerPoster
hi
here is some code to give u some ideas. I have gone for an eternal looping set of pictures rather than one big picture. you could use one big picture and just set the top property however you will max out at 96000 if that is a problem.
This code uses 2 picture boxes that are alternatively the current drawing pic and the one above or below that is simply scrolling.
It doesnt use any API routines and so u may want to go that way for less flicker (i write financial software not graphics ).
hope it helps
Regards
Stuart
Form contains
1 command button Command1 on form
1 Timer.. timer1 with Interval = 200
1 picture called pic_container on form
2 pictures pic_inner(0) and (1) inside pic_container
I have set most properties thru code so it should run straight from here. If i have missed any properties that i set at design time just ask and i will check for you.
VB Code:
Option Explicit
Private Const GridScale As Long = 1000 'Grid Height and Width . U may want to have one for each
Private Const ScrollPosn As Long = 700 'Point at where the tape starts scrolling
Private Const ScrollJump As Long = 20 'X and Y jump. Again u may want to separate
Dim lCounter As Integer 'Loop counter
Dim XPosn As Single 'X Posn of line
Dim YPosn As Single 'Y Posn of line
Dim XMarker As Single 'Your minimum line
Dim CurPicture As Integer 'Which picture is being drawn on
Dim lScroll As Boolean 'Are we ready to scroll
Private Sub SetupTreadMill()
XPosn = GridScale / 2 'Default X Posn
YPosn = 0
XMarker = GridScale / 2
CurPicture = 0
Randomize 'Used to make 'runner' .. u would use actuals
With pic_container 'Set up container picture
.BorderStyle = 0
.Height = 4 * GridScale
.Width = 4 * GridScale
.ScaleHeight = GridScale
.ScaleWidth = GridScale
End With
'These 2 pictures are IN pic_container
For lCounter = 0 To 1
With pic_inner(lCounter)
.Cls
.AutoRedraw = True
.BackColor = vbWhite
.BorderStyle = 0
.DrawWidth = 1
.Move 0, lCounter * GridScale, GridScale, GridScale
.ScaleHeight = GridScale 'Set scaling
.ScaleWidth = GridScale
End With
With Line1(lCounter) 'Your minimum line
.X1 = XMarker: .X2 = XMarker: .Y1 = 0: .Y2 = GridScale
End With
Next
With HScroll1 'Scroll bar for your minimum line
.Move pic_container.Left - 300, pic_container.Top + pic_container.Height, pic_container.Width + 600
.Min = 0
.Max = GridScale
.Value = XMarker
.SmallChange = GridScale / 50
.LargeChange = GridScale / 20
End With
End Sub
Private Sub Command1_Click()
SetupTreadMill 'Set up the form
DrawGridLines 0 'Draw grid lines for first pic
DrawGridLines 1
SetStartPosn 0 'Set starting position for first pic
Timer1.Enabled = True 'Start it rolling
End Sub
Private Sub DrawGridLines(ByVal WhichPic As Integer)
'Downward lines
With pic_inner(WhichPic)
.Cls
For lCounter = 1 To 3
pic_inner(WhichPic).Line (lCounter * GridScale / 4, 0)-(lCounter * GridScale / 4, GridScale), vbBlue
Next
End With
End Sub
Private Sub SetStartPosn(ByVal WhichPic As Integer)
'Starting positions
With pic_inner(WhichPic)
.CurrentX = XPosn
.CurrentY = YPosn
.ZOrder
End With
End Sub
Private Sub Timer1_Timer()
GetRandomValues
DrawLine
ScrollDown
End Sub
Private Sub GetRandomValues()
'Add or subtract from the current x position
XPosn = Int(Rnd * ScrollJump * 2) - ScrollJump + XPosn
If XPosn < 0 Then XPosn = 0
If XPosn > GridScale Then XPosn = GridScale
YPosn = YPosn + ScrollJump 'Move down a bit
End Sub
Private Sub DrawLine()
Dim lColour As Long
'Set colour based on above or below minimum
lColour = vbBlack
If XPosn < XMarker Then lColour = vbRed
With pic_inner(CurPicture)
'Draw line
pic_inner(CurPicture).Line -(XPosn, YPosn), lColour
.CurrentX = XPosn 'Update X Y posn
.CurrentY = YPosn
End With
End Sub
Private Sub ScrollDown()
If YPosn > ScrollPosn Then lScroll = True 'Once only to set scrolling
If lScroll Then
With pic_inner(CurPicture)
.Top = ScrollPosn - YPosn 'Move picture up
If .Top <= 0 Then 'Is it negative?
'then other pic should be below it
pic_inner(1 - CurPicture).Top = .Top + .Height
Else 'otherwise it is above it
pic_inner(1 - CurPicture).Top = .Top - .Height
End If
'Is the non current pic fully off the page?
If pic_inner(1 - CurPicture).Top <= -.Height + ScrollJump * 2 Then
pic_inner(1 - CurPicture).Cls 'Clear it
DrawGridLines 1 - CurPicture 'REdraw lines
End If
End With
If YPosn >= GridScale Then 'Have we reached end of current pic
CurPicture = 1 - CurPicture 'Swap to other pic
YPosn = 0 'Reset Y to top
With pic_inner(CurPicture)
.CurrentX = XPosn 'Get X position
.CurrentY = YPosn
End With
End If
End If
End Sub
Private Sub HScroll1_Change()
'Move the minimum line
XMarker = HScroll1.Value
For lCounter = 0 To 1
With Line1(lCounter)
.X1 = XMarker: .X2 = XMarker: .Y1 = 0: .Y2 = GridScale
End With
Next
End Sub
-
Dec 20th, 2001, 04:54 AM
#4
PowerPoster
oops
and 1 Horizontal scroll bar Hscroll1
-
Dec 20th, 2001, 05:17 AM
#5
-
Dec 20th, 2001, 07:21 AM
#6
beachburn did give some code but as he said
It doesnt use any API routines and so u may want to go that way for less flicker
I believe you will get lots of flickering.
Sorry at present I can't send you my code example, which uses API. You have to wait til this evening (GMT+1).
One question for beachburn, whow do you show the changing "desired" speed. If I understand your code correctly the gridlines never change the position. I'd prefer to show a change in desired speed by changing this "target " line. But that way you will have a "snaking" Line (sorry, but I'm not a native english speaker).
You're welcome to rate this post!
If your problem is solved, please use the Mark thread as resolved button
Wait, I'm too old to hurry!
-
Dec 20th, 2001, 08:02 AM
#7
well actually, a "snaking" line is what I was looking for. Lets say the entire screen top to bottom represents 20 seconds. I would like time zero (now) to be 5 seconds from the bottom. This would give me a little history of what I was supposed to do and a 15 second window of what is coming up.
graphics is not my thing at all. I am a hardware guy that can do some logic programming (plc's). So, you will have to be the judge as to what will look good. Remember, this has to be smooth, otherwise the runner will get "sea sick" from the flicker.
Thanx
BoB
-
Dec 20th, 2001, 04:19 PM
#8
You need on your form a PicureBox and 2 Line-Objects (VerticalLine, HorizontalLine) (They make a cross)
The PictureBox will showw the desired speed at present at the lower horizontal limit, the older values will be move to the top.(I didn't use your times, so you have to work them out yourself).
The cross(VerticalLine, HorizontalLine) should show the actual treadmill speed. You can show that cross always at the lower limit (that way you will not see which speed should be used in the future) or you can show somewhere to the top (that way you can see future and history speeds)
In here the speed ranges from 0 to 100 (PictureBox.Scalewidth)
Start/stop is done by clicking onto the PictureBox
Code:
Option Explizit
'API for TimeControlling
Private Declare Function GetTickCount Lib "kernel32.dll" () As Long
'API for the Graphic Part
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal xDest As Long, ByVal_ yDest As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal_ xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Dim Start as Boolean
Dim ActualTime as Long
Dim LastTime as Long
Dim Tread_Mill_Speed as Single
Dim DesiredSpeed as Single
Private Sub Form_Load()
Dim Ret As Integer
MainForm.PictureBox. AutoRedraw = -1 'True
MainForm.PictureBox.ScaleHeight = 125
MainForm.PictureBox. ScaleMode = 3 'Pixel
MainForm.PictureBox. ScaleWidth = 100
Call Show_Tread_Mill_Speed (MainForm.PictureBox. ScaleWidth /2 )
End Sub
Private Sub PictureBox_MouseDown (Button As Integer, Shift As Integer, x As Single, y As Single)
If Start=True then
Start=False
Else
Start=True
End Sub
Private Sub Time_Control()
Do
If Start = True Then
ActualTime = GetTickCount()
'In here you can control whow fast the display is running to the top
If LastTime +1000 <= ActualZeit Then
Call PictureBox_Mover
'In here you must give Tread_Mill_speed the correct value
If Tread_Mill_Speed< DesiredSpeed then
VerticalLine.ForeColor=vbRed
HorizontalLine.ForeColor=vbRed
Else
If Tread_Mill_Speed< DesiredSpeed then
VerticalLine.ForeColor=vbBlue
HorizontalLine.ForeColor=vbBlue
Else
VerticalLine.ForeColor=vbGreen
HorizontalLine.ForeColor=vbGreen
End If
End If
Call Show_Tread_Mill_Speed (Trad_Mill_Speed)
LastSimTime = ActualZeit
End If
DoEvents
Else
Exit Do
End If
Loop
End Sub
Private Sub Show_Tread_Mill_Speed (Trad_Mill_Speed as single)
MainForm.VerticalLine.X1=Trad_Mill_Speed
MainForm.VerticalLine.X2=Trad_Mill_Speed
MainForm.VerticalLine.Y1=MainForm.PictureBox.ScaleHeight
MainForm.VerticalLine.Y2=MainForm.PictureBox.ScaleHeight-6
MainForm.HorizontalLine.X1=Trad_Mill_Speed -3
MainForm.HorizontalLine.X2=Trad_Mill_Speed +3
MainForm.HorizontalLine.Y1=MainForm.PictureBox.ScaleHeight
MainForm.HorizontalLine.Y2=MainForm.PictureBox.ScaleHeight-3
End Sub
Private Sub PictureBox_Mover
'Set a Point at the actual desired Speed onto the picturebox
PictureBox.PSet (DesiredSpeed, PictureBox.Height - 6), vbBlack
'Move the upper (i.e.)older part further up
Ret = BitBlt(PictureBox.hdc, 0, 0,PictureBox.ScaleWidth, PictureBox.ScaleHeight, PictureBox.hdc, 0,_ 1, SRCCOPY)
End Sub
I hope that works. I had to do it without VB, since I'm at home. Sorry for any errors.
You're welcome to rate this post!
If your problem is solved, please use the Mark thread as resolved button
Wait, I'm too old to hurry!
-
Dec 20th, 2001, 04:52 PM
#9
PowerPoster
Originally posted by opus
I believe you will get lots of flickering.
Actually, u don't get much flickering at all because the grid lines and speed line are all vertical. Make any horizontal lines and bammo flicker.
Originally posted by opus
One question for beachburn, whow do you show the changing "desired" speed. If I understand your code correctly the gridlines never change the position. I'd prefer to show a change in desired speed by changing this "target " line. But that way you will have a "snaking" Line (sorry, but I'm not a native english speaker).
The Line1(0) and Line1(1) are used for the 'target minimum' value. This line is moved with the scroller bar. Anyways, rdepalma, try it out in a blank project and let me know if this is the concept that you are after. ps opus, question for you. why so many object references? Surely that will slow things down considerably. Can't u just use With... End With and also remove any references to the form as the routines are private.
Regards
Stuart
-
Dec 20th, 2001, 05:14 PM
#10
That point goes to you, Beach
You're welcome to rate this post!
If your problem is solved, please use the Mark thread as resolved button
Wait, I'm too old to hurry!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|