Looking to solve an infinite loop - vb.net

I have a piece of code that generates a dungeon in Java and Python but seems to create an infinite loop in visual basic. There might be a slight problem that I'm overlooking.
Dim Touching As Boolean = True
While Touching = True
Touching = False
'Run through all the rooms and check if they overlap
For i = 0 To numRooms
Dim aPos As Point = RoomXY(i)
Dim aDime As Point = RoomWH(i)
For j = 0 To numRooms
Dim bPos As Point = RoomXY(j)
Dim bDime As Point = RoomWH(j)
If (aPos = bPos) And (aDime = bDime) Then
Continue For
Else
'Check for overlapping
Dim H_Overlaps As Boolean = (aPos.X <= bPos.X + bDime.X) And (bPos.X <= aPos.X + aDime.X)
Dim V_Overlaps As Boolean = (aPos.Y <= bPos.Y + bDime.Y) And (bPos.Y <= aPos.Y + aDime.Y)
If H_Overlaps AndAlso V_Overlaps Then
Touching = True
'Find the minimum amount of movment that stops the squares from touching
Dim dx = Math.Min(Math.Abs((aPos.X + aDime.X) - (bPos.X + 2)), Math.Abs(aPos.X - (bPos.X + bDime.X + 2)))
Dim dy = Math.Min(Math.Abs((aPos.Y + aDime.Y) - (bPos.Y + 2)), Math.Abs(aPos.Y - (bPos.Y + bDime.Y + 2)))
If dx <= dy Then
dy = 0
Else
dx = 0
End If
If aPos.X >= bPos.X Then
RoomXY(i) = New Point(RoomXY(i).X + (dx / 2), RoomXY(i).Y)
RoomXY(j) = New Point(RoomXY(j).X - (dx / 2), RoomXY(j).Y)
Else
RoomXY(i) = New Point(RoomXY(i).X - (dx / 2), RoomXY(i).Y)
RoomXY(j) = New Point(RoomXY(j).X + (dx / 2), RoomXY(j).Y)
End If
If aPos.Y >= bPos.Y Then
RoomXY(i) = New Point(RoomXY(i).X, RoomXY(i).Y + (dy / 2))
RoomXY(j) = New Point(RoomXY(j).X, RoomXY(j).Y - (dy / 2))
Else
RoomXY(i) = New Point(RoomXY(i).X, RoomXY(i).Y - (dy / 2))
RoomXY(j) = New Point(RoomXY(j).X, RoomXY(j).Y + (dy / 2))
End If
End If
End If
Next
Next
End While
This piece is of code is given room dimensions, checks if they overlap and then shifts them away from each other. I've tried everything, but I can't seem to break the infinite loop.

Related

How to solve ArgumentException : The parameter is not valid for drawing Arcs

I'm making a custom winforms button in VB.Net with rounded edges and other features. I create a path using various inputs defined by the user and draw and fill it using pens and brushes.
When I call e.Graphics.FillEllipse(Brush1, Rect1) and e.Graphics.DrawEllips(Pen1, Rect1) it just works fine without any problems, but when I try e.Graphics.FillPath(Brush1, OuterPath) and e.Graphics.DrawPath(Pen1, OuterPath) it doesn't work at all. I get this error:
ArgumentException: The parameter is not valid
I tried giving the right types of each variable used in the process and not letting the compiler decide, creating more variables to calculate and manage the inputs individually to not make all the calculations in the inputs of each function, which makes my work easier honestly, and even using the CType function in the inputs of each function to make sure that the function understands what I want as inputs. But everything failed and I don't know what to do next to fix the issue.
Here is the code:
Private Sub MetaniumButton_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
Dim PathWidth As Integer = Width - BorderSize / 2
Dim PathHeight As Integer = Height - BorderSize / 2
_Roundnes = RoundnesMemory
If PathHeight < Roundenes.Height Then
_Roundnes.Height = PathHeight - 1
End If
If PathWidth < Roundenes.Width Then
_Roundnes.Width = PathWidth - 1
End If
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
Dim OuterPath As New GraphicsPath
Dim Rec1 As Rectangle = New Rectangle(CType(BorderSize / 2, Int32), CType(BorderSize / 2, Int32), CType(_Roundnes.Width, Int32), CType(_Roundnes.Height, Int32))
Dim Rec2 As Rectangle = New Rectangle(PathWidth - _Roundnes.Width, BorderSize / 2, _Roundnes.Width, _Roundnes.Height)
Dim Rec3 As Rectangle = New Rectangle(PathWidth - _Roundnes.Width, PathHeight - _Roundnes.Height, _Roundnes.Width, _Roundnes.Height)
Dim Rec4 As Rectangle = New Rectangle(BorderSize / 2, PathHeight - _Roundnes.Height, _Roundnes.Width, _Roundnes.Height)
OuterPath.StartFigure()
OuterPath.AddLine(CInt(_Roundnes.Width / 2 + BorderSize / 2), CInt(BorderSize / 2), CInt(PathWidth - _Roundnes.Width / 2), CInt(BorderSize / 2))
OuterPath.AddArc(Rec1, 180.0, 90.0) ' Here is the problem and it could probably in any AddArc Function i used
OuterPath.AddLine(PathWidth, CInt(_Roundnes.Height / 2 + BorderSize / 2), PathWidth, CInt(PathHeight - _Roundnes.Height / 2))
OuterPath.AddArc(Rec2, -90, 90)
OuterPath.AddLine(CInt(_Roundnes.Width / 2 + BorderSize / 2), PathHeight, CInt(PathWidth - _Roundnes.Width / 2), PathHeight)
OuterPath.AddArc(Rec3, 0, 90)
OuterPath.AddLine(CInt(BorderSize / 2), CInt(_Roundnes.Height / 2), CInt(BorderSize / 2), CInt(PathHeight - _Roundnes.Height / 2))
OuterPath.AddArc(Rec4, 90, 90)
OuterPath.CloseFigure()
e.Graphics.FillPath(Brush1, OuterPath)
e.Graphics.DrawPath(Pen1, OuterPath)
Dim LabelCount As Integer = 0
For Each l As Label In Controls
LabelCount += 1
Next
Dim TextPlace As New Label With {.Name = "TextLabel",
.Text = Text,
.AutoEllipsis = True,
.Size = New Size(Width -
Margin.Left + Margin.Right + 2 * _Roundnes.Width) / 2, Height - (Margin.Top + Margin.Bottom + 2 * _Roundnes.Height) / 2),
.TextAlign = _TextAlign,
.ForeColor = _FontColor,
.BackColor = _MetaniumBackColor,
.Location = New Point((Width - .Width) / 2, (Height - .Height) / 2)}
AddHandler TextPlace.TextChanged, AddressOf MetaniumButton_TextChanged
AddHandler Me.TextChanged, AddressOf MetaniumButton_TextChanged
Controls.Add(TextPlace)
T += 1
If LabelCount <= 0 Then
0: For Each l As Label In Controls
If l.Name = "TextLabel" Then
l.Text = Text
l.AutoEllipsis = True
l.Size = New Size(Width - (Margin.Left + Margin.Right + 2 * _Roundnes.Width) / 2, Height - (Margin.Top + Margin.Bottom + 2 * _Roundnes.Height) / 2)
l.TextAlign = _TextAlign
l.ForeColor = _FontColor
l.BackColor = _MetaniumBackColor
l.Location = New Point((Width - l.Width) / 2, (Height - l.Height) / 2)
End If
Next
ElseIf LabelCount = 1 Then
For Each l As Label In Controls
If l.Name <> "TextLabel" Then
Controls.Remove(l)
Else
GoTo 1
End If
1: GoTo 0
Next
Else
End If
End Sub
When I track down the bug it seems the problem is in the AddArc() function, and I really don't know why it doesn't work. Any help appreciated.
BTW, I use VB.Net Express 2010 with .Net Framework 4.8.
PS: you can post an answer using either VB.Net or C# I can translate the code from both of them.
I solved My problem, and the answer was to initialize the value or Roundnes to (1,1) at least because my code creates the arcs of the edges using Roundnes to know how wide and long the curving edge
so the solution is to add this line of code before the code responsible for creating the arc.
If _Roundnes = New Size(0, 0) Then _Roundnes = New Size(1, 1)
And that's pretty much it! Thank you for helping me out!

Error bar not showing all the values in mschart

I am using VB.NET with mschart. I am using ErroBar chartype but i am not able to label all the values (medium, upper and lower). When i set chart.Series("ErrorBar").IsValueShownAsLabel = True, only upper value is shown.
I want to show the center, upper and lower values.
Thanks in advance
The solution adopted by me was a simpler one using annotations as can be seen in the code below
Dim Media1 As New RectangleAnnotation()
Media1.BackColor = Color.Yellow
Media1.Text = FormatNumber(D20, 4)
Dim point As PointF = New PointF(chart.ChartAreas(0).AxisX.ValueToPosition(1), chart.ChartAreas(0).AxisY.ValueToPosition(D20))
Media1.AnchorX = point.X + 10
Media1.AnchorY = point.Y + 2
Media1.AllowMoving = True
Dim L1 As New RectangleAnnotation()
L1.BackColor = Color.Yellow
L1.Text = FormatNumber(D20 - result * My.Settings("IncertezaDensidade20") / 2, 4)
point = New PointF(chart.ChartAreas(0).AxisX.ValueToPosition(1), chart.ChartAreas(0).AxisY.ValueToPosition(D20 - result * My.Settings("IncertezaDensidade20") / 2))
L1.AnchorX = point.X
L1.AnchorY = point.Y + 10
L1.AllowMoving = True
Dim L2 As New RectangleAnnotation()
L2.BackColor = Color.Yellow
L2.Text = FormatNumber(D20 + result * My.Settings("IncertezaDensidade20") / 2, 4)
point = New PointF(chart.ChartAreas(0).AxisX.ValueToPosition(1), chart.ChartAreas(0).AxisY.ValueToPosition(D20 + result * My.Settings("IncertezaDensidade20") / 2))
L2.AnchorX = point.X
L2.AnchorY = point.Y - 5
L2.AllowMoving = True
The chart now, can be seen below

Snakes and ladders Vb.net [closed]

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

Excel XY Chart (Scatter plot) Data Label No Overlap

So I've been working on this for the past week. Although it can't do miracles, I can say I've got a pretty good result:
I just wanted to put this code out there for all the poor souls like me that are looking for some kind of vba macro that helps them avoid label overlaps in a scatter plot, because while doing my research on the subject, I wasn't able to find anything helpful.
Const PIXEL_TO_POINT_RATIO As Double = 0.72 '1 Pixel = 72/96*1 Point
Const tStep As Double = 0.1
Const rStep As Double = 0.1
Dim pCount As Integer
Sub ExampleMain()
RearrangeScatterLabels Sheet5
RearrangeScatterLabels Sheet25
End Sub
Sub RearrangeScatterLabels(sht As Worksheet)
Dim plot As Chart
Dim sCollection As SeriesCollection
Dim dLabels() As DataLabel
Dim dPoints() As Point
Dim xArr(), yArr(), stDevX, stDevY As Double
Dim x0, x1, y0, y1 As Double
Dim temp() As Double
Dim theta As Double
Dim r As Double
Dim isOverlapped As Boolean
Dim safetyNet, validEntry, currentPoint As Integer
Set plot = sht.ChartObjects(1).Chart 'XY chart (scatter plot)
Set sCollection = plot.SeriesCollection 'All points and labels
safetyNet = 1
pCount = (sCollection.Count - 1)
ReDim dLabels(1 To 1)
ReDim dPoints(1 To 1)
ReDim xArr(1 To 1)
ReDim yArr(1 To 1)
For pt = 1 To sCollection(1).Points.Count
For i = 1 To pCount
If sCollection(i).Points.Count <> 0 Then
'Dynamically expand the arrays
validEntry = validEntry + 1
If validEntry <> 1 Then
ReDim Preserve dLabels(1 To UBound(dLabels) + 1)
ReDim Preserve dPoints(1 To UBound(dPoints) + 1)
ReDim Preserve xArr(1 To UBound(xArr) + 1)
ReDim Preserve yArr(1 To UBound(yArr) + 1)
End If
Set dLabels(i) = sCollection(i).Points(pt).DataLabel 'Store all label objects
Set dPoints(i) = sCollection(i).Points(pt) 'Store all point objects
temp = getElementDimensions(, dPoints(i))
xArr(i) = temp(0) 'Store all points x values
yArr(i) = temp(2) 'Store all points y values
End If
Next
Next
If UBound(dLabels) < 2 Then Exit Sub
pCount = UBound(dLabels)
stDevX = Application.WorksheetFunction.StDev(xArr) 'Get standard deviation for x
stDevY = Application.WorksheetFunction.StDev(yArr) 'Get standard deviation for y
If stDevX = 0 Then stDevX = 1
If stDevY = 0 Then stDevY = 1
r = 0
For currentPoint = 1 To pCount
theta = Rnd * 2 * Application.WorksheetFunction.Pi()
x0 = xArr(currentPoint)
y0 = yArr(currentPoint)
x1 = xArr(currentPoint)
y1 = yArr(currentPoint)
isOverlapped = True
Do Until Not isOverlapped
safetyNet = safetyNet + 1
If safetyNet < 500 Then
If Not checkForOverlap(dLabels(currentPoint), dLabels, dPoints, plot) Then
'No label is within bounds and not overlapping
isOverlapped = False
r = 0
theta = Rnd * 2 * Application.WorksheetFunction.Pi()
safetyNet = 1
Else
'Move label so it does not overlap
theta = theta + tStep
r = r + rStep * tStep / (2 * Application.WorksheetFunction.Pi())
x1 = x0 + stDevX * r * Cos(theta)
y1 = y0 + stDevY * r * Sin(theta)
dLabels(currentPoint).Left = x1
dLabels(currentPoint).Top = y1
End If
Else
safetyNet = 1
Exit Do
End If
Loop
Next
End Sub
Function checkForOverlap(ByRef dLabel As DataLabel, ByRef dLabels() As DataLabel, ByRef dPoints() As Point, ByRef dChart As Chart) As Boolean
checkForOverlap = False 'Return false by default
'Detect label going over chart area
If detectOverlap(dLabel, , , dChart) Then
checkForOverlap = True
Exit Function
End If
'Detect labels overlap
For i = 1 To pCount
If Not dLabel.Left = dLabels(i).Left Then
If detectOverlap(dLabel, dLabels(i)) Then
checkForOverlap = True
Exit Function
End If
End If
Next
'Detect label overlap with point
For i = 1 To pCount
If detectOverlap(dLabel, , dPoints(i)) Then
checkForOverlap = True
Exit Function
End If
Next
End Function
Function getElementDimensions(Optional dLabel As DataLabel, Optional dPoint As Point, Optional dChart As Chart) As Double()
'Get element dimensions and compensate slack
Dim eDimensions(3) As Double
'Working in IV quadrant
If dPoint Is Nothing And dChart Is Nothing Then
'Get label dimensions and compensate padding
eDimensions(0) = dLabel.Left + PIXEL_TO_POINT_RATIO * 3 'Left
eDimensions(1) = dLabel.Left + dLabel.Width - PIXEL_TO_POINT_RATIO * 3 'Right
eDimensions(2) = dLabel.Top + PIXEL_TO_POINT_RATIO * 6 'Top
eDimensions(3) = dLabel.Top + dLabel.Height - PIXEL_TO_POINT_RATIO * 3 'Bottom
End If
If dLabel Is Nothing And dChart Is Nothing Then
'Get point dimensions
eDimensions(0) = dPoint.Left - PIXEL_TO_POINT_RATIO * 5 'Left
eDimensions(1) = dPoint.Left + PIXEL_TO_POINT_RATIO * 5 'Right
eDimensions(2) = dPoint.Top - PIXEL_TO_POINT_RATIO * 5 'Top
eDimensions(3) = dPoint.Top + PIXEL_TO_POINT_RATIO * 5 'Bottom
End If
If dPoint Is Nothing And dLabel Is Nothing Then
'Get chart dimensions
eDimensions(0) = dChart.PlotArea.Left + PIXEL_TO_POINT_RATIO * 22 'Left
eDimensions(1) = dChart.PlotArea.Left + dChart.PlotArea.Width - PIXEL_TO_POINT_RATIO * 22 'Right
eDimensions(2) = dChart.PlotArea.Top - PIXEL_TO_POINT_RATIO * 4 'Top
eDimensions(3) = dChart.PlotArea.Top + dChart.PlotArea.Height - PIXEL_TO_POINT_RATIO * 4 'Bottom
End If
getElementDimensions = eDimensions 'Return dimensions array in Points
End Function
Function detectOverlap(ByVal dLabel1 As DataLabel, Optional ByVal dLabel2 As DataLabel, Optional ByVal dPoint As Point, Optional ByVal dChart As Chart) As Boolean
'Left, Right, Top, Bottom
Dim AxL, AxR, AyT, AyB As Double 'First label coordinates
Dim BxL, BxR, ByT, ByB As Double 'Second label coordinates
Dim eDimensions() As Double 'Element dimensions
eDimensions = getElementDimensions(dLabel1)
AxL = eDimensions(0)
AxR = eDimensions(1)
AyT = eDimensions(2)
AyB = eDimensions(3)
If dPoint Is Nothing And dChart Is Nothing Then
'Compare with another label
eDimensions = getElementDimensions(dLabel2)
End If
If dLabel2 Is Nothing And dChart Is Nothing Then
'Compare with a point
eDimensions = getElementDimensions(, dPoint)
End If
If dPoint Is Nothing And dLabel2 Is Nothing Then
'Compare with chart area
eDimensions = getElementDimensions(, , dChart)
End If
BxL = eDimensions(0)
BxR = eDimensions(1)
ByT = eDimensions(2)
ByB = eDimensions(3)
If dChart Is Nothing Then
detectOverlap = (AxL <= BxR And AxR >= BxL And AyT <= ByB And AyB >= ByT) 'Reverse De Morgan's Law
Else
detectOverlap = Not (AxL >= BxL And AxR <= BxR And AyT >= ByT And AyB <= ByB) 'Is in chart bounds (working in IV quadrant)
End If
End Function
I realize the code is kinda rough and not optimized, but I can't spend more time on this project. I've left quite a few notes around to help read it, should anyone choose to continue this project. Hope this helps.
Best wishes, Schadenfreude.
Building on your function, I made a routine to randomly reposition the labels, assigning a score according to how much overlap it would cause, and thusly optimize. The results aren't great for my own data set, but I think it can be tuned easily for most usages.
There are some issues with the borders and the axis labels which maybe I'll account for later.
Option Explicit
Sub ExampleUsage()
RearrangeScatterLabels ActiveSheet.ChartObjects(1).Chart, 3
End Sub
Sub RearrangeScatterLabels(plot As Chart, Optional timelimit As Double = 5)
Dim sCollection As SeriesCollection
Set sCollection = plot.SeriesCollection
Dim pCount As Integer
pCount = sCollection(1).Points.Count
If pCount < 2 Then Exit Sub
Dim dPoints() As Point
Dim xArr() As Double ' Label center position X
Dim yArr() As Double ' Label center position Y
Dim wArr() As Double ' Label width
Dim hArr() As Double ' Label height
Dim pArr() As Double ' Marker position X
Dim qArr() As Double ' Marker position Y
Dim mArr() As Double ' Markersize
ReDim dPoints(1 To pCount)
ReDim xArr(1 To pCount)
ReDim yArr(1 To pCount)
ReDim wArr(1 To pCount)
ReDim hArr(1 To pCount)
ReDim pArr(1 To pCount)
ReDim qArr(1 To pCount)
ReDim mArr(1 To pCount)
Dim theta As Double
Dim i As Integer
Dim j As Integer
Dim dblStart As Double
' Loop through all points to get their handles and coordinates
For i = 1 To pCount
' Store all point objects
Set dPoints(i) = sCollection(1).Points(i)
' Extract their coordinates and size
pArr(i) = dPoints(i).Left
qArr(i) = dPoints(i).Top
mArr(i) = dPoints(i).MarkerSize
' Store the size of the corresponding labels
wArr(i) = dPoints(i).DataLabel.Width
hArr(i) = dPoints(i).DataLabel.Height
' Starting position (center of label) is middle below
xArr(i) = pArr(i)
yArr(i) = qArr(i) + mArr(i)
Next
Dim newX As Double
Dim newY As Double
Dim dE As Double
Dim wgtOverlap As Double
Dim wgtDistance As Double
Dim wgtClose As Double
wgtOverlap = 10000 ' Extra penalty for overlapping
wgtDistance = 10000 ' Penalty for being nearby other labels
wgtClose = 10 ' Penalty for being further from marker
' Limit the function by time
dblStart = Timer
Do Until TimerDiff(dblStart, Timer) > timelimit
' Pick a random label to move around
i = Int(Rnd * pCount + 1)
' Pick a new random position by angle
theta = Rnd * 2 * Application.WorksheetFunction.Pi()
' Determine the position it would shift to
If Abs(Sin(theta) * wArr(i)) > Abs(hArr(i) * Cos(theta)) Then
' above or below
If Sin(theta) > 0 Then
' above
newX = pArr(i) + wArr(i) * Cos(theta) / 2
newY = qArr(i) - hArr(i) / 2 - mArr(i) / 2
Else
' below
newX = pArr(i) + wArr(i) * Cos(theta) / 2
newY = qArr(i) + hArr(i) / 2 + mArr(i) / 2
End If
Else
' left or right side
If Cos(theta) < 0 Then
' left
newX = pArr(i) - wArr(i) / 2 - mArr(i) / 2
newY = qArr(i) - hArr(i) * Sin(theta) / 2
Else
' right
newX = pArr(i) + wArr(i) / 2 + mArr(i) / 2
newY = qArr(i) - hArr(i) * Sin(theta) / 2
End If
End If
' Determine increase in energy caused by this shift
dE = 0
For j = 1 To pCount
If i <> j Then
' Current overlap with labels
If 2 * Abs(xArr(i) - xArr(j)) < wArr(i) + wArr(j) _
And 2 * Abs(yArr(i) - yArr(j)) < hArr(i) + hArr(j) Then
dE = dE - Abs(xArr(i) - xArr(j) + (wArr(i) + wArr(j)) / 2) _
* Abs(yArr(i) - yArr(j) + (hArr(i) + hArr(j)) / 2)
dE = dE - wgtOverlap
End If
' New overlap with labels
If 2 * Abs(newX - xArr(j)) < wArr(i) + wArr(j) _
And 2 * Abs(newY - yArr(j)) < hArr(i) + hArr(j) Then
dE = dE + Abs(newX - xArr(j) + (wArr(i) + wArr(j)) / 2) _
* Abs(newY - yArr(j) + (hArr(i) + hArr(j)) / 2)
dE = dE + wgtOverlap
End If
' Current overlap with labels
If Abs(xArr(i) - pArr(j)) < wArr(i) / 2 + mArr(j) _
And Abs(yArr(i) - qArr(j)) < hArr(i) / 2 + mArr(j) Then
dE = dE - wgtOverlap
End If
' New overlap with points
If Abs(newX - pArr(j)) < wArr(i) / 2 + mArr(j) _
And Abs(newY - qArr(j)) < hArr(i) / 2 + mArr(j) Then
dE = dE + wgtOverlap
End If
' We like the neighbours to be far away
dE = dE - wgtDistance / ((xArr(i) - xArr(j)) ^ 2 + (yArr(i) - yArr(j)) ^ 2)
dE = dE + wgtDistance / ((newX - xArr(j)) ^ 2 + (newY - yArr(j)) ^ 2)
End If
' We like the offsets to be low
dE = dE - wgtClose * (Abs(xArr(i) - pArr(i)) + Abs(yArr(i) - qArr(i)))
dE = dE + wgtClose * (Abs(newX - pArr(i)) + Abs(newY - qArr(i)))
Next
' If it didn't get worse, adjust to new position
If dE <= 0 Then
xArr(i) = newX
yArr(i) = newY
End If
Loop
' Actually adjust the labels
For i = 1 To pCount
dPoints(i).DataLabel.Left = xArr(i) - wArr(i) / 2
dPoints(i).DataLabel.Top = yArr(i) - hArr(i) / 2
Next
End Sub
' Timer function from Peter Albert
' http://stackoverflow.com/questions/15634623
Function TimerDiff(dblTimerStart As Double, dblTimerEnd As Double)
Dim dblTemp As Double
dblTemp = dblTimerEnd - dblTimerStart
If dblTemp < -43200 Then
dblTemp = dblTemp + 86400
End If
TimerDiff = dblTemp
End Function

How to draw very specific annular sectors using visual basic .NET 2

This question furthers a previous question. In that question valter provided me with a very good answer that used two lines of code to perform all the math. I'm hoping he would like to try his hand at this problem also. Even though it looks similar I have not been able to get any math to work.
I need to now draw exactly the same annular sectors accept that the OuterRadius in that question becomes a Rectangle. I include this image to explain what I mean. You will notice the red line that represents the Rectangle plugged into the function. The image is actually a screen capture of what the code I tried up to now produces. Naturally most them are is wrong, but the top left annular sector for instance is correct. All the annular sectors should terminate on the rectangle edge, whilst compensating for the gap. Corner cases would probably need 3 points.
I have decided to post the code I have so far, so the puritans must please close their eyes, because it is pretty brutal:
<Extension()> Friend Sub AddAnnularSector(
ByVal aGraphicsPath As GraphicsPath,
ByVal aCenterPoint As PointR,
ByVal aInnerRadius As Double,
ByVal aOuterRectangle As RectangleF,
ByVal aStartAngle As Double,
ByVal aSweepAngle As Double,
ByVal aStartGap As Double,
ByVal aEndGap As Double)
'Declare local variables...
Dim tInnerStartOffset As Double = (Math.Asin(aStartGap / aInnerRadius) * 180.0R) / Math.PI
Dim tInnerEndOffset As Double = (Math.Asin(aEndGap / aInnerRadius) * 180.0R) / Math.PI
Dim tTestAngle1 As Double = aStartAngle + aSweepAngle - tInnerEndOffset
If tTestAngle1 > 360.0R Then tTestAngle1 -= 360.0R
If tTestAngle1 > 270.0R Then tTestAngle1 = 360.0R - tTestAngle1
If tTestAngle1 > 180.0R Then tTestAngle1 -= 180.0R
If tTestAngle1 > 90.0R Then tTestAngle1 = 180.0R - tTestAngle1
Dim tOuterEndLength As Double = (Math.Min(aOuterRectangle.Width, aOuterRectangle.Height) / 2) / Math.Sin(tTestAngle1.ToRadians)
Dim tTestAngle2 As Double = aStartAngle + tInnerStartOffset
If tTestAngle2 > 360.0R Then tTestAngle2 -= 360.0R
If tTestAngle2 > 270.0R Then tTestAngle2 = 360.0R - tTestAngle2
If tTestAngle2 > 180.0R Then tTestAngle2 -= 180.0R
If tTestAngle2 > 90.0R Then tTestAngle2 = 180.0R - tTestAngle2
Dim tOuterStartLength As Double = (Math.Min(aOuterRectangle.Width, aOuterRectangle.Height) / 2) / Math.Sin(tTestAngle2.ToRadians)
'Add the annular sector to the figure...
aGraphicsPath.StartFigure()
aGraphicsPath.AddArc(CSng(aCenterPoint.X - aInnerRadius), CSng(aCenterPoint.Y - aInnerRadius), CSng(aInnerRadius * 2.0R), CSng(aInnerRadius * 2.0R), CSng(aStartAngle + tInnerStartOffset), CSng(aSweepAngle - (tInnerStartOffset + tInnerEndOffset)))
aGraphicsPath.AddLines(New PointF() {
New PointF(CSng((aCenterPoint.X) + (Math.Cos((aStartAngle + aSweepAngle - tInnerEndOffset).ToRadians) * tOuterEndLength)), CSng((aCenterPoint.Y) + (Math.Sin((aStartAngle + aSweepAngle - tInnerEndOffset).ToRadians) * tOuterEndLength))),
New PointF(CSng((aCenterPoint.X) + (Math.Cos((aStartAngle + tInnerStartOffset).ToRadians) * tOuterStartLength)), CSng((aCenterPoint.Y) + (Math.Sin((aStartAngle + tInnerStartOffset).ToRadians) * tOuterStartLength)))
})
aGraphicsPath.CloseFigure()
Return
End Sub
You will notice how OuterRadius of the previous question changed to aOuterRectangle. Also the inner arc is drawn exactly like the previous outer arc was drawn.
EDIT 1: Just chopped the code off a bit to make it more legible.
EDIT 2: Here is an image of what is actually required unlike the above image that just shows the current result.
Light Cyan - Figure that will actually be added to the GraphicsPath.
Dark Cyan - The part of the figure that is cut away by the OuterRectangle.
Green - The OuterRectangle's dimensions including its center point.
Yellow - The InnerRadius's dimensions including its center point.
Pink - Figure added in a previous call to the function with different inputs just for reference.
EDIT 3: This image shows what I thought would be a quick mathematical solution.
Thanks
drifter
For wdthRect = 250, hgtRect = 200, innerR = 65, startA = 280.0, angle = 30.0, gap = 10.0R
Private Sub DrawAnnular2(ByVal pntC As Point, ByVal wdthRect As Integer, ByVal hgtRect As Integer, ByVal innerR As Integer, ByVal startA As Single, ByVal angle As Single, ByVal gap As Double)
Dim g As Graphics
Dim pth As New GraphicsPath
Dim pthRct As New GraphicsPath
Dim pthCrclIn As New GraphicsPath
Dim pthCrclOut As New GraphicsPath
Dim fe, theta, dbl As Double
Dim outerR, wdth As Integer
Dim rect As Rectangle
wdth = Math.Min(wdthRect, hgtRect)
outerR = CInt(Math.Sqrt(2.0R * (CDbl(wdth) / 2.0R) * (CDbl(wdth) / 2.0R))) 'πυθαγόρειο θεώρημα
rect.X = CInt(CDbl(pntC.X) - CDbl(wdth) / 2.0R)
rect.Y = CInt(CDbl(pntC.Y) - CDbl(wdth) / 2.0R)
rect.Width = wdth
rect.Height = wdth
pthCrclOut.AddEllipse(pntC.X - outerR, pntC.Y - outerR, 2 * outerR, 2 * outerR)
pthCrclIn.AddEllipse(rect)
pthRct.AddRectangle(rect)
'////// The same as annular 1 //////////////////////////////////////////////////
g = Me.CreateGraphics
g.SmoothingMode = SmoothingMode.AntiAlias
gap /= 2.0R
dbl = gap / CDbl(outerR)
theta = Math.Asin(dbl) * 180.0R / Math.PI
fe = theta
pth.AddArc(pntC.X - outerR, pntC.Y - outerR, 2 * outerR, 2 * outerR, startA + CSng(fe), angle - CSng(2.0R * fe)) 'Outer
dbl = gap / CDbl(innerR)
theta = Math.Asin(dbl) * 180.0R / Math.PI
fe = theta
pth.AddArc(pntC.X - innerR, pntC.Y - innerR, 2 * innerR, 2 * innerR, startA + angle - CSng(fe), -(angle - CSng(2.0R * fe))) 'Inner
'////////////////////////////////////////////////////////////
Dim Reg1 As New Region(pth)
Dim Reg2 As New Region(pthRct)
Reg2.Intersect(Reg1)
g.FillRegion(Brushes.Aqua, Reg2) 'This is the actual annular 2.
g.DrawPath(Pens.Green, pthCrclIn)
g.DrawPath(Pens.Green, pthCrclOut)
g.DrawPath(Pens.Red, pthRct)
Reg1.Dispose()
Reg2.Dispose()
pthRct.Dispose()
pthCrclOut.Dispose()
pthCrclIn.Dispose()
pth.Dispose()
g.Dispose()
End Sub
This line of code:
Reg2.Intersect(Reg1)
is actually the intersect between the blue and the red
EDIT
Private Function DrawAnnular2(ByVal pntC As Point, ByVal wdthRect As Integer, ByVal hgtRect As Integer, ByVal innerR As Integer, ByVal startA As Single, ByVal angle As Single, ByVal gap As Double) As GraphicsPath
Dim g As Graphics
Dim pth As New GraphicsPath
Dim pthRct As New GraphicsPath
Dim pthFinal As New GraphicsPath
Dim fe, theta, dbl As Double
Dim outerR, wdth As Integer
Dim rect As Rectangle
Dim lst1 As New List(Of Integer)
Dim lst2 As New List(Of Integer)
Dim lst3 As New List(Of Integer)
Dim lst4 As New List(Of Integer)
Dim i As Integer
Dim lstBl(3) As Boolean
Dim position As Integer
lstBl(0) = False
lstBl(1) = False
lstBl(2) = False
lstBl(3) = False
wdth = Math.Min(wdthRect, hgtRect)
outerR = CInt(Math.Sqrt(2.0R * (CDbl(wdth) / 2.0R) * (CDbl(wdth) / 2.0R))) 'πυθαγόρειο θεώρημα
rect.X = CInt(CDbl(pntC.X) - CDbl(wdth) / 2.0R)
rect.Y = CInt(CDbl(pntC.Y) - CDbl(wdth) / 2.0R)
rect.Width = wdth
rect.Height = wdth
pthRct.AddRectangle(rect)
'////////////////////////////////////////////////////////
g = Me.CreateGraphics
g.SmoothingMode = SmoothingMode.AntiAlias
gap /= 2.0R
dbl = gap / CDbl(outerR)
theta = Math.Asin(dbl) * 180.0R / Math.PI
fe = theta
If CDbl(angle) - 2.0R * fe >= 360.0R Then
pthFinal.AddEllipse(pntC.X - innerR, pntC.Y - innerR, 2 * innerR, 2 * innerR)
pthFinal.AddRectangle(rect)
g.FillPath(Brushes.Aqua, pthFinal)
g.DrawPath(Pens.Red, pthRct)
pthRct.Dispose()
pth.Dispose()
g.Dispose()
Return pthFinal
End If
pth.AddArc(pntC.X - outerR, pntC.Y - outerR, 2 * outerR, 2 * outerR, startA + CSng(fe), angle - CSng(2.0R * fe)) 'Outer
dbl = gap / CDbl(innerR)
theta = Math.Asin(dbl) * 180.0R / Math.PI
fe = theta
pth.AddArc(pntC.X - innerR, pntC.Y - innerR, 2 * innerR, 2 * innerR, startA + angle - CSng(fe), -(angle - CSng(2.0R * fe))) 'Inner
'////////////////////////////////////////////////////////////
For i = rect.X To rect.X + wdth
If pth.IsVisible(i, rect.Y) Then
If lst1.Count <> 0 Then
If i <> lst1(lst1.Count - 1) + 1 Then
lstBl(0) = True
position = lst1.Count
End If
End If
lst1.Add(i)
End If
Next
For i = rect.Y To rect.Y + wdth
If pth.IsVisible(rect.X + wdth, i) Then
If lst2.Count <> 0 Then
If i <> lst2(lst2.Count - 1) + 1 Then
lstBl(1) = True
position = lst2.Count
End If
End If
lst2.Add(i)
End If
Next
For i = rect.X To rect.X + wdth
If pth.IsVisible(i, rect.Y + wdth) Then
If lst3.Count <> 0 Then
If i <> lst3(lst3.Count - 1) + 1 Then
lstBl(2) = True
position = lst3.Count
End If
End If
lst3.Add(i)
End If
Next
For i = rect.Y To rect.Y + wdth
If pth.IsVisible(rect.X, i) Then
If lst4.Count <> 0 Then
If i <> lst4(lst4.Count - 1) + 1 Then
lstBl(3) = True
position = lst4.Count
End If
End If
lst4.Add(i)
End If
Next
'If lstBl(0) = True Or lstBl(1) = True Or lstBl(2) = True Or lstBl(3) = True Then
'It is a rare case that i have to work on, when angle is too large
'MsgBox(lstBl(0).ToString + " " + lstBl(1).ToString + " " + lstBl(2).ToString + " " + lstBl(3).ToString + " ")
'Application.Exit()
'End If
'TextBox1.Text = lst1.Count.ToString + " " + lst2.Count.ToString + " " + lst3.Count.ToString + " " + " " + lst4.Count.ToString
pthFinal.AddArc(pntC.X - innerR, pntC.Y - innerR, 2 * innerR, 2 * innerR, startA + angle - CSng(fe), -(angle - CSng(2.0R * fe))) 'Inner
If CDbl(startA) + fe >= 225.0R And CDbl(startA) + fe <= 315.0R Then '1
If lst1.Count <> 0 Then
If lstBl(0) = True Then
pthFinal.AddLine(lst1(position), rect.Y, lst1(lst1.Count - 1), rect.Y)
Else
pthFinal.AddLine(lst1(0), rect.Y, lst1(lst1.Count - 1), rect.Y)
End If
End If
If lst2.Count <> 0 Then
pthFinal.AddLine(lst1(lst1.Count - 1), rect.Y, rect.X + wdth, lst2(lst2.Count - 1))
End If
If lst3.Count <> 0 Then
pthFinal.AddLine(rect.X + wdth, lst2(lst2.Count - 1), lst3(0), rect.Y + wdth)
End If
If lst4.Count <> 0 Then
pthFinal.AddLine(lst3(0), rect.Y + wdth, rect.X, lst4(0))
End If
If lstBl(0) = True Then
pthFinal.AddLine(rect.X, lst4(0), lst1(position - 1), rect.Y)
End If
ElseIf (CDbl(startA) + fe > 315.0R And CDbl(startA) + fe <= 360.0R) Or _
(CDbl(startA) + fe >= 0.0R And CDbl(startA) + fe <= 45.0R) Then '2
If lst2.Count <> 0 Then
If lstBl(1) = True Then
pthFinal.AddLine(rect.X + wdth, lst2(position), rect.X + wdth, lst2(lst2.Count - 1))
Else
pthFinal.AddLine(rect.X + wdth, lst2(0), rect.X + wdth, lst2(lst2.Count - 1))
End If
End If
If lst3.Count <> 0 Then
pthFinal.AddLine(rect.X + wdth, lst2(lst2.Count - 1), lst3(0), rect.Y + wdth)
End If
If lst4.Count <> 0 Then
pthFinal.AddLine(lst3(0), rect.Y + wdth, rect.X, lst4(0))
End If
If lst1.Count <> 0 Then
pthFinal.AddLine(rect.X, lst4(0), lst1(lst1.Count - 1), rect.Y)
End If
If lstBl(1) = True Then
pthFinal.AddLine(lst1(lst1.Count - 1), rect.Y, rect.X + wdth, lst2(position - 1))
End If
ElseIf CDbl(startA) + fe > 45.0R And CDbl(startA) + fe <= 135.0R Then '3
If lst3.Count <> 0 Then
If lstBl(2) = True Then
pthFinal.AddLine(lst3(position - 1), rect.Y + wdth, lst3(0), rect.Y + wdth)
Else
pthFinal.AddLine(lst3(lst3.Count - 1), rect.Y + wdth, lst3(0), rect.Y + wdth)
End If
End If
If lst4.Count <> 0 Then
pthFinal.AddLine(lst3(0), rect.Y + wdth, rect.X, lst3(0))
End If
If lst1.Count <> 0 Then
pthFinal.AddLine(rect.X, lst3(0), lst1(lst1.Count - 1), rect.Y)
End If
If lst2.Count <> 0 Then
pthFinal.AddLine(lst1(lst1.Count - 1), rect.Y, rect.X + wdth, lst2(lst2.Count - 1))
End If
If lstBl(2) = True Then
pthFinal.AddLine(rect.X + wdth, lst2(lst2.Count - 1), lst3(position), rect.Y + wdth)
End If
Else '4
If lst4.Count <> 0 Then
If lstBl(3) = True Then
pthFinal.AddLine(rect.X, lst4(position - 1), rect.X, lst4(0))
Else
pthFinal.AddLine(rect.X, lst4(lst4.Count - 1), rect.X, lst4(0))
End If
End If
If lst1.Count <> 0 Then
pthFinal.AddLine(rect.X, lst4(0), lst1(lst1.Count - 1), rect.Y)
End If
If lst2.Count <> 0 Then
pthFinal.AddLine(lst1(lst1.Count - 1), rect.Y, rect.X + wdth, lst2(lst2.Count - 1))
End If
If lst3.Count <> 0 Then
pthFinal.AddLine(rect.X + wdth, lst2(lst2.Count - 1), lst3(0), rect.Y + wdth)
End If
If lstBl(3) = True Then
pthFinal.AddLine(lst3(0), rect.Y + wdth, rect.X, lst4(position))
End If
End If
'g.FillPath(Brushes.Blue, pth)
g.FillPath(Brushes.Aqua, pthFinal)
g.DrawPath(Pens.Red, pthRct)
pthRct.Dispose()
pth.Dispose()
g.Dispose()
Return pthFinal
End Function
Your values: