I have started the timer with Game.Start() and by using a breakpoint I have determined that the timer is enabled, the interval is 100. However when stepping through my code, the timer sub is ignored and the paint sub is given priority. Therefore, the timer is never being run.
Here is the code which i am referring to :
Public Class Form1
Dim speed_s As Integer = 5
Dim speed_w As Integer = 5
Dim speed_d As Integer = 5
Dim speed_a As Integer = 5
Dim Enemy1 As New computerControlled(1, 1, Me)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
player1.Bounds = New Rectangle(player1.Location.X, player1.Location.Y, player1.Width, player1.Height)
'Enemy1.DrawEnemy(Me)
Game.Enabled = True
Game.Start()
End Sub
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.W Then
player1.Top -= speed_w
ElseIf e.KeyCode = Keys.S Then
player1.Top += speed_s
ElseIf e.KeyCode = Keys.A Then
player1.Left -= speed_a
ElseIf e.KeyCode = Keys.D Then
player1.Left += speed_d
' Enemy1.enemypic.Left += 10 this moves enemy class well
End If
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Game.Tick
'Enemy1.enemypic.Left += 10
Enemy1.Walk()
MsgBox("hi")
End Sub
Private MOUSE_X As Integer
Private MOUSE_Y As Integer
Private Sub Form1_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
MOUSE_X = e.X
MOUSE_Y = e.Y
End Sub
Private Sub Player_Paint(sender As Object, e As PaintEventArgs) Handles player1.Paint
Dim GFX As Graphics = e.Graphics
Dim BMP As Bitmap = Image.FromFile("c:\firaas\ball.png")
Dim center As Point = New Point(player1.Width \ 2, player1.Height \ 2)
Dim angle As Integer
Dim rad As Double
Dim CENTRE_X As Integer
Dim CENTRE_Y As Integer
'=========================
Using cyan As New Pen(Brushes.Cyan, 2)
GFX.ResetTransform()
GFX.TranslateTransform(CENTRE_X, CENTRE_Y)
GFX.RotateTransform(angle) ' angle in DEGREES!
'For Each pos As PointF In pat.Positions
' Dim r As New Rectangle(pos.X, pos.Y, 1, 1)
' r.Inflate(3, 3)
' GFX.DrawEllipse(cyan, r)
' Next
End Using
'===========================
Dim rotatematrix As New System.Drawing.Drawing2D.Matrix()
Dim srcRect As New RectangleF(64, 64, 64, 64)
Dim OffsetX As Single = Me.Width / 2 - player1.Width / 2
Dim OffsetY As Single = Me.Height / 2 - player1.Height / 2
CENTRE_X = player1.Location.X + player1.Width / 2
CENTRE_Y = player1.Location.Y + player1.Height / 2
rad = Math.Atan2(MOUSE_Y - CENTRE_Y, MOUSE_X - CENTRE_X)
angle = rad * (180 / Math.PI)
'================================================================================
BMP = New Bitmap(My.Resources.ball)
GFX.TranslateTransform(player1.Height / 2, player1.Width / 2)
GFX.RotateTransform(angle)
GFX.DrawImage(BMP, 64, 64, player1.Location.X, player1.Location.Y)
GFX.ResetTransform()
e.Graphics.TranslateTransform(player1.Height / 2, player1.Width / 2)
e.Graphics.RotateTransform(angle)
' BMP.RotateAt(angle, New PointF(player1.Location.X, player1.Location.Y))
e.Graphics.DrawImage(BMP, New Point(-player1.Width \ 2, -player1.Height \ 2))
e.Graphics.DrawImageUnscaled(BMP, New Point(0, 0))
player1.Invalidate()
End Sub
End Class
'latest project
If this is the complete code, it doesn't seem like you're setting your timer's interval.
So you're telling it, it can tick and what to do each tick but not actually setting a time for it to tick.
Game.Interval = 60000 '1 minute
Game.Enabled = True
Game.Start() 'I don't believe you need this line
Related
I'm trying to make a Pong knockoff in VB.net. However, I am having difficulty managing to get the ball object to change directions once it gets outside of the screen. This is what I have right now:
Option Explicit On
Option Infer Off
Option Strict On
Public Class Form1
'Declare variables here
Dim P1Score As Integer = 0
Dim P2Score As Integer = 0
Dim velocity As Integer = 1
Dim RandGen As New Random
Dim angle As Integer
'This function defines the X-value movement
Private Function angleCalcX(ByVal angle As Integer) As Integer
Dim xSpeed As Integer
xSpeed = Convert.ToInt16(ball.Location.X + (velocity * System.Math.Cos(angle)))
If ball.Bounds.IntersectsWith(Player1.Bounds) OrElse ball.Bounds.IntersectsWith(Player2.Bounds) Then
xSpeed = Convert.ToInt16(-(ball.Location.X + (velocity * System.Math.Cos(angle))))
End If
Return xSpeed
End Function
Private Function angleCalcY(ByRef angle As Integer) As Integer
Dim ySpeed As Integer
ySpeed = Convert.ToInt16(ball.Location.Y + (velocity * System.Math.Sin(angle)))
If (ball.Bounds.IntersectsWith(background.Bounds)) = False Then
ySpeed = Convert.ToInt16(-(ball.Location.Y + (velocity * System.Math.Sin(angle))))
End If
Return ySpeed
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
MessageBox.Show("Hello, and welcome to Pong! This is a 2-player game. Player 1 uses the W and S keys, and Player 2 uses the K and I keys. First to five goals wins. Press space to start!", "Start Screen.jpg", MessageBoxButtons.OK, MessageBoxIcon.Information)
angle = RandGen.Next(1, 360)
End Sub
Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
ball.Location = New Point(angleCalcX(angle), angleCalcY(angle))
If ball.Location.X > 1049 Then
P1Score += 1
velocity = 1
ElseIf ball.Location.X < 12 Then
P2Score += 1
velocity = 1
End If
End Sub
Public Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.S Then
Player1.Top += 25
ElseIf e.KeyCode = Keys.W Then
Player1.Top -= 25
ElseIf e.KeyCode = Keys.K Then
Player2.Top += 25
ElseIf e.KeyCode = Keys.I Then
Player2.Top -= 25
End If
End Sub
Private Sub quitButton_Click(sender As Object, e As EventArgs) Handles quitButton.Click
Me.Close()
End Sub
End Class
Can anyone help me out?
There's missing something like this in your Timer2_Tick
ElseIf ball.Location.Y < 12 OrElse ball.Location.Y > 600 Then
ySpeed = -ySpeed 'Make a bounce from top/bottom edge
But there's a lot to improve in the rest of code as well. I don't see the reason to use Int16 for speeds or hard-coding boundaries in code for example.
How to zoom to the cursor position after the graphics component has been transformed?
I want to be able to zoom to any of the test rectangles.
The panning is done with the Middle mouse button.
MouseWheel Event handles the zooming.
Ignore the DrawGrid method, it's just to get some visual reference.
Public Class Diagram
Dim renderOrigin As New Point
Dim zoom As Single = 1.0F
Dim startPoint As New Point
Dim isDragging As Boolean = False
Dim gridSpacing As Integer = 50
Dim testRects() As Rectangle = New Rectangle() {New Rectangle(-150, -150, 70, 25), _
New Rectangle(-10, -5, 70, 25), _
New Rectangle(100, 8, 70, 25), _
New Rectangle(300, 80, 70, 25)}
Sub New()
SetStyle(ControlStyles.ResizeRedraw, True)
SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
SetStyle(ControlStyles.AllPaintingInWmPaint, True)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
End Sub
Protected Overrides Sub OnPaint(e As PaintEventArgs)
Dim g As Graphics = e.Graphics
g.TranslateTransform(renderOrigin.X, renderOrigin.Y)
g.ScaleTransform(zoom, zoom)
drawGrid(g)
g.FillRectangles(Brushes.Green, testRects.ToArray)
End Sub
Private Sub drawGrid(ByRef g As Graphics)
If zoom < 0.6 Then
Exit Sub
End If
Dim oX As Integer = renderOrigin.X
Dim oY As Integer = renderOrigin.Y
Dim maxStepX As Integer = Math.Ceiling((Width - oX) / gridSpacing) / zoom
Dim maxStepY As Integer = Math.Ceiling((Height - oY) / gridSpacing) / zoom
Dim minStepX As Integer = Math.Floor((oX * -1) / gridSpacing) / zoom
Dim minStepY As Integer = Math.Floor((oY * -1) / gridSpacing) / zoom
For x = minStepX To maxStepX
For y = minStepY To maxStepY
g.DrawLine(Pens.Black, x * gridSpacing, gridSpacing * y, (x + 1) * gridSpacing, gridSpacing * y)
g.DrawLine(Pens.Black, x * gridSpacing, gridSpacing * y, x * gridSpacing, (y + 1) * gridSpacing)
Next
Next
End Sub
Private Sub Diagram_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
If e.Button = Windows.Forms.MouseButtons.Middle Then
startPoint = New Point(e.X - renderOrigin.X, e.Y - renderOrigin.Y)
isDragging = True
End If
End Sub
Private Sub Diagram_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
If isDragging Then
renderOrigin = New Point(e.X - startPoint.X, e.Y - startPoint.Y)
Invalidate()
End If
End Sub
Private Sub Diagram_MouseUp(sender As Object, e As MouseEventArgs) Handles Me.MouseUp
isDragging = False
End Sub
Private Sub Diagram_MouseWheel(sender As Object, e As MouseEventArgs) Handles Me.MouseWheel
Dim i As Single = (e.Delta / Math.Abs(e.Delta)) / 100
zoom += i
If zoom < 0.1 Then zoom = 0.1
If zoom > 1.0 Then zoom = 1.0
renderOrigin = New Point(e.X - e.X * zoom, e.Y - e.Y * zoom)
Invalidate()
End Sub
End Class
1st. thing to know is what your mouse location is in control coordinates. It is part of the EventArguments in the scroll event. Save that location to a field.
2nd is you have to apply a TranslateTransform with the negativ saved location to move the zoom location to 0/0 then apply the ScaleTransform.
3rd move the picture back to it's original location by another TranslateTransform. now with the saved mouse location (not negated).
Thomas
I have a Picturebox that I can draw a rectangle on and I have it so that the rectangle dimensions, in percent, are logged so that if the size of the form changes, then so does the rectangle size (see code below the text)
However, when I have the Picturebox in "Zoom" mode, the rectangle does not match up when resizing (see here: First one, with corners on defined points on image http://i1262.photobucket.com/albums/ii602/bmgh85/Size1.png and then second one after resizing the form http://i1262.photobucket.com/albums/ii602/bmgh85/Size2.png
It works fine in "Stretch" mode, but that skews the images, which is no use to me (I need to keep the proportions). How can I manipulate my code to get it to work as intended?
Private x, y As Integer
Private Rct As New Rectangle(0, 0, 0, 0)
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
x = e.X
y = e.Y
End If
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If e.Button = Windows.Forms.MouseButtons.Left Then
Rct.X = Math.Min(x, e.X)
Rct.Y = Math.Min(y, e.Y)
Rct.Height = Math.Abs(e.Y - y)
Rct.Width = Math.Abs(e.X - x)
PictureBox1.Refresh()
PictureBox1.Tag = calculatePercent(Rct.X, Rct.Y, Rct.Height, Rct.Width, PictureBox1)
End If
End Sub
Private Sub PictureBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
MsgBox(PictureBox1.Tag)
Dim lst1 As List(Of Int32) = returnPercent(PictureBox1.Tag)
For i = 0 To lst1.Count - 1
MsgBox(lst1(i))
Next
End Sub
Private Sub PictureBox1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
e.Graphics.DrawRectangle(Pens.Red, Rct)
End Sub
Function calculatePercent(ByVal X As Long, Y As Long, Ht As Long, Wth As Long, pBox As PictureBox)
Dim wPercent As Long = 100 * Wth / pBox.Width
Dim hPercent As Long = 100 * Ht / pBox.Height
Dim yPercent As Long = 100 * Y / pBox.Height
Dim xPercent As Long = 100 * X / pBox.Width
Return "X:" & xPercent & ", Y:" & yPercent & ", Ht:" & hPercent & ", Wth:" & wPercent
End Function
Function returnPercent(ByVal myTag As String)
Dim lst As New List(Of Int32)
Dim getX As String = getNum(Mid(myTag, InStr(myTag, "X:"), InStr(myTag, ", Y:") - InStr(myTag, "X:")))
Dim getY As String = getNum(Mid(myTag, InStr(myTag, ", Y:"), InStr(myTag, ", Ht:") - InStr(myTag, ", Y:")))
Dim getH As String = getNum(Mid(myTag, InStr(myTag, ", Ht:"), InStr(myTag, ", Wth:") - InStr(myTag, ", Ht:")))
Dim getW As String = getNum(Mid(myTag, InStr(myTag, ", Wth:")))
lst.Add(getX)
lst.Add(getY)
lst.Add(getH)
lst.Add(getW)
Return lst
End Function
Function getNum(ByVal txt As String)
Dim rtn As String = vbNullString
Dim coln As MatchCollection = Regex.Matches(txt, "\d+")
For Each mtch As Match In coln
rtn = rtn & mtch.ToString
Next
Return Convert.ToInt32(rtn)
End Function
Private Sub PictureBox1_SizeChanged(sender As Object, e As EventArgs) Handles PictureBox1.SizeChanged
Dim lst As New List(Of Int32)
If PictureBox1.Tag <> "" Then
lst = returnPercent(PictureBox1.Tag)
Rct.X = lst(0) * PictureBox1.Width / 100
Rct.Y = lst(1) * PictureBox1.Height / 100
Rct.Height = lst(2) * PictureBox1.Height / 100
Rct.Width = lst(3) * PictureBox1.Width / 100
PictureBox1.Refresh()
End If
End Sub
I have some code that might help you:
' Rectangle to draw
Private Rct As New Rectangle(0, 0, 0, 0)
Private offsetX As Integer = 0
Private offsetY As Integer = 0
Sub Main() Handles MyBase.Load
' Some image to use
MiniPictureBox.Image = My.Resources.P6130003
MainPictureBox.Image = My.Resources.P6130003
End Sub
Private Sub MiniPictureBox_MouseDown(sender As Object, e As MouseEventArgs) Handles MiniPictureBox.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
If Not Rct.Contains(e.Location) Then
' New rectangle
Rct.Location = New Point(e.X, e.Y)
Else
' Moving a rectangle
offsetX = Rct.X - e.X
offsetY = Rct.Y - e.Y
End If
ElseIf e.Button = Windows.Forms.MouseButtons.Right Then
' Clears the screen of a rectangle
Rct = New Rectangle(0, 0, 0, 0)
MiniPictureBox.Invalidate()
End If
End Sub
Private Sub MiniPictureBox_MouseMove(sender As Object, e As MouseEventArgs) Handles MiniPictureBox.MouseMove
' Event handler to update the picture of the rectangle
If e.Button = Windows.Forms.MouseButtons.Left Then
If Rct.Contains(e.Location) Then
' Move the box
Rct.X = e.X + offsetX
Rct.Y = e.Y + offsetY
MainPictureBox.Invalidate()
Else
' Update the size of the box
Rct.Width = e.X - Rct.X
Rct.Height = e.Y - Rct.Y
End If
MiniPictureBox.Invalidate()
End If
End Sub
Private Sub MiniPictureBox_MouseUp(sender As Object, e As MouseEventArgs) Handles MiniPictureBox.MouseUp
' Event handler to call the paint event for runtime display
MiniPictureBox.Invalidate()
MainPictureBox.Invalidate()
End Sub
Private Sub MiniPictureBox_Paint(sender As Object, e As PaintEventArgs) Handles MiniPictureBox.Paint
Dim myPen As Pen = New Pen(Brushes.Red, 2)
e.Graphics.DrawRectangle(myPen, Rct)
End Sub
Private Sub MainPictureBox_Paint(sender As Object, e As PaintEventArgs) Handles MainPictureBox.Paint
If Rct.Width > 0 Then
Dim biggerRec As Rectangle = CalculateRectangle(MainPictureBox)
Dim myPen As Pen = New Pen(Brushes.Red, 2)
e.Graphics.DrawRectangle(myPen, biggerRec)
End If
End Sub
Private Function CalculateRectangle(currentPicture As PictureBox) As Rectangle
Try
Dim newWidth As Integer = (Rct.Width / MiniPictureBox.Width) * currentPicture.Image.Width
Dim newHeight As Integer = (Rct.Height / MiniPictureBox.Height) * currentPicture.Image.Height
Dim newX As Integer = (Rct.X / MiniPictureBox.Width) * currentPicture.Image.Width
Dim newY As Integer = (Rct.Y / MiniPictureBox.Height) * currentPicture.Image.Height
Return New Rectangle(newX, newY, newWidth, newHeight)
Catch ex As Exception
MessageBox.Show(ex.Message + Environment.NewLine + Environment.NewLine + ex.StackTrace)
End Try
End Function
This code will allow you to create, move, and clear a rectangle. One point of caution is in the calculations for changing the size of the rectangle, you have to ensure exception handling is properly inserted for any arithmetic exceptions.
I am collecting data from an Arduino and transmit on Visual Basic through the serial port. Now I wanted to plot a graph with time vs electrical energy (unit kWh) - time along the x-axis and electrical energy along the y-axis. Usually I am getting data of the current from Arduino.
Now I wanted to learn how to start plotting the graph. I need a simple example explaining plotting a graph for sample. I tried some example code. It seems they are not working.
How do I plot a graph time vs current read from serial? Once Visual Basic starts running, it should save data w.r.t system time and date.
Example available here
Current code
Imports System
Imports System.IO.Ports
Imports System.ComponentModel
Imports System.Threading
Imports System.Drawing
Public Class Form1
Dim myPort As Array
Dim Distance As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
myPort = IO.Ports.SerialPort.GetPortNames()
PortComboBox.Items.AddRange(myPort)
BaudComboBox.Items.Add(9600)
BaudComboBox.Items.Add(19200)
BaudComboBox.Items.Add(38400)
BaudComboBox.Items.Add(57600)
BaudComboBox.Items.Add(115200)
ConnectButton.Enabled = True
DisconnectButton.Enabled = False
End Sub
Private Sub ConnectButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConnectButton.Click
SerialPort1.PortName = PortComboBox.Text
SerialPort1.BaudRate = BaudComboBox.Text
SerialPort1.Open()
Timer1.Start()
'lblMessage.Text = PortComboBox.Text & " Connected."
ConnectButton.Enabled = False
DisconnectButton.Enabled = True
End Sub
Private Sub DisconnectButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DisconnectButton.Click
SerialPort1.Close()
DisconnectButton.Enabled = False
ConnectButton.Enabled = True
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Try
SerialPort1.Write("c")
System.Threading.Thread.Sleep(250)
Dim k As Double
Dim distance As String = SerialPort1.ReadLine()
k = CDbl(distance)
ListBoxSensor.Text = k
Catch ex As Exception
End Try
End Sub
Private Sub Relay_ON_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Relay_ON.Click
SerialPort1.Write("1")
End Sub
Private Sub Relay_Off_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Relay_Off.Click
SerialPort1.Write("0")
End Sub
End Class
Add a picturebox, a timer a button and a textbox:
PictureBox1 size = 768, 279
timer interval to 500
Private img As Bitmap
Private imgClone As Bitmap
Private widthInterval As Integer
'the distance from the left side of picturebox where x axis starts
Private leftPad As Integer = 50
'the distance from the down side of picturebox where x axis is
Private downPad As Integer = 30
'the distance from the up side of picturebox where y axis ends
Private upPad As Integer = 50
'the distance from the right side of picturebox where x axis ends
Private rightPad As Integer = 80
Private rn As New Random
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
drawBack()
Timer1.Enabled = True
End Sub
Private Sub drawBack()
Static count As Boolean = False
Dim g As Graphics
'number of values in x axis e.g 1, 2, 3, ... representing time
Dim numX As Integer = 23
'number of values in y axis representing KW/h
Dim numY As Integer = 5
Dim stringFormat As New StringFormat()
'arreys to hold the text for both axies
Dim arrayTextX(numX), arrayTextY(numY - 1) As String
Dim i As Integer
'the distance from the right side of picturebox where x axis stops
Dim rightPad As Integer = 80
Dim brush As Brush = New SolidBrush(Color.FromArgb(245, 255, 255))
Dim pen As Pen = New Pen(Color.FromArgb(212, 212, 212), 1)
Dim height, x, y As Integer
'Run once
If count = True Then
Return
End If
count = True
stringFormat.Alignment = StringAlignment.Center
img = New Bitmap(PictureBox1.Width, PictureBox1.Height)
imgClone = New Bitmap(PictureBox1.Width, PictureBox1.Height)
g = Graphics.FromImage(img)
g.SmoothingMode = SmoothingMode.AntiAlias
g.Clear(Color.White)
'the distance in x axis between each value
widthInterval = CInt((PictureBox1.Width - leftPad - rightPad) / (numX + 1))
'the distance in y axis between each value
height = CInt((PictureBox1.Height - upPad - downPad) / (numY + 1))
'fill arrays with text
For i = 0 To numX - 1
arrayTextX(i) = (i + 1).ToString
Next
For i = 0 To numY - 1
arrayTextY(i) = ((i + 1) * height).ToString
Next
'fill background of graph with color
g.FillRectangle(brush, New Rectangle(leftPad, upPad, PictureBox1.Width - leftPad - rightPad + 1, _
PictureBox1.Height - downPad - upPad))
'vertical lines
x = leftPad
For i = 0 To numX - 1
x += widthInterval
g.DrawLine(pen, x, PictureBox1.Height - downPad, x, upPad)
g.DrawString(arrayTextX(i), New Font("Arial", 8), Brushes.Black, _
New Rectangle(x - 10, PictureBox1.Height - downPad + 3, 20, 20), stringFormat)
Next
'horizontal lines
stringFormat.Alignment = StringAlignment.Far
y = PictureBox1.Height - downPad
For i = 0 To numY - 1
y -= height
g.DrawLine(pen, leftPad, y, PictureBox1.Width - rightPad, y)
g.DrawString(arrayTextY(i), New Font("Arial", 8), Brushes.Black, _
New Rectangle(0, y - 6, leftPad - 5, 20), stringFormat)
Next
g.DrawString("KW/Hour", New Font("Arial", 8, FontStyle.Bold), Brushes.Black, _
New PointF(5, 5))
g.DrawString("Time", New Font("Arial", 8, FontStyle.Bold), Brushes.Black, _
New PointF(PictureBox1.Width - 50, PictureBox1.Height - 20))
'draws x axis
g.DrawLine(Pens.Black, New Point(leftPad, PictureBox1.Height - downPad), _
New Point(PictureBox1.Width - rightPad, PictureBox1.Height - downPad))
'draws y axis
g.DrawLine(Pens.Black, New Point(leftPad, PictureBox1.Height - downPad), _
New Point(leftPad, upPad))
g.Dispose()
PictureBox1.Image = img
imgClone = CType(img.Clone, Bitmap)
End Sub
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
Dim value, x As Integer
Dim g As Graphics
Dim pntEnd As Point
Static pnt As Point = New Point(-1, -1)
Static staticX As Integer = -1
Dim hour As Integer = DateTime.Now.Hour
Dim minute As Integer = DateTime.Now.Minute
Dim second As Integer = DateTime.Now.Second
second = minute * 60 + second
x = leftPad + hour * widthInterval + CInt(CDbl(widthInterval - 1) * CDbl(second) / 3600.0R)
If pnt.X >= 0 Then
'checks if the new points x coordinate is the same as the previous and returns
If x <= staticX Then
Return
End If
End If
GetValue(value)
pntEnd = New Point(x, PictureBox1.Height - value - downPad)
g = Graphics.FromImage(img)
g.SmoothingMode = SmoothingMode.AntiAlias
If pnt.X < 0 Then
g.DrawLine(Pens.Red, pntEnd, pntEnd)
Else
g.DrawLine(Pens.Red, pnt, pntEnd)
End If
g.Dispose()
pnt = pntEnd
staticX = x
PictureBox1.Invalidate()
End Sub
Private Sub GetValue(ByRef value As Integer)
'here you can take the value from arduino.
value = rn.Next(0, PictureBox1.Height - downPad - upPad) 'random value
End Sub
When you press Button1 the graph starts.
Calculate width of graph (x axis)
width = PictureBox1.Width - leftPad - rightPad
this width is equivelant with 24h or 86400sec. So you should set the timer interval to
Timer1.Interval = CInt((86400 / width ) * 1000) 'in milliseconds
There is no need to be that because the tick function checks if the
new point is the same as the previous. So set timer interval to 1 second.
Dim HaveToDraw As New Boolean
Dim xMouse As Integer
Dim yMouse As Integer
Private Sub foo(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
If HaveToDraw = True Then
e.Graphics.FillEllipse(Brushes.Green, xMouse, yMouse, 10, 10)
End If
HaveToDraw = False
End Sub
Sub PictureBox1_MouseClick(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseClick
If RadioButton1.Checked = True Then
xMouse = e.X
yMouse = e.Y
HaveToDraw = True
PictureBox1.Refresh()
End If
End Sub
This code lets the user draw an elipse when he clicks on any point on the map, but there are 2 problems with it: 1 - The user is able to draw only one elipse; 2 - The user is not able to erase a previously created elipse.
So, how can I do that solving these two problems?
As #Idle_Mind suggested, you could use a list to store your points, and a right-click event to remove the points:
Dim radius as Integer = 5
Private points As New List(Of Point)()
Private Sub pictureBox1_MouseClick(sender As Object, e As MouseEventArgs)
If e.Button = System.Windows.Forms.MouseButtons.Left Then
points.Add(e.Location) ' add point on left click
ElseIf e.Button = System.Windows.Forms.MouseButtons.Right Then
For i As Integer = 0 To points.Count - 1 ' remove points on right-click
If distance(points(i).X, points(i).Y, e.Location) < radius Then
points.RemoveAt(i)
End If
Next
End If
pictureBox1.Refresh()
End Sub
'helper function
Private Function distance(x__1 As Integer, y__2 As Integer, mousep As Point) As Integer
Dim X__3 As Integer = CInt(Math.Pow(CDbl(x__1 - mousep.X), 2))
Dim Y__4 As Integer = CInt(Math.Pow(CDbl(y__2 - mousep.Y), 2))
Return CInt(Math.Sqrt(CDbl(X__3 + Y__4)))
End Function
Private Sub pictureBox1_Paint(sender As Object, e As PaintEventArgs)
For i As Integer = 0 To points.Count - 1
e.Graphics.FillEllipse(Brushes.Green, points(i).X - radius, points(i).Y - radius, radius * 2, radius * 2)
Next
End Sub
I also changed the paint code to draw the circles so that they are centered under the mouse-click.