Related
I'm trying to develop a program that has been made by another person.
What I develop is just for showing the measurement point like the picture below.
There are min and max data that appear in the form and it's showing from the smallest to the largest value and every time the mouse moves from left to right, the measuring point value will adjust to the graph value that has been determined as above.
The problem is data accuracy at the measuring point does not match with the value that has been determined, this is because the graphic is out of frame.
Here is the code for showing graphics;
Private Sub UpdateDiaGraph()
Call Me.ClearGraph(Me.gDia, Me.PicDiaGraph)
Call Me.InitializeGraph(Me.gDia, Me.PicDiaGraph, Me.recDia)
If Me.dsData.Tables("Dia").Rows.Count = 0 Then
Exit Sub
End If
Dim drs() As DataRow = Me.dsData.Tables("Dia").Select("", "[PathNo],[EquipmentNo],[Point]")
Dim pathNo As Integer = 0
Dim equipmentNo As Integer = 0
Dim diaCount As Integer = 0
Dim maxPoint As Integer = 0
Dim longestDiaCount As Integer = 0
Dim upper As New List(Of Decimal)
Dim lower As New List(Of Decimal)
For Each dr As DataRow In drs
If pathNo <> dr("PathNo") Or equipmentNo <> dr("EquipmentNo") Then
pathNo = dr("PathNo")
equipmentNo = dr("EquipmentNo")
'Count the graphics
diaCount += 1
' Get standard width
upper.Add(dr("Upper"))
lower.Add(dr("Lower"))
End If
' Get the max number of graph points and the number of graphs at that time
If maxPoint < dr("Point") Then
maxPoint = dr("Point")
longestDiaCount = diaCount
End If
Next
Dim x1, x2 As Decimal
Dim y1, y2 As Decimal
' Get the width to draw the reference line
Dim oneHeight As Decimal = Me.recDia.Height / (diaCount + 1)
'Initialize the graph
For i As Integer = 1 To diaCount
x1 = Me.recDia.Left + 1
x2 = Me.recDia.Left + Me.recDia.Width - 1
y1 = Me.recDia.Top + oneHeight * i
' Tolerance range
'※0.01mm/1 Point
Me.gDia.FillRectangle(New SolidBrush(Me.toleranceRecColor) _
, x1 _
, y1 - upper(diaCount - i) * 100 _
, Me.recDia.Width - 1 _
, (upper(diaCount - i) - lower(diaCount - i)) * 100)
' reference line
Me.gDia.DrawLine(New Pen(Me.centerLineColor), x1, y1, x2, y1)
Next
' Determine the drawing magnification of the X-axis so that the max number of points can be displayed
Dim xMag As Decimal = Me.recDia.Width / maxPoint
'Draw a graph
Dim counter As Integer = 0
Dim centerLineY As Decimal
Dim center As Decimal = 0
Dim p As Integer = -1
pathNo = 0 : equipmentNo = 0
For Each dr As DataRow In drs
' Get reference line and reference value
If pathNo <> dr("PathNo") Or equipmentNo <> dr("EquipmentNo") Then
pathNo = dr("PathNo")
equipmentNo = dr("EquipmentNo")
counter += 1
centerLineY = Me.recDia.Top + oneHeight * (diaCount - (counter - 1))
center = dr("Center")
'Draw chart title and reference value
Dim num As New Common.Numeric
Dim numFormat As String = num.GetNumericFormat(1, 2)
Dim s As String = dr("MeasuringTarget").ToString & ControlChars.CrLf
Dim sSize As Size = TextRenderer.MeasureText(Me.gDia, s, Me.Font)
Me.gDia.DrawString(s, Me.Font, Brushes.White, Me.recDia.Left - sSize.Width - 2, centerLineY - sSize.Height / 2)
s = ControlChars.CrLf & Format(center, numFormat)
sSize = TextRenderer.MeasureText(Me.gDia, s, Me.Font)
Me.gDia.DrawString(s, Me.Font, Brushes.White, Me.recDia.Left - sSize.Width - 2, centerLineY - sSize.Height / 2)
x1 = 0 : x2 = 0 : y1 = 0 : y2 = 0 : p = -1
End If
p += 1
'Change the drawing direction and starting point of the graph depending on the number of direction changes
If Me.extRevCnt.Item(pathNo) Mod 2 = 0 Then
x2 = Me.recDia.Left + p * xMag
Else
x2 = Me.recDia.Left + Me.recDia.Width - p * xMag
End If
y2 = centerLineY - (dr("Data") - center) * 100
If p <> 0 Then
'graph drawing
If Me.recDia.Top < y2 And y2 < Me.recDia.Top + Me.recDia.Height Then
' Change the drawing color of the graph for each outer diameter
If counter < Me.diaGraphColor.Count Then
Me.gDia.DrawLine(New Pen(Me.diaGraphColor(counter)), x1, y1, x2, y2)
Else
Me.gDia.DrawLine(New Pen(Me.graphColor), x1, y1, x2, y2)
End If
End If
' out of tolerance
If dr("DataFlag") = Common.Constant.DataFlag.NG Then
Me.gDia.DrawLine(New Pen(Me.ngColor), x1, centerLineY, x2, centerLineY)
End If
'Draw a scale every 10m * However, only when drawing the longest graph
'Drawn for the first graph (normal mandrel diameter)
If counter = 1 Then
If p Mod 100 = 0 Then
Me.gDia.DrawLine(Pens.White, x2, Me.recDia.Top + Me.recDia.Height, x2, Me.recDia.Top + Me.recDia.Height - 3)
Dim s As String = (p \ 10).ToString & "m"
Dim sSize As Size = TextRenderer.MeasureText(Me.gDia, s, Me.Font)
Me.gDia.DrawString(s, Me.Font, Brushes.White, x2 - sSize.Width / 2, Me.recDia.Top + Me.recDia.Height + 2)
End If
End If
Else
' determine the corners of a polygon
Dim points As Point() = {New Point(x2, centerLineY - 10), New Point(x2 - 10, centerLineY - 40), New Point(x2 + 10, centerLineY - 40)}
Me.gDia.FillPolygon(Brushes.Blue, points, System.Drawing.Drawing2D.FillMode.Alternate)
' Display the division number in the circle above
Dim s As String = dr("DivNo").ToString
Dim sSize As Size = TextRenderer.MeasureText(Me.gDia, s, Me.Font)
Me.gDia.DrawString(s, New Font(Me.Font, FontStyle.Regular), Brushes.White, x2 - sSize.Width / 2 + 2, centerLineY - 35)
End If
x1 = x2
y1 = y2
Next
Type.Variable.divideTargetDia = Me.DGVDataDia.SelectedRows.Item(0).Index
Call Me.DrawingGraphDia(Me.DGVDataDia.SelectedRows.Item(0).Index)
Me.PicDiaGraph.Refresh()
End Sub
Here is the code for showing data pointer
Private Sub PicDiaGraph_Paint(ByVal gDia As Graphics)
If IsNothing(tblDataDia) = True Then Exit Sub
If tblDataDia.Rows.Count = 0 Then Exit Sub
If IsNothing(tblEquipmentNoDia) = True Then Exit Sub
If tblEquipmentNoDia.Rows.Count = 0 Then Exit Sub
' Allocate the drawing range according to the number of device numbers
Dim allHeight As Integer = Me.PicDiaGraph.Size.Height
'Drawing range per device number
Dim heightPerEN As Integer = allHeight / (tblEquipmentNoDia.Rows.Count + 1)
' Device number count
Dim count As Integer = 0
' Draw a graph for each device number
For Each rEN As DataRow In tblEquipmentNoDia.Rows
Dim eNo As Integer = rEN("EquipmentNo")
Dim tblSource As DataTable = tblDataDia.Clone
For Each r As DataRow In tblDataDia.Select("EquipmentNo = '" & eNo & "'", "Point ASC")
tblSource.ImportRow(r)
Next
' Acquisition of standard value
Dim tblStandard As New DataTable
If Me.Today = False Then
Dim SQL As String = ""
SQL &= "SELECT Standard.Center "
SQL &= "FROM Standard "
SQL &= "WHERE Standard.EquipmentNo = " & eNo & " And Standard.MfgID = '" & barcodeNo.Trim & "' "
SQL &= "GROUP BY Standard.Center;"
daDia = New OleDb.OleDbDataAdapter(SQL, cnMdbDia)
daDia.Fill(tblStandard)
Else
'
End If
Dim center As Single = Format(tblStandard.Rows(0)("center"), "0.00")
' Drawing start position (height)
Dim shift As Integer = heightPerEN * count
'get width of data
Dim margin As Integer = 0
_xMaxDia = tblSource.Select("Point = MAX(Point)")(0)("Point")
_xMinDia = tblSource.Select("Point = MIN(Point)")(0)("Point")
Dim yMax As Single = tblSource.Select("Data = MAX(Data)")(0)("Data")
Dim yMin As Single = tblSource.Select("Data = MIN(Data)")(0)("Data")
'Width on X-axis data
Dim xRange As Integer = _xMaxDia - _xMinDia
'Width on Y-axis data
Dim yRange As Single = yMax - yMin
'Get size of control
Dim height As Integer = heightPerEN - (margin * 2)
Dim width As Integer = Me.PicDiaGraph.Size.Width - 21
' Nominal length per unit
_xUnitDia = width / xRange
Dim yUnit As Single = 200
'graph drawing
For i As Integer = 0 To tblSource.Rows.Count - 2
Dim x1 As Decimal = Me.recDia.Left + 1
' starting point data
Dim row1 As DataRow = tblSource.Rows(i)
Dim point1 As Integer = row1("Point")
Dim data1 As Single = row1("Data")
' end point data
Dim row2 As DataRow = tblSource.Rows(i + 1)
Dim point2 As Integer = row2("Point")
Dim data2 As Single = row2("Data")
If point2 < point1 Then MessageBox.Show("X")
Me.gDia.DrawLine(Pens.White, _
CInt((point1 - _xMinDia) * _xUnitDia), _
height - (data1 - center) * yUnit + margin + shift, _
CInt(point2 - _xMinDia) * _xUnitDia, _
height - (data2 - center) * yUnit + margin + shift)
Next
count += 1
Next
End Sub
The problem might appear in this code
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Compare(PictureBox1.Image, PictureBox2.Image)
End Sub
Public Function Compare(ByVal img1_ As Image, ByVal img2_ As Image) As Double
Dim pixelNb As Integer = img1_.Width * img1_.Height
Dim percent As Double = 100
Dim resized_img2_ As Bitmap = ResizeBitmap(CType(img2_, Bitmap), img1_.Width, img1_.Height)
For i As Integer = 0 To img1_.Width - 1
For j As Integer = 0 To img1_.Height - 1
percent -= ColorCompare((CType(img1_, Bitmap)).GetPixel(i, j), (CType(resized_img2_, Bitmap)).GetPixel(i, j)) / pixelNb
Next
Next
Return percent
End Function
Public Function ResizeBitmap(ByVal b As Bitmap, ByVal nWidth As Integer, ByVal nHeight As Integer) As Bitmap
Dim result As Bitmap = New Bitmap(nWidth, nHeight)
Using g As Graphics = Graphics.FromImage(CType(result, Image))
g.DrawImage(b, 0, 0, nWidth, nHeight)
End Using
Return result
End Function
Public Function ColorCompare(ByVal c1 As Color, ByVal c2 As Color) As Double
Return Double.Parse((Math.Abs(c1.B - c2.B) + Math.Abs(c1.R - c2.R) + Math.Abs(c1.G - c2.G)).ToString()) * 100 / (3 * 255)
End Function
Error Give in this line
Return Double.Parse((Math.Abs(c1.B - c2.B) + Math.Abs(c1.R - c2.R) +
Math.Abs(c1.G - c2.G)).ToString()) * 100 / (3 * 255)
c1.B returns a byte. A Byte has a value of 0-255 and is unsigned so it cannot hold a negative value.
Dim a As Byte = 200
Dim b As Byte = 201
Dim x = a - b
causes the same overflow error.
Changing to an integer avoids the error. A cast doesn't seem to be necessary as it is widening (no data loss).
Dim a As Byte = 200
Dim b As Byte = 201
Dim c As Integer = a
Dim d As Integer = b
Dim x = c - d
Change your color bytes to Integers and try again.
Dim g, h, i, j, k, l As Integer
g = c1.B
h = c2.B
i = c1.R
j = c1.R
k = c1.G
l = c1.G
Dim result As Double = CDbl(Math.Abs(g - h) + Math.Abs(i - j) + Math.Abs(k - l)) * 100 / (3 * 255)
Return result
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Form 2 is to enter ladder base and its off set value and for snakes where the snake head is and skakes off set value.
Not able to figure out why its not working . When the values are entered to show simulation it show's up error sandl is private and the other one is the validation one .
Public Class Form2
Dim sandl(99) As Integer
Dim snakeshead As TextBox()
Dim snakesoffset As TextBox()
Dim ladderfoot As TextBox()
Dim ladderoffset As TextBox()
Dim rnd As Random = New Random
Sub initialise()
For i = 0 To 99
sandl(i) = 0 ' reset data
Next
End Sub
Sub snake()
snakeshead = {txthead1, txthead2, txthead3, txthead4, txthead5, txthead6, txthead7, txthead8, txthead9, txthead10}
snakesoffset = {txtoffset1, txtoffset2, txtoffset3, txtoffset4, txtoffset5, txtoffset6, txtoffset7, txtoffset8, txtoffset9, txtoffset10}
' SnakeHead(i).Text = (i + 81).ToString
' SnakeOffset(i).Text = "10" '(i + 10).ToString
For i As Integer = 0 To 9
While True
Dim base = rnd.Next(90) + 11
If sandl(base - 1) <> 0 Then
Continue While
End If
Dim offset = rnd.Next(20) + 10
If base - offset < 1 Then
Continue While
End If
snakeshead(i).Text = base.ToString
snakesoffset(i).Text = offset.ToString
sandl(base - 1) = -offset
Exit While
End While
Next
End Sub
Sub ladders()
ladderfoot = {txtladder1, txtladder2, txtladder3, txtladder4, txtladder5, txtladder6, txtladder7, txtladder8, txtladder9, txtladder10}
ladderoffset = {txtladderoffset1, txtladderoffset2, txtladderoffset3, txtladderoffset4, txtladderoffset5, txtladderoffset6, txtladderoffset7, txtladderoffset8, txtladderoffset9, txtladderoffset10}
'For i As Integer = 0 To 9
' LadderFoot(i).Text = (i + 11).ToString
' LadderOffset(i).Text = "10"
For i As Integer = 0 To 99
sandl(i) = 0 'reset data
Next
For i As Integer = 0 To 9
While True
Dim base = rnd.Next(90) + 1
If sandl(base - 1) <> 0 Then
Continue While
End If
Dim offset = rnd.Next(20) + 10
If base + offset > 100 Then
Continue While
End If
ladderfoot(i).Text = base.ToString
ladderoffset(i).Text = offset.ToString
sandl(base - 1) = offset
Exit While
End While
Next
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For i As Integer = 0 To 99
sandl(i) = 0 'reset data
Next
Dim valid = Validate(ladderfoot, ladderoffset, +1, "Ladder")
If (valid) Then
valid = Validate(snakeshead, snakesoffset, -1, "Snake")
End If
If (valid) Then
'Form3 = New Form3
Form3.ShowDialog()
End If
End Sub
Private Function Validate(tbBase() As TextBox, tbOffset() As TextBox, delta As Integer, s As String) As Boolean
For i As Integer = 0 To 9
Dim base As Integer
If ((Not Integer.TryParse(tbBase(i).Text.Trim(), base)) OrElse (base < 1) OrElse (base > 100) OrElse (sandl(base - 1) <> 0)) Then
MessageBox.Show(s & (i + 1).ToString() & " base is invalid.")
tbBase(i).Select()
tbBase(i).SelectAll()
Return False
End If
base -= 1 'zero based
Dim offset As Integer
If ((Not Integer.TryParse(tbOffset(i).Text.Trim(), offset)) OrElse (offset < 10) OrElse (offset > 30) OrElse (base + offset * delta < 0) OrElse (base + offset * delta >= 100)) Then
MessageBox.Show(s & (i + 1).ToString() & " offset is invalid.")
tbOffset(i).Select()
tbOffset(i).SelectAll()
Return False
End If
sandl(base) = offset * delta 'write offset
Next
Return True
End Function
End Class
Public Class Form3
Enum EState
Dice
Move
Slide
Wait
Win
End Enum
Dim Fnt = New Font("Arial", 16)
Dim FntBig = New Font("Arial", 256)
Dim Frame As Integer = -1 'counter
Dim State = EState.Dice
Dim Rnd As Random = New Random
Dim Dice As Integer
Dim Pos As Point = New Point(32, 640 + 32)
Dim CurrentIndex As Integer = -1
Dim NextIndex As Integer
Dim TargetIndex As Integer
Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dice = 0
Frame = -1
State = EState.Dice
Pos = New Point(32, 640 + 32)
CurrentIndex = -1
End Sub
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
DrawBackground(e.Graphics)
Frame += 1
Dim oldState = State
Select Case State
Case EState.Dice
If Frame = 0 Then
Dice = Rnd.Next(6) + 1 'roll dice
TargetIndex = CurrentIndex + Dice
NextIndex = CurrentIndex
ElseIf Frame >= 63 Then
If CurrentIndex + Dice < 100 Then
State = EState.Move 'valid dice
Else
State = EState.Wait 'invalid dice
End If
Dice = 0
End If
Case EState.Move
If Frame Mod 64 = 0 Then
CurrentIndex = NextIndex
If CurrentIndex = TargetIndex Then
If CurrentIndex < 99 Then 'not win
If Form2.sandl(CurrentIndex) <> 0 Then
State = EState.Slide 'snake or ladder
Else
State = EState.Dice 'empty tile
End If
TargetIndex = CurrentIndex + Form2.sandl(CurrentIndex)
Else
State = EState.Win 'win
End If
Else
NextIndex = CurrentIndex + 1 'move
End If
Else
Dim c = GetCoordinate(CurrentIndex)
Dim n = GetCoordinate(NextIndex)
Dim dx = (n.X - c.X)
Dim dy = (n.Y - c.Y)
Pos.X = c.X * 64 + (dx * (Frame Mod 64)) + 32
Pos.Y = c.Y * 64 + (dy * (Frame Mod 64)) + 32
End If
Case EState.Slide
If Frame >= 63 Then
CurrentIndex = TargetIndex
If CurrentIndex < 99 Then
State = EState.Dice 'not win
Else
State = EState.Win 'win
End If
Else
Dim c = GetCoordinate(CurrentIndex)
Dim n = GetCoordinate(TargetIndex)
Dim dx = (n.X - c.X)
Dim dy = (n.Y - c.Y)
Pos.X = c.X * 64 + (dx * (Frame Mod 64)) + 32
Pos.Y = c.Y * 64 + (dy * (Frame Mod 64)) + 32
End If
Case EState.Wait
If Frame >= 63 Then
State = EState.Dice
End If
End Select
e.Graphics.FillEllipse(Brushes.Blue, Pos.X - 16, Pos.Y - 16, 32, 32) 'draw player
If Dice > 0 Then
Dim size = e.Graphics.MeasureString(Dice.ToString, FntBig)
e.Graphics.DrawString(Dice.ToString, FntBig, Brushes.Black, 320 - size.Width / 2, 320 - size.Height / 2) 'print dice
End If
If State <> oldState Then
Frame = -1 'reset counter
End If
If State <> EState.Win Then
PictureBox1.Invalidate() 'schedule next paint
End If
End Sub
Private Sub DrawBackground(g As Graphics)
For y As Integer = 0 To 9
For x As Integer = 0 To 9
If (((x + y) Mod 2) = 0) Then
g.FillRectangle(Brushes.LightGray, x * 64, y * 64, 64, 64) 'dark rectangle
End If
Dim z = (9 - y) * 10 + x + 1
If y Mod 2 = 0 Then
z = (9 - y) * 10 + (9 - x) + 1
End If
g.DrawString(z.ToString, Fnt, Brushes.Black, x * 64, y * 64) 'number
Next
Next
For i As Integer = 0 To 99
If Form2.sandl(i) <> 0 Then
Dim base = GetCoordinate(i)
Dim offset = GetCoordinate(i + Form2.sandl(i))
If Form2.sandl(i) > 0 Then 'ladder
Dim delta = Math.Abs(base.X - offset.X) + 4
g.DrawLine(Pens.Green, base.X * 64 + 32 - delta, base.Y * 64 + 32, offset.X * 64 + 32 - delta, offset.Y * 64 + 32) 'left part
g.DrawLine(Pens.Green, base.X * 64 + 32 + delta, base.Y * 64 + 32, offset.X * 64 + 32 + delta, offset.Y * 64 + 32) 'right part
Else 'snake
g.DrawLine(Pens.Red, base.X * 64 + 32, base.Y * 64 + 32, offset.X * 64 + 32, offset.Y * 64 + 32) 'red line
End If
End If
Next
End Sub
Private Function GetCoordinate(i As Integer) As Point
Dim result As Point
result.Y = 9 - (i \ 10)
result.X = i Mod 10
If result.Y Mod 2 = 0 Then
result.X = 9 - result.X
End If
Return result
End Function
End Class
In Form2, change your declaration from
Dim sandl(99) As Integer
to
Public sandl(99) As Integer
This would allow Form3 to access your integer array
Rename your Validate method to something else, like ValidateTextBoxes, or if you intend to overload the base.Validate, then declare as
Private Overloads Function Validate
i'm trying to display pitch, roll and yaw indications in term of graphic so i build an GUI using user control in visual basic. this is my code for the GUI only.
Private g As Graphics
Private _roll_angle As Double
Public Property roll_angle() As Double
Get
Return _roll_angle
End Get
Set(ByVal value As Double)
_roll_angle = value
Invalidate()
End Set
End Property
Private _pitch_angle As Double
Public Property pitch_angle() As Double
Get
Return _pitch_angle
End Get
Set(ByVal value As Double)
_pitch_angle = value
Invalidate()
End Set
End Property
Private Sub ArtificialHorizon_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
Private Function pitch_to_pix(ByVal pitch As Double) As Integer
Return pitch / 35.0 * Me.Height / 2
'Return pitch / 45.0 * Me.Height / 2
End Function
Private Sub ArtificialHorizon_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
g = e.Graphics
g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
g.Clear(Me.BackColor)
Dim sin As Double = Math.Sin(roll_angle / 180 * 3.14)
g.ResetTransform()
' g.FillRegion(Brushes.White, New Region(New Rectangle(0, 0, Me.Width, Me.Height)))
' rounded rectangle
Dim path As New Drawing2D.GraphicsPath()
Dim r As Single = 50
path.AddArc(0, 0, r, r, 180, 90)
path.AddArc(Me.Width - r, 0, r, r, 270, 90)
path.AddArc(Me.Width - r, Me.Height - r, r, r, 0, 90)
path.AddArc(0, Me.Height - r, r, r, 90, 90)
'path.AddEllipse(0, 0, Me.Width, Me.Height)
path.CloseFigure()
g.SetClip(path)
g.TranslateTransform(Me.Width / 2, Me.Height / 2)
g.RotateTransform(roll_angle)
g.TranslateTransform(0, pitch_to_pix(pitch_angle))
' chocolate
Dim b As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(-Me.Width, 0, Me.Height * 2, Me.Width * 2), Color.FromArgb(255, 219, 140, 21), Color.Brown, Drawing2D.LinearGradientMode.Vertical)
g.FillRectangle(b, New RectangleF(-Me.Width * 2, +1, Me.Height * 4, Me.Width * 4))
g.RotateTransform(180)
' color.aqua
b = New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(-Me.Width, -1, Me.Height * 2, Me.Width * 2), Color.FromArgb(255, 28, 134, 186), Color.DarkBlue, Drawing2D.LinearGradientMode.Vertical)
g.FillRectangle(b, New RectangleF(-Me.Width * 2, 0, Me.Height * 4, Me.Width * 4))
g.ResetTransform()
Dim w2 As Single = Me.Width / 2
Dim s As Single = Me.Width / 38
g.TranslateTransform(Me.Width / 2, Me.Height / 2)
g.RotateTransform(45)
g.TranslateTransform(-w2 + s, 0)
g.DrawLine(New Pen(Color.White, 2), 0, 0, s * 2, 0)
g.TranslateTransform(+w2 - s, 0)
g.RotateTransform(15)
g.DrawLine(New Pen(Color.White, 2), -w2 + s, 0, -w2 + s * 2, 0)
g.RotateTransform(15)
g.DrawLine(New Pen(Color.White, 2), -w2 + s, 0, -w2 + s * 2, 0)
g.RotateTransform(15)
g.DrawLine(New Pen(Color.White, 2), -w2 + s, 0, -w2 + s * 3, 0)
'g.DrawString("0°", New System.Drawing.Font("sans-serif", 9), Brushes.White, -w2 + 40, -4)
g.RotateTransform(15)
g.DrawLine(New Pen(Color.White, 2), -w2 + s, 0, -w2 + s * 2, 0)
g.RotateTransform(15)
g.DrawLine(New Pen(Color.White, 2), -w2 + s, 0, -w2 + s * 2, 0)
g.RotateTransform(15)
g.DrawLine(New Pen(Color.White, 2), -w2 + s, 0, -w2 + s * 3, 0)
'g.DrawString("+45°", New System.Drawing.Font("sans-serif", 9), Brushes.White, -w2 + 40, -4)
g.ResetTransform()
Dim length As Single = Me.Width / 4
Dim notch As Single = Me.Width / 30
g.TranslateTransform(Me.Width / 2, Me.Height / 2)
g.DrawLine(New Pen(Color.White, 3), -length + notch * 2, 0, -notch, 0)
g.DrawLine(New Pen(Color.White, 3), notch, 0, length - notch * 2, 0)
g.DrawArc(New Pen(Color.White, 3), -notch, -notch, notch * 2, notch * 2, 180, -180)
g.ResetTransform()
' driehoekje
Dim ww As Single = Me.Width / 38
g.TranslateTransform(Me.Width / 2, Me.Height / 2)
g.RotateTransform(-90 + roll_angle)
path = New Drawing2D.GraphicsPath()
path.AddLine(w2 - ww * 3, 0, w2 - ww * 4, ww)
path.AddLine(w2 - ww * 4, -ww, w2 - ww * 4, ww)
path.AddLine(w2 - ww * 4, -ww, w2 - ww * 3, 0)
g.FillRegion(Brushes.White, New Region(path))
g.DrawLine(New Pen(Color.White, 1), w2 - ww * 3, 0, w2 - ww * 4, ww)
g.DrawLine(New Pen(Color.White, 1), w2 - ww * 4, -ww, w2 - ww * 4, ww)
g.DrawLine(New Pen(Color.White, 1), w2 - ww * 4, -ww, w2 - ww * 3, 0)
g.ResetTransform()
g.ResetClip()
path = New Drawing2D.GraphicsPath()
path.AddPie(New Rectangle(ww * 3, ww * 3, Me.Width - ww * 6, Me.Height - ww * 6), 0, 360)
g.SetClip(path)
g.TranslateTransform(Me.Width / 2, Me.Height / 2)
g.RotateTransform(roll_angle)
g.TranslateTransform(0, pitch_to_pix(pitch_angle))
For i As Integer = -80 To 80 Step 10
drawpitchline(g, i)
Next i
End Sub
Private Sub drawpitchline(ByVal g As Graphics, ByVal pitch As Double)
Dim w As Single = Me.Width / 8
g.DrawLine(Pens.White, -w, pitch_to_pix(-pitch + 5), w, pitch_to_pix(-pitch + 5))
g.DrawLine(Pens.White, -w * 5 / 3, pitch_to_pix(-pitch), w * 5 / 3, pitch_to_pix(-pitch))
g.DrawString(pitch, Me.Font, Brushes.White, -w * 75 / 30, pitch_to_pix(-pitch) - 5)
g.DrawString(pitch, Me.Font, Brushes.White, w * 2, pitch_to_pix(-pitch) - 5)
End Sub
Private Sub drawrollline(ByVal g As Graphics, ByVal a As Single)
Dim w2 As Single = Me.Width / 2
g.RotateTransform(a + 90)
g.TranslateTransform(-w2 + 10, 0)
g.DrawLine(Pens.White, 0, 0, 20, 0)
g.TranslateTransform(10, 5)
g.RotateTransform(-a - 90)
g.DrawString("" & (a) & "°", New System.Drawing.Font("sans-serif", 9), Brushes.White, 0, 0)
g.RotateTransform(+90 + a)
g.TranslateTransform(-10, -5)
g.TranslateTransform(+w2 - 10, 0)
g.RotateTransform(-a - 90)
End Sub
then i added in a button to give some testing readings. code below
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
AH.roll_angle = 45
AH.pitch_angle = 10
End Sub
when the button is clicked, the GUI is supposed to turn/rotate according to the inputs. however, it stays still (btw, code is able to debug thou and the graphic did show up). i believe it's because i did not refer to the AH variable in my painting. can someone pls give me a guide on this?
thanks in advance!
I might have something which can be used, I created this to display azimuth heading of parabolic antenna.
the heading is using simple pen
superimpose on top of circle image
the pen will rotate according to the degree movement
With 3 main functions
DrawAntenna() --> draw the pen/line
FindPointOnCircle() --> find end point of the pen (start point always center of circle)
RotateAntenna() --> this will rotate the pen and updating the image accordingly
call RotateAntenna from your function (e.g. TextChanged), and pass the change angle to RotateAntenna
One key thing is to do a refresh on the image whenever the angle change, this will provide rotate effect.
I suggest making this on a different thread, as not to bogged down your main thread, because usually this data acquisition for the azm/elv/roll will happen continuously.
Down to the code:
Private Function FindPointOnCircle(ByVal originPoint As Point, ByVal radius As Double, ByVal angleDegrees As Double) As Point
Dim x As Double = radius * Math.Cos(Math.PI * angleDegrees / 180.0) + originPoint.X
Dim y As Double = radius * Math.Sin(Math.PI * angleDegrees / 180.0) + originPoint.Y
Return New Point(x, y)
End Function
Private Sub DrawAntenna(ByVal originPoint As Point, ByVal endPoint As Point, ByVal g As Graphics, Optional ByVal aPen As Pen = Nothing)
If aPen Is Nothing Then
Using BluePen = New Pen(Color.Blue)
BluePen.Width = 2
g.DrawLine(BluePen, originPoint.X, originPoint.Y, endPoint.X, endPoint.Y)
End Using
Else
g.DrawLine(aPen, originPoint.X, originPoint.Y, endPoint.X, endPoint.Y)
End If
End Sub
Private Sub RotateAntenna(ByVal ang As Double, ByVal g As Graphics, ByVal typeOfDisplay As Integer)
' Radius of 95% of half the width of the panel
Dim radius As Double = (Me.picDestTop.Width / 2) * 0.95
' Origin half of width and height of panel
Dim origin As New Point(Me.picDestTop.Width / 2, Me.picDestTop.Height / 2)
Select Case typeOfDisplay
Case displayAntenna.DisplayTop
'rotate start at 270deg, pointing up
Dim antennaDegrees As Double = ang + 170
'find point
Dim secondsPoint As Point = FindPointOnCircle(origin, radius, antennaDegrees)
Using p As New Pen(Color.Red)
p.Width = 5
DrawAntenna(origin, secondsPoint, g, p)
End Using
Case displayAntenna.DisplaySide
'display elevation
Case displayAntenna.DisplayRoll
'display pitch
End Select
g.Dispose()
End Sub
'azimuth
Private Sub lblEncCurrent_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblEncCurrent.TextChanged
Dim iint As Double
Me.picDestTop.Refresh()
iint = CDbl(lblEncCurrent.Text)
If iint >= 360 Then
iint = iint - 360
End If
RotateAntenna(iint, Me.picDestTop.CreateGraphics, displayAntenna.DisplayTop)
End Sub
Hope this help!!. Thanks.
I have been trying to get a 2D grid going. It's for a game map.
Unfortunately, the grid is not as it should be. And I cannot figure out why.
Does anyone have an idea?
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D
Public Class clsIsometric
'==================================
' SETTINGS
'==================================
Private tile_size As New Point(64, 64) 'Size of one tile in pixels
Private map_size As New Point(25, 25) 'Amount of tiles in total
Private gDevice As Device
Private bufVertex As VertexBuffer
Private bufIndex As IndexBuffer
Private gVertices() As CustomVertex.TransformedColored
Private gIndices() As Integer
'==================================
' CONSTRUCTOR
'==================================
Public Sub New(vDevice As Device)
gDevice = vDevice
End Sub
Public Sub dispose()
bufVertex.Dispose()
bufIndex.Dispose()
bufVertex = Nothing
bufIndex = Nothing
End Sub
'==================================
' RENDERING
'==================================
Public Sub buildMap()
' Recreate buffers to fit the map size
ReDim gVertices((map_size.X + 1) * (map_size.Y + 1)) ' x+1 * y+1
ReDim gIndices(map_size.X * map_size.Y * 6) ' x * y * 6
Dim k As Integer
For cX = 0 To map_size.X - 1 'Rows
For cY = 0 To map_size.Y - 1 'Columns
'VERTEX
k = cX * map_size.X + cY
gVertices(k) = New CustomVertex.TransformedColored(cX * tile_size.X, cY * tile_size.Y, 0, 1, Color.Blue.ToArgb)
Next cY
Next cX
Dim vertexPerCol As Integer = map_size.Y + 1
k = 0
For ccX = 0 To map_size.X - 1
For ccY = 0 To map_size.Y - 1
gIndices(k) = ccX * vertexPerCol + ccY ' 0
gIndices(k + 1) = (ccX + 1) * vertexPerCol + (ccY + 1) ' 1
gIndices(k + 2) = (ccX + 1) * vertexPerCol + ccY ' 2
gIndices(k + 3) = ccX * vertexPerCol + ccY ' 3
gIndices(k + 4) = ccX * vertexPerCol + (ccY + 1) ' 4
gIndices(k + 5) = (ccX + 1) * vertexPerCol + (ccY + 1) ' 5
k += 6 'Each tile has 6 indices. Increase for next tile
Next
Next
bufVertex = New VertexBuffer(GetType(CustomVertex.TransformedColored), gVertices.Length, gDevice, Usage.Dynamic Or Usage.WriteOnly, CustomVertex.TransformedColored.Format, Pool.Default)
bufIndex = New IndexBuffer(GetType(Integer), gIndices.Length, gDevice, Usage.WriteOnly, Pool.Default)
End Sub
Public Sub render()
'RENDER THE MAP
bufVertex.SetData(gVertices, 0, LockFlags.ReadOnly)
bufIndex.SetData(gIndices, 0, LockFlags.None)
gDevice.VertexFormat = CustomVertex.TransformedColored.Format
gDevice.SetStreamSource(0, bufVertex, 0)
gDevice.Indices = bufIndex
gDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, gVertices.Length, 0, CInt(gIndices.Length / 3))
End Sub
End Class
This should output a perfect square grid of 25 by 25 tiles. But the wireframe looks like:
http://i43.tinypic.com/2whf51c.jpg
Your loop which build the vertices seems to end too early, because you have n+1 vertices each row/column. It fills the array only to the forelast column, which leads to a shift in the vertices.
For cX = 0 To map_size.X 'Rows
For cY = 0 To map_size.Y 'Columns
'VERTEX
k = cX * (map_size.X + 1) + cY
gVertices(k) = New CustomVertex.TransformedColored(cX * tile_size.X, cY * tile_size.Y, 0, 1, Color.Blue.ToArgb)
Next cY
Next cX