I am trying to make a game where I bounce a ball off of the ground which is drawn as a closed curve (The green part), I just don't know how I would go about calculating the collision between the ball and curve.
I've drawn both the ball and curve using graphics in a picturebox, I imagine I have to do it mathematically as I can't find any builtin functionality in Visual basic that lets me do it.
My code:
Public Class Form1
Dim BallSpeedY, BallSpeedX As Double
Dim BallLoc As Point
Dim Start As Boolean = False
Dim gameTime As Decimal = 60.1
Dim gameTimeFont As New Font("Arial", 24, FontStyle.Bold)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.WindowState = FormWindowState.Maximized
'Size of the picturebox that is being drawn on
PictureBox1.Width = Me.Width
PictureBox1.Height = Me.Height - 24
DrawGame(False, False, True)
End Sub
Private Sub DrawGame(refreshMap As Boolean, drawBall As Boolean, drawTime As Boolean)
Dim g As Graphics = Graphics.FromImage(PictureBox1.Image)
Static startcornerpt As PointF
Static firstpt As PointF
Static pt2 As PointF
Static pt3 As PointF
Static pt4 As PointF
Static pt5 As PointF
Static lastpt As PointF
Static Endcornerpt As PointF
' Clears the window
g.Clear(Color.White)
If refreshMap Then
Randomize() ' The rnd seed would always be the same if this is not done
' Creates 5 points chosen at random positions on the window within certain parameters
startcornerpt = New PointF(0, Me.Height)
pt2 = New PointF(Me.Width * 0.2, Me.Height * ((39 * Rnd() + 30) / 100))
firstpt = New PointF(0, pt2.Y * 0.5 * 2)
pt3 = New PointF(Me.Width * 0.4, Me.Height * ((39 * Rnd() + 30) / 100))
pt4 = New PointF(Me.Width * 0.6, Me.Height * ((39 * Rnd() + 30) / 100))
pt5 = New PointF(Me.Width * 0.8, Me.Height * ((39 * Rnd() + 30) / 100))
lastpt = New PointF(Me.Width, pt5.Y * 0.5 * 2)
Endcornerpt = New PointF(Me.Width, Me.Height)
End If
' Draws the map with the 5 points
Dim curvepoints As PointF() = {startcornerpt, firstpt, pt2, pt3, pt4, pt5, lastpt, Endcornerpt}
g.FillClosedCurve(Brushes.PaleGreen, curvepoints)
If drawBall Then
' Draws the ball
g.DrawEllipse(Pens.Blue, BallLoc.X, BallLoc.Y, 20, 20)
g.FillEllipse(Brushes.Blue, BallLoc.X, BallLoc.Y, 20, 20)
' Accelerates speed
BallSpeedY = BallSpeedY - 1
' Update position
BallLoc = New Point(BallLoc.X + BallSpeedX, BallLoc.Y - BallSpeedY)
End If
If drawTime Then
gameTime = gameTime - 0.1
gameTime.ToString()
g.DrawString(gameTime, gameTimeFont, Brushes.Black, Me.Width / 2 - 120, Me.Height * 0.025) ' Draws the gametime on screen,
' Width is set to be around the middle of the screen while height is just under the strip menu.
End If
PictureBox1.Refresh()
End Sub
Private Sub StartToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles StartToolStripMenuItem.Click
If Start = False Then
gameTime = 60.1
'Resets ball for testing
BallLoc.X = 800
BallLoc.Y = 300
BallSpeedY = 0
'Starts the timers
Gravity.Start()
Movement.Start()
Start = True
ElseIf Start = True Then
' Resets the ball
Dim ballloc As New Point(800, 300)
Gravity.Stop()
Movement.Stop()
Start = False
End If
End Sub
Private Sub NewMapToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles NewMapToolStripMenuItem.Click
' Creates a new map
DrawGame(True, False, False)
Start = False
End Sub
Private Sub Movement_Tick(sender As Object, e As EventArgs) Handles Movement.Tick
' Starts movement of the ball
DrawGame(False, True, True)
End Sub
End Class
EDIT: Collision now works with these additions:
Dim wider = CType(ground.Clone(), GraphicsPath)
Using widenizer As Pen = New Pen(Color.Black, ballDiameter)
wider.Widen(widenizer)
End Using
And:
If ground.IsVisible(BallLoc) OrElse wider.IsVisible(BallLoc) Then
BallSpeedY = BallSpeedY + 50 ' rebound on collision
End If
The code below illustrates the comment I've added about using Widen() so you can test using the center of the ball.
It has been ages since I've done any VB.NET, but it does show the idea:
Imports System.Drawing.Drawing2D
Partial Public Class Form1
Inherits Form
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
Dim diameter As Integer = 10
Dim path As GraphicsPath = New GraphicsPath()
path.AddCurve(New Point() {New Point(0, 100), New Point(200, 200), New Point(400, 100)})
path.AddLines(New Point() {New Point(400, 400), New Point(0, 400)})
path.CloseAllFigures()
e.Graphics.FillPath(Brushes.Green, path)
Dim wider = CType(path.Clone(), GraphicsPath)
Using widenizer As Pen = New Pen(Color.Black, diameter)
wider.Widen(widenizer)
End Using
For x As Integer = 0 To 400 Step diameter
For y As Integer = 0 To 400 Step diameter
If path.IsVisible(x, y) OrElse wider.IsVisible(x, y) Then
e.Graphics.DrawEllipse(Pens.Red, CType(x - diameter / 2, Single), CType(y - diameter / 2, Single), diameter, diameter)
Else
e.Graphics.DrawEllipse(Pens.Blue, CType(x - diameter / 2, Single), CType(y - diameter / 2, Single), diameter, diameter)
End If
Next y
Next x
End Sub
End Class
It fills the area with circles, where the red ones are "touching" the ground:
Related
i have three different buttons in a form which have three different widths and heights of a rectangle.each time the button is clicked , the width and height is loaded and eachtime picturebox is clicked rectangle is created on a picturebox.i want the three rectangles to go side by side in X axis but wheneven i click the first rectangle and click on picturebox, three same rectangle is drawn. i want some help with the loop. here is my code.
Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
Dim myGraphics As Graphics = PictureBox1.CreateGraphics()
Dim myPen As Pen
myPen = New Pen(Drawing.Color.Black, 1)
myGraphics.DrawLine(myPen, pt1.X, pt1.Y, pt2.X, pt2.Y)
myGraphics.DrawLine(myPen, pt3.X, pt3.Y, pt4.X, pt4.Y)
End Sub
Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As MouseEventArgs) Handles PictureBox1.Click 'MessageBox.Show(e.Clicks)
Dim myGraphics As Graphics = PictureBox1.CreateGraphics
midpoint.X = (pt1.X + pt2.X) / 2
midpoint.Y = (pt3.Y + pt4.Y) / 2
Dim l(2) As Point
l(0).X = midpoint.X
l(0).Y = midpoint.Y
If e.X >= midpoint.X Then
Dim i As Integer
For i = 0 To 2
If (i > 0) Then
l(i).X += l(i - 1).X + myRect.Width
l(i).Y = midpoint.Y - myRect.Height
Dim myPen As Pen
myPen = New Pen(Drawing.Color.Black, 1)
myGraphics.DrawRectangle(myPen, l(i).X, l(i).Y, myRect.Width, myRect.Height)
Else
l(i).X = midpoint.X
l(i).Y = midpoint.Y - myRect.Height
Dim myPen As Pen
myPen = New Pen(Drawing.Color.Black, 1)
myGraphics.DrawRectangle(myPen, l(i).X, l(i).Y, myRect.Width, myRect.Height)
End If
Next
End If
Here's an example of what jmcilhinney is talking about:
Public Class Form1
' these represent the x-axis?
Private pt1 As New Point(0, 100)
Private pt2 As New Point(200, 100)
' these represent the y-axis?
Private pt3 As New Point(100, 0)
Private pt4 As New Point(100, 200)
' represents the size of the box to draw
Private myRect As New Size(30, 20)
Private numClicks As Integer
Private rects As New List(Of Rectangle)
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
' draw the x and y axis
e.Graphics.DrawLine(Pens.Black, pt1, pt2)
e.Graphics.DrawLine(Pens.Black, pt3, pt4)
' draw all the rectangles in our list
For Each rc As Rectangle In rects
e.Graphics.DrawRectangle(Pens.Blue, rc)
Next
End Sub
Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
Dim origin As New Point((pt1.X + pt2.X) / 2, (pt3.Y + pt4.Y) / 2)
Dim clickedPt As Point = PictureBox1.PointToClient(Cursor.Position)
If clickedPt.X > origin.X Then
If numClicks < 3 Then
Dim rc As New Rectangle(New Point(origin.X + (numClicks * myRect.Width), origin.Y - myRect.Height), myRect)
rects.Add(rc)
numClicks = numClicks + 1
PictureBox1.Invalidate()
End If
End If
End Sub
End Class
How do I erase a graphic as it is moving along the screen? As my code is now it draws the shape on screen multiple times and doesn't ever erase them so it ends up looking like the attached picture.
picture
I'm trying to make a game where you shoot a ball from a cannon but I'm having trouble getting the ball to move smoothly and without the ball being on screen multiple places at the same time.
All of the code used:
Public Class Form1
Dim BMP As New Bitmap(6000, 6000)
Dim ball As Graphics = Graphics.FromImage(BMP)
Dim Map As Graphics = Graphics.FromImage(BMP)
Dim BallSpeedY, BallSpeedX As Integer
Dim BallLoc As Point
Dim Start As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.WindowState = FormWindowState.Maximized
'Size of the picturebox that is being drawn on
PictureBox1.Width = Me.Width
PictureBox1.Height = Me.Height - 24
End Sub
Private Sub StartToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles StartToolStripMenuItem.Click
If Start = False Then
'Resets ball for testing
BallLoc.X = 800
BallLoc.Y = 300
BallSpeedY = 0
'Starts the timers
Gametime.Start()
Gravity.Start()
MovementY.Start()
MovementX.Start()
Start = True
ElseIf Start = True Then
Dim ballloc As New Point(800, 300)
Start = False
End If
End Sub
Private Sub NewMapToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles NewMapToolStripMenuItem.Click
Map.Clear(Color.White)
Randomize()
' Draws map
Dim firstpt As New Point(0, Me.Height * 0.7)
Dim pt2 As New Point(Me.Width * 0.2, Me.Height * (((70 - 30 + 1) * Rnd() + 30) / 100))
Dim pt3 As New Point(Me.Width * 0.4, Me.Height * (((70 - 30 + 1) * Rnd() + 30) / 100))
Dim pt4 As New Point(Me.Width * 0.6, Me.Height * (((70 - 30 + 1) * Rnd() + 30) / 100))
Dim pt5 As New Point(Me.Width * 0.8, Me.Height * (((70 - 30 + 1) * Rnd() + 30) / 100))
Dim lastpt As New Point(Me.Width, Me.Height * 0.7)
Dim curvepoints As Point() = {firstpt, pt2, pt3, pt4, pt5, lastpt}
Map.DrawCurve(Pens.Red, curvepoints)
PictureBox1.Image = BMP
End Sub
Private Sub Gametime_Tick(sender As Object, e As EventArgs) Handles Gametime.Tick
End Sub
Private Sub MovementY_Tick(sender As Object, e As EventArgs) Handles MovementY.Tick
' Draws the ball
ball.DrawEllipse(Pens.Blue, BallLoc.X, BallLoc.Y, 20, 20)
ball.FillEllipse(Brushes.Blue, BallLoc.X, BallLoc.Y, 20, 20)
' Accelerated speed
BallSpeedY = BallSpeedY - 1
' Updates position
BallLoc = New Point(BallLoc.X + BallSpeedX, BallLoc.Y - BallSpeedY)
' Redraws image
PictureBox1.Image = BMP
End Sub
End Class
You're drawing on a bitmap and setting that to your PictureBox image. Try this...
In your tick event, draw everything directly on the PictureBox Graphics object and refresh the PictureBox. The points are saved as Static variables so as the ball is moving, the same map is generated behind it and whenever you choose new map, it will generate new points and redraw the map.
Basically the concept is to calculate different object movements and then draw everything in one place making sure to draw it in layers: background, next foreground object, etc.
Private Sub NewMapToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles NewMapToolStripMenuItem.Click
DrawGame(True, True)
'Or if you just want a new map and not the ball use: DrawGame(True, False)
End Sub
Private Sub MovementY_Tick(sender As Object, e As EventArgs) Handles MovementY.Tick
DrawGame(False, True)
End Sub
Private Sub DrawGame(refreshMap As Boolean, drawBall As Boolean)
Dim g As Graphics = Graphics.FromImage(PictureBox1.Image)
Static firstpt As Point
Static pt2 As Point
Static pt3 As Point
Static pt4 As Point
Static pt5 As Point
Static lastpt As Point
g.Clear(Color.White)
If refreshMap Then
Randomize()
' Generate new points
firstpt = New Point(0, Me.Height * 0.7)
pt2 = New Point(Me.Width * 0.2, Me.Height * (((70 - 30 + 1) * Rnd() + 30) / 100))
pt3 = New Point(Me.Width * 0.4, Me.Height * (((70 - 30 + 1) * Rnd() + 30) / 100))
pt4 = New Point(Me.Width * 0.6, Me.Height * (((70 - 30 + 1) * Rnd() + 30) / 100))
pt5 = New Point(Me.Width * 0.8, Me.Height * (((70 - 30 + 1) * Rnd() + 30) / 100))
lastpt = New Point(Me.Width, Me.Height * 0.7)
End If
Dim curvepoints As Point() = {firstpt, pt2, pt3, pt4, pt5, lastpt}
g.DrawCurve(Pens.Red, curvepoints)
If drawBall Then
' Draws the ball
g.DrawEllipse(Pens.Blue, BallLoc.X, BallLoc.Y, 20, 20)
g.FillEllipse(Brushes.Blue, BallLoc.X, BallLoc.Y, 20, 20)
' Accelerated speed
BallSpeedY = BallSpeedY - 1
' Updates position
BallLoc = New Point(BallLoc.X + BallSpeedX, BallLoc.Y - BallSpeedY)
End If
PictureBox1.Refresh()
End Sub
And then you don't need this:
Dim BMP As New Bitmap(6000, 6000)
Dim ball As Graphics = Graphics.FromImage(BMP)
Dim Map As Graphics = Graphics.FromImage(BMP)
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 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.
I want to place my Crop Control on center of image of picture box. I have tried following code
Dim oCropControl As new CropControl
Dim oControlLocation As Point
oControlLocation = New Point(peImageViewer.Width / 2, peImageViewer.Height / 2)
oCropControl.Location = New Point(oControlLocation.X, oControlLocation.Y)
But this is not working well.. :( Crop Control shown in bottom.
Thanks in advance!!
Assuming they are both parented to the same control you could do it like this:
Dim rect1 As Rectangle = Me.myPictureBox.Bounds
Dim rect2 As Rectangle = Me.myCropControl.Bounds
rect2.X = CInt(rect1.X + ((rect1.Width / 2) - (rect2.Width / 2)))
rect2.Y = CInt(rect1.Y + ((rect1.Height / 2) - (rect2.Height / 2)))
Me.myCropControl.Bounds = rect2
Me.myCropControl.BringToFront()
Example
Public Class Form1
Public Sub New()
Me.InitializeComponent()
Me.Size = New Size(400, 400)
Me.StartPosition = FormStartPosition.CenterScreen
Me.myButton = New Button() With {.Location = New Point(3, 3), .Text = "ALIGN!"}
Me.myCropControl = New Label() With {.Bounds = New Rectangle(245, 263, 60, 60), .BackColor = Color.Blue, .ForeColor = Color.White, .Text = "CROP", .TextAlign = ContentAlignment.MiddleCenter}
Me.myPictureBox = New PictureBox() With {.Bounds = New Rectangle(23, 56, 246, 143), .BackColor = Color.Red}
Me.Controls.AddRange({Me.myButton, Me.myCropControl, Me.myPictureBox})
End Sub
Private Sub Align(sender As Object, e As EventArgs) Handles myButton.Click
Dim rect1 As Rectangle = Me.myPictureBox.Bounds
Dim rect2 As Rectangle = Me.myCropControl.Bounds
rect2.X = CInt(rect1.X + ((rect1.Width / 2) - (rect2.Width / 2)))
rect2.Y = CInt(rect1.Y + ((rect1.Height / 2) - (rect2.Height / 2)))
Me.myCropControl.Bounds = rect2
Me.myCropControl.BringToFront()
End Sub
Private WithEvents myButton As Button
Private myCropControl As Label
Private myPictureBox As PictureBox
End Class