My Math Seems Fine, but My Drawlines Look Weird. [Hexagon Grid]
up vote
2
down vote
favorite
I think I just need a fresh set of eyes to look at this. Or perhaps it's an issue with my numbers not being specific enough. I'm a beginner at programming and my only hunch is recursion.
Essentially, my hexagons are incorrectly positioned in some rows, but not others and I want them to all be smooth.
Public Class Form1
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
'Side Length
Dim side As Integer = 25
'Grid Width
Dim width As Integer = 10
'Grid Height
Dim height As Integer = 10
'Starting X
Dim startX As Integer = 100
'Starting Y
Dim startY As Integer = 100
'Hexagon Border
Dim borderPen As New Pen(Brushes.Gray, 1)
For i = 1 To width Step 1
For j = 1 To height Step 1
Dim apothem As Integer = (Math.Sqrt(3) * side / 2)
Dim half As Integer = (side / 2)
Dim centerX As Integer = (startX + (side * i * 1.5))
Dim centerY As Integer = (startY + (apothem * j * 2))
If i Mod 2 = 0 Then
centerY += apothem
End If
e.Graphics.DrawLine(borderPen, (centerX - half), (centerY + apothem), (centerX + half), (centerY + apothem))
e.Graphics.DrawLine(borderPen, (centerX + half), (centerY + apothem), (centerX + side), (centerY))
e.Graphics.DrawLine(borderPen, (centerX + side), (centerY), (centerX + half), (centerY - apothem))
e.Graphics.DrawLine(borderPen, (centerX + half), (centerY - apothem), (centerX - half), (centerY - apothem))
e.Graphics.DrawLine(borderPen, (centerX - half), (centerY - apothem), (centerX - side), (centerY))
e.Graphics.DrawLine(borderPen, (centerX - side), (centerY), (centerX - half), (centerY + apothem))
Next
Next
End Sub
End Class
vb.net
|
show 3 more comments
up vote
2
down vote
favorite
I think I just need a fresh set of eyes to look at this. Or perhaps it's an issue with my numbers not being specific enough. I'm a beginner at programming and my only hunch is recursion.
Essentially, my hexagons are incorrectly positioned in some rows, but not others and I want them to all be smooth.
Public Class Form1
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
'Side Length
Dim side As Integer = 25
'Grid Width
Dim width As Integer = 10
'Grid Height
Dim height As Integer = 10
'Starting X
Dim startX As Integer = 100
'Starting Y
Dim startY As Integer = 100
'Hexagon Border
Dim borderPen As New Pen(Brushes.Gray, 1)
For i = 1 To width Step 1
For j = 1 To height Step 1
Dim apothem As Integer = (Math.Sqrt(3) * side / 2)
Dim half As Integer = (side / 2)
Dim centerX As Integer = (startX + (side * i * 1.5))
Dim centerY As Integer = (startY + (apothem * j * 2))
If i Mod 2 = 0 Then
centerY += apothem
End If
e.Graphics.DrawLine(borderPen, (centerX - half), (centerY + apothem), (centerX + half), (centerY + apothem))
e.Graphics.DrawLine(borderPen, (centerX + half), (centerY + apothem), (centerX + side), (centerY))
e.Graphics.DrawLine(borderPen, (centerX + side), (centerY), (centerX + half), (centerY - apothem))
e.Graphics.DrawLine(borderPen, (centerX + half), (centerY - apothem), (centerX - half), (centerY - apothem))
e.Graphics.DrawLine(borderPen, (centerX - half), (centerY - apothem), (centerX - side), (centerY))
e.Graphics.DrawLine(borderPen, (centerX - side), (centerY), (centerX - half), (centerY + apothem))
Next
Next
End Sub
End Class
vb.net
1
So write some test code. Draw one hexagon at a time and see exactly where/when things go wrong and then you can observe the actual values in use at the time. You fix bugs by debugging and testing, not just by reading code.
– jmcilhinney
Nov 9 at 5:18
1
Also, I would be inclined to look at a single call toDrawLines
rather than multiple calls toDrawLine
. Finally, you should be disposing yourPen
, which you should do by creating it with aUsing
statement.
– jmcilhinney
Nov 9 at 5:29
In the process of doing that. The only thing that makes my hexagons smooth is when the length of the side is an even number. Odd numbers may not be as accurate I suppose. I'll continue to tinker. And I'll look into those improvements! Thanks!
– Elijah Adams
Nov 9 at 5:29
2
Before debugging, set Option Strict On. Correct the assignments (and the errors) using all floating points values (single). Also, note that there's ae.Graphics.DrawLines()
method (plural) but alsoe.Graphics.DrawPolygon()
. All of those accept floating point positions. You could also exploreGraphicsPath.AddPolygon()
. Since you're using a Pen on size 1, you could use a StockObject (Pens.Gray
) which doesn't need disposing of. Or a pre-defined custom Pen that you Dispose() of at the end (when closing the Form/App)
– Jimi
Nov 9 at 6:01
2
PutOption Strict On
at the very top beforePublic Class Form1
. VS will then highlight your problem. Replace the highlightedInteger
s withSingle
and it will look smooth.
– GSerg
Nov 9 at 9:28
|
show 3 more comments
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I think I just need a fresh set of eyes to look at this. Or perhaps it's an issue with my numbers not being specific enough. I'm a beginner at programming and my only hunch is recursion.
Essentially, my hexagons are incorrectly positioned in some rows, but not others and I want them to all be smooth.
Public Class Form1
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
'Side Length
Dim side As Integer = 25
'Grid Width
Dim width As Integer = 10
'Grid Height
Dim height As Integer = 10
'Starting X
Dim startX As Integer = 100
'Starting Y
Dim startY As Integer = 100
'Hexagon Border
Dim borderPen As New Pen(Brushes.Gray, 1)
For i = 1 To width Step 1
For j = 1 To height Step 1
Dim apothem As Integer = (Math.Sqrt(3) * side / 2)
Dim half As Integer = (side / 2)
Dim centerX As Integer = (startX + (side * i * 1.5))
Dim centerY As Integer = (startY + (apothem * j * 2))
If i Mod 2 = 0 Then
centerY += apothem
End If
e.Graphics.DrawLine(borderPen, (centerX - half), (centerY + apothem), (centerX + half), (centerY + apothem))
e.Graphics.DrawLine(borderPen, (centerX + half), (centerY + apothem), (centerX + side), (centerY))
e.Graphics.DrawLine(borderPen, (centerX + side), (centerY), (centerX + half), (centerY - apothem))
e.Graphics.DrawLine(borderPen, (centerX + half), (centerY - apothem), (centerX - half), (centerY - apothem))
e.Graphics.DrawLine(borderPen, (centerX - half), (centerY - apothem), (centerX - side), (centerY))
e.Graphics.DrawLine(borderPen, (centerX - side), (centerY), (centerX - half), (centerY + apothem))
Next
Next
End Sub
End Class
vb.net
I think I just need a fresh set of eyes to look at this. Or perhaps it's an issue with my numbers not being specific enough. I'm a beginner at programming and my only hunch is recursion.
Essentially, my hexagons are incorrectly positioned in some rows, but not others and I want them to all be smooth.
Public Class Form1
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
'Side Length
Dim side As Integer = 25
'Grid Width
Dim width As Integer = 10
'Grid Height
Dim height As Integer = 10
'Starting X
Dim startX As Integer = 100
'Starting Y
Dim startY As Integer = 100
'Hexagon Border
Dim borderPen As New Pen(Brushes.Gray, 1)
For i = 1 To width Step 1
For j = 1 To height Step 1
Dim apothem As Integer = (Math.Sqrt(3) * side / 2)
Dim half As Integer = (side / 2)
Dim centerX As Integer = (startX + (side * i * 1.5))
Dim centerY As Integer = (startY + (apothem * j * 2))
If i Mod 2 = 0 Then
centerY += apothem
End If
e.Graphics.DrawLine(borderPen, (centerX - half), (centerY + apothem), (centerX + half), (centerY + apothem))
e.Graphics.DrawLine(borderPen, (centerX + half), (centerY + apothem), (centerX + side), (centerY))
e.Graphics.DrawLine(borderPen, (centerX + side), (centerY), (centerX + half), (centerY - apothem))
e.Graphics.DrawLine(borderPen, (centerX + half), (centerY - apothem), (centerX - half), (centerY - apothem))
e.Graphics.DrawLine(borderPen, (centerX - half), (centerY - apothem), (centerX - side), (centerY))
e.Graphics.DrawLine(borderPen, (centerX - side), (centerY), (centerX - half), (centerY + apothem))
Next
Next
End Sub
End Class
vb.net
vb.net
edited Nov 9 at 9:21
Andrew Morton
15k53049
15k53049
asked Nov 9 at 4:51
Elijah Adams
317
317
1
So write some test code. Draw one hexagon at a time and see exactly where/when things go wrong and then you can observe the actual values in use at the time. You fix bugs by debugging and testing, not just by reading code.
– jmcilhinney
Nov 9 at 5:18
1
Also, I would be inclined to look at a single call toDrawLines
rather than multiple calls toDrawLine
. Finally, you should be disposing yourPen
, which you should do by creating it with aUsing
statement.
– jmcilhinney
Nov 9 at 5:29
In the process of doing that. The only thing that makes my hexagons smooth is when the length of the side is an even number. Odd numbers may not be as accurate I suppose. I'll continue to tinker. And I'll look into those improvements! Thanks!
– Elijah Adams
Nov 9 at 5:29
2
Before debugging, set Option Strict On. Correct the assignments (and the errors) using all floating points values (single). Also, note that there's ae.Graphics.DrawLines()
method (plural) but alsoe.Graphics.DrawPolygon()
. All of those accept floating point positions. You could also exploreGraphicsPath.AddPolygon()
. Since you're using a Pen on size 1, you could use a StockObject (Pens.Gray
) which doesn't need disposing of. Or a pre-defined custom Pen that you Dispose() of at the end (when closing the Form/App)
– Jimi
Nov 9 at 6:01
2
PutOption Strict On
at the very top beforePublic Class Form1
. VS will then highlight your problem. Replace the highlightedInteger
s withSingle
and it will look smooth.
– GSerg
Nov 9 at 9:28
|
show 3 more comments
1
So write some test code. Draw one hexagon at a time and see exactly where/when things go wrong and then you can observe the actual values in use at the time. You fix bugs by debugging and testing, not just by reading code.
– jmcilhinney
Nov 9 at 5:18
1
Also, I would be inclined to look at a single call toDrawLines
rather than multiple calls toDrawLine
. Finally, you should be disposing yourPen
, which you should do by creating it with aUsing
statement.
– jmcilhinney
Nov 9 at 5:29
In the process of doing that. The only thing that makes my hexagons smooth is when the length of the side is an even number. Odd numbers may not be as accurate I suppose. I'll continue to tinker. And I'll look into those improvements! Thanks!
– Elijah Adams
Nov 9 at 5:29
2
Before debugging, set Option Strict On. Correct the assignments (and the errors) using all floating points values (single). Also, note that there's ae.Graphics.DrawLines()
method (plural) but alsoe.Graphics.DrawPolygon()
. All of those accept floating point positions. You could also exploreGraphicsPath.AddPolygon()
. Since you're using a Pen on size 1, you could use a StockObject (Pens.Gray
) which doesn't need disposing of. Or a pre-defined custom Pen that you Dispose() of at the end (when closing the Form/App)
– Jimi
Nov 9 at 6:01
2
PutOption Strict On
at the very top beforePublic Class Form1
. VS will then highlight your problem. Replace the highlightedInteger
s withSingle
and it will look smooth.
– GSerg
Nov 9 at 9:28
1
1
So write some test code. Draw one hexagon at a time and see exactly where/when things go wrong and then you can observe the actual values in use at the time. You fix bugs by debugging and testing, not just by reading code.
– jmcilhinney
Nov 9 at 5:18
So write some test code. Draw one hexagon at a time and see exactly where/when things go wrong and then you can observe the actual values in use at the time. You fix bugs by debugging and testing, not just by reading code.
– jmcilhinney
Nov 9 at 5:18
1
1
Also, I would be inclined to look at a single call to
DrawLines
rather than multiple calls to DrawLine
. Finally, you should be disposing your Pen
, which you should do by creating it with a Using
statement.– jmcilhinney
Nov 9 at 5:29
Also, I would be inclined to look at a single call to
DrawLines
rather than multiple calls to DrawLine
. Finally, you should be disposing your Pen
, which you should do by creating it with a Using
statement.– jmcilhinney
Nov 9 at 5:29
In the process of doing that. The only thing that makes my hexagons smooth is when the length of the side is an even number. Odd numbers may not be as accurate I suppose. I'll continue to tinker. And I'll look into those improvements! Thanks!
– Elijah Adams
Nov 9 at 5:29
In the process of doing that. The only thing that makes my hexagons smooth is when the length of the side is an even number. Odd numbers may not be as accurate I suppose. I'll continue to tinker. And I'll look into those improvements! Thanks!
– Elijah Adams
Nov 9 at 5:29
2
2
Before debugging, set Option Strict On. Correct the assignments (and the errors) using all floating points values (single). Also, note that there's a
e.Graphics.DrawLines()
method (plural) but also e.Graphics.DrawPolygon()
. All of those accept floating point positions. You could also explore GraphicsPath.AddPolygon()
. Since you're using a Pen on size 1, you could use a StockObject (Pens.Gray
) which doesn't need disposing of. Or a pre-defined custom Pen that you Dispose() of at the end (when closing the Form/App)– Jimi
Nov 9 at 6:01
Before debugging, set Option Strict On. Correct the assignments (and the errors) using all floating points values (single). Also, note that there's a
e.Graphics.DrawLines()
method (plural) but also e.Graphics.DrawPolygon()
. All of those accept floating point positions. You could also explore GraphicsPath.AddPolygon()
. Since you're using a Pen on size 1, you could use a StockObject (Pens.Gray
) which doesn't need disposing of. Or a pre-defined custom Pen that you Dispose() of at the end (when closing the Form/App)– Jimi
Nov 9 at 6:01
2
2
Put
Option Strict On
at the very top before Public Class Form1
. VS will then highlight your problem. Replace the highlighted Integer
s with Single
and it will look smooth.– GSerg
Nov 9 at 9:28
Put
Option Strict On
at the very top before Public Class Form1
. VS will then highlight your problem. Replace the highlighted Integer
s with Single
and it will look smooth.– GSerg
Nov 9 at 9:28
|
show 3 more comments
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
I've tinkered with the suggestions you guys commented and fixed the bug I was having. I wasn't using correct data types. Also, I utilized e.Graphics.Drawlines and the StockObject tip for pens and disposing of them. Thanks, again!
https://imgur.com/B37MDwB
If there's any other improvements I can make to my code feel free to comment them.
Option Strict On
Imports System.Drawing.Drawing2D
Public Class Form1
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles
Me.Paint
'Side Length
Dim side As Single = 30
'Grid Width
Dim width As Single = 10
'Grid Height
Dim height As Single = 5
'Starting X
Dim startX As Single = 0
'Starting Y
Dim startY As Single = 0
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
e.Graphics.PixelOffsetMode = PixelOffsetMode.Half
Dim apothem As Single = CSng(Math.Sqrt(3) * side / 2.0F)
Dim half As Single = (side / 2)
For i = 1 To width Step 1
For j = 1 To height Step 1
Dim centerX As Single = (startX + (side * i * 1.5F))
Dim centerY As Single = (startY + (apothem * j * 2))
If i Mod 2 = 0 Then
centerY += apothem
End If
Dim points As New List(Of PointF)
points.Add(New PointF((centerX - half), (centerY + apothem)))
points.Add(New PointF((centerX + half), (centerY + apothem)))
points.Add(New PointF((centerX + side), (centerY)))
points.Add(New PointF((centerX + half), (centerY - apothem)))
points.Add(New PointF((centerX - half), (centerY - apothem)))
points.Add(New PointF((centerX - side), (centerY)))
points.Add(New PointF((centerX - half), (centerY + apothem)))
e.Graphics.DrawLines(Pens.Gray, points.ToArray())
Next
Next
End Sub
End Class
1
Adde.Graphics.SmoothingMode = SmoothingMode.AntiAlias
ande.Graphics.PixelOffsetMode = PixelOffsetMode.Half
before the loop. See the difference. + You should use single, not double. In your loop you have constant casts from double to single inpoints.Add()
+Dim apothem
andDim half
should be moved outside the loop. You have to calculate those just once.
– Jimi
Nov 10 at 0:45
1
Cast to single when needed (e.g.,CSng((Math.Sqrt(3) / 2.0F) * side)
). Use single values for all the other varialbles: side, width etc. Btw,width
andheight
are bad names (same as Controls properties)). Use something likeGridWidth
,GridHeight
etc.
– Jimi
Nov 10 at 0:53
I did the 2dGraphics suggestions and I liked them, but you've lost me on the casting integers part.
– Elijah Adams
Nov 10 at 1:01
1
Simple. All of you local variables should be declared asSingle
. When you do, you'll have consistent behaviour on all the calculations. You need to use aList(Of PointF)
and then add aNew PointF()
and not cast again toInteger
. That's bad. Use thePointF
structure, it accepts aSingle
data type. => Do not useIntegers
in this procedure anywhere.
– Jimi
Nov 10 at 1:06
1
I edited my code in my answer to fit your suggestions. Constant casts fixed and improved graphics. Thanks!
– Elijah Adams
Nov 10 at 1:15
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
I've tinkered with the suggestions you guys commented and fixed the bug I was having. I wasn't using correct data types. Also, I utilized e.Graphics.Drawlines and the StockObject tip for pens and disposing of them. Thanks, again!
https://imgur.com/B37MDwB
If there's any other improvements I can make to my code feel free to comment them.
Option Strict On
Imports System.Drawing.Drawing2D
Public Class Form1
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles
Me.Paint
'Side Length
Dim side As Single = 30
'Grid Width
Dim width As Single = 10
'Grid Height
Dim height As Single = 5
'Starting X
Dim startX As Single = 0
'Starting Y
Dim startY As Single = 0
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
e.Graphics.PixelOffsetMode = PixelOffsetMode.Half
Dim apothem As Single = CSng(Math.Sqrt(3) * side / 2.0F)
Dim half As Single = (side / 2)
For i = 1 To width Step 1
For j = 1 To height Step 1
Dim centerX As Single = (startX + (side * i * 1.5F))
Dim centerY As Single = (startY + (apothem * j * 2))
If i Mod 2 = 0 Then
centerY += apothem
End If
Dim points As New List(Of PointF)
points.Add(New PointF((centerX - half), (centerY + apothem)))
points.Add(New PointF((centerX + half), (centerY + apothem)))
points.Add(New PointF((centerX + side), (centerY)))
points.Add(New PointF((centerX + half), (centerY - apothem)))
points.Add(New PointF((centerX - half), (centerY - apothem)))
points.Add(New PointF((centerX - side), (centerY)))
points.Add(New PointF((centerX - half), (centerY + apothem)))
e.Graphics.DrawLines(Pens.Gray, points.ToArray())
Next
Next
End Sub
End Class
1
Adde.Graphics.SmoothingMode = SmoothingMode.AntiAlias
ande.Graphics.PixelOffsetMode = PixelOffsetMode.Half
before the loop. See the difference. + You should use single, not double. In your loop you have constant casts from double to single inpoints.Add()
+Dim apothem
andDim half
should be moved outside the loop. You have to calculate those just once.
– Jimi
Nov 10 at 0:45
1
Cast to single when needed (e.g.,CSng((Math.Sqrt(3) / 2.0F) * side)
). Use single values for all the other varialbles: side, width etc. Btw,width
andheight
are bad names (same as Controls properties)). Use something likeGridWidth
,GridHeight
etc.
– Jimi
Nov 10 at 0:53
I did the 2dGraphics suggestions and I liked them, but you've lost me on the casting integers part.
– Elijah Adams
Nov 10 at 1:01
1
Simple. All of you local variables should be declared asSingle
. When you do, you'll have consistent behaviour on all the calculations. You need to use aList(Of PointF)
and then add aNew PointF()
and not cast again toInteger
. That's bad. Use thePointF
structure, it accepts aSingle
data type. => Do not useIntegers
in this procedure anywhere.
– Jimi
Nov 10 at 1:06
1
I edited my code in my answer to fit your suggestions. Constant casts fixed and improved graphics. Thanks!
– Elijah Adams
Nov 10 at 1:15
add a comment |
up vote
1
down vote
accepted
I've tinkered with the suggestions you guys commented and fixed the bug I was having. I wasn't using correct data types. Also, I utilized e.Graphics.Drawlines and the StockObject tip for pens and disposing of them. Thanks, again!
https://imgur.com/B37MDwB
If there's any other improvements I can make to my code feel free to comment them.
Option Strict On
Imports System.Drawing.Drawing2D
Public Class Form1
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles
Me.Paint
'Side Length
Dim side As Single = 30
'Grid Width
Dim width As Single = 10
'Grid Height
Dim height As Single = 5
'Starting X
Dim startX As Single = 0
'Starting Y
Dim startY As Single = 0
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
e.Graphics.PixelOffsetMode = PixelOffsetMode.Half
Dim apothem As Single = CSng(Math.Sqrt(3) * side / 2.0F)
Dim half As Single = (side / 2)
For i = 1 To width Step 1
For j = 1 To height Step 1
Dim centerX As Single = (startX + (side * i * 1.5F))
Dim centerY As Single = (startY + (apothem * j * 2))
If i Mod 2 = 0 Then
centerY += apothem
End If
Dim points As New List(Of PointF)
points.Add(New PointF((centerX - half), (centerY + apothem)))
points.Add(New PointF((centerX + half), (centerY + apothem)))
points.Add(New PointF((centerX + side), (centerY)))
points.Add(New PointF((centerX + half), (centerY - apothem)))
points.Add(New PointF((centerX - half), (centerY - apothem)))
points.Add(New PointF((centerX - side), (centerY)))
points.Add(New PointF((centerX - half), (centerY + apothem)))
e.Graphics.DrawLines(Pens.Gray, points.ToArray())
Next
Next
End Sub
End Class
1
Adde.Graphics.SmoothingMode = SmoothingMode.AntiAlias
ande.Graphics.PixelOffsetMode = PixelOffsetMode.Half
before the loop. See the difference. + You should use single, not double. In your loop you have constant casts from double to single inpoints.Add()
+Dim apothem
andDim half
should be moved outside the loop. You have to calculate those just once.
– Jimi
Nov 10 at 0:45
1
Cast to single when needed (e.g.,CSng((Math.Sqrt(3) / 2.0F) * side)
). Use single values for all the other varialbles: side, width etc. Btw,width
andheight
are bad names (same as Controls properties)). Use something likeGridWidth
,GridHeight
etc.
– Jimi
Nov 10 at 0:53
I did the 2dGraphics suggestions and I liked them, but you've lost me on the casting integers part.
– Elijah Adams
Nov 10 at 1:01
1
Simple. All of you local variables should be declared asSingle
. When you do, you'll have consistent behaviour on all the calculations. You need to use aList(Of PointF)
and then add aNew PointF()
and not cast again toInteger
. That's bad. Use thePointF
structure, it accepts aSingle
data type. => Do not useIntegers
in this procedure anywhere.
– Jimi
Nov 10 at 1:06
1
I edited my code in my answer to fit your suggestions. Constant casts fixed and improved graphics. Thanks!
– Elijah Adams
Nov 10 at 1:15
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
I've tinkered with the suggestions you guys commented and fixed the bug I was having. I wasn't using correct data types. Also, I utilized e.Graphics.Drawlines and the StockObject tip for pens and disposing of them. Thanks, again!
https://imgur.com/B37MDwB
If there's any other improvements I can make to my code feel free to comment them.
Option Strict On
Imports System.Drawing.Drawing2D
Public Class Form1
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles
Me.Paint
'Side Length
Dim side As Single = 30
'Grid Width
Dim width As Single = 10
'Grid Height
Dim height As Single = 5
'Starting X
Dim startX As Single = 0
'Starting Y
Dim startY As Single = 0
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
e.Graphics.PixelOffsetMode = PixelOffsetMode.Half
Dim apothem As Single = CSng(Math.Sqrt(3) * side / 2.0F)
Dim half As Single = (side / 2)
For i = 1 To width Step 1
For j = 1 To height Step 1
Dim centerX As Single = (startX + (side * i * 1.5F))
Dim centerY As Single = (startY + (apothem * j * 2))
If i Mod 2 = 0 Then
centerY += apothem
End If
Dim points As New List(Of PointF)
points.Add(New PointF((centerX - half), (centerY + apothem)))
points.Add(New PointF((centerX + half), (centerY + apothem)))
points.Add(New PointF((centerX + side), (centerY)))
points.Add(New PointF((centerX + half), (centerY - apothem)))
points.Add(New PointF((centerX - half), (centerY - apothem)))
points.Add(New PointF((centerX - side), (centerY)))
points.Add(New PointF((centerX - half), (centerY + apothem)))
e.Graphics.DrawLines(Pens.Gray, points.ToArray())
Next
Next
End Sub
End Class
I've tinkered with the suggestions you guys commented and fixed the bug I was having. I wasn't using correct data types. Also, I utilized e.Graphics.Drawlines and the StockObject tip for pens and disposing of them. Thanks, again!
https://imgur.com/B37MDwB
If there's any other improvements I can make to my code feel free to comment them.
Option Strict On
Imports System.Drawing.Drawing2D
Public Class Form1
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles
Me.Paint
'Side Length
Dim side As Single = 30
'Grid Width
Dim width As Single = 10
'Grid Height
Dim height As Single = 5
'Starting X
Dim startX As Single = 0
'Starting Y
Dim startY As Single = 0
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
e.Graphics.PixelOffsetMode = PixelOffsetMode.Half
Dim apothem As Single = CSng(Math.Sqrt(3) * side / 2.0F)
Dim half As Single = (side / 2)
For i = 1 To width Step 1
For j = 1 To height Step 1
Dim centerX As Single = (startX + (side * i * 1.5F))
Dim centerY As Single = (startY + (apothem * j * 2))
If i Mod 2 = 0 Then
centerY += apothem
End If
Dim points As New List(Of PointF)
points.Add(New PointF((centerX - half), (centerY + apothem)))
points.Add(New PointF((centerX + half), (centerY + apothem)))
points.Add(New PointF((centerX + side), (centerY)))
points.Add(New PointF((centerX + half), (centerY - apothem)))
points.Add(New PointF((centerX - half), (centerY - apothem)))
points.Add(New PointF((centerX - side), (centerY)))
points.Add(New PointF((centerX - half), (centerY + apothem)))
e.Graphics.DrawLines(Pens.Gray, points.ToArray())
Next
Next
End Sub
End Class
edited Nov 10 at 1:14
answered Nov 10 at 0:16
Elijah Adams
317
317
1
Adde.Graphics.SmoothingMode = SmoothingMode.AntiAlias
ande.Graphics.PixelOffsetMode = PixelOffsetMode.Half
before the loop. See the difference. + You should use single, not double. In your loop you have constant casts from double to single inpoints.Add()
+Dim apothem
andDim half
should be moved outside the loop. You have to calculate those just once.
– Jimi
Nov 10 at 0:45
1
Cast to single when needed (e.g.,CSng((Math.Sqrt(3) / 2.0F) * side)
). Use single values for all the other varialbles: side, width etc. Btw,width
andheight
are bad names (same as Controls properties)). Use something likeGridWidth
,GridHeight
etc.
– Jimi
Nov 10 at 0:53
I did the 2dGraphics suggestions and I liked them, but you've lost me on the casting integers part.
– Elijah Adams
Nov 10 at 1:01
1
Simple. All of you local variables should be declared asSingle
. When you do, you'll have consistent behaviour on all the calculations. You need to use aList(Of PointF)
and then add aNew PointF()
and not cast again toInteger
. That's bad. Use thePointF
structure, it accepts aSingle
data type. => Do not useIntegers
in this procedure anywhere.
– Jimi
Nov 10 at 1:06
1
I edited my code in my answer to fit your suggestions. Constant casts fixed and improved graphics. Thanks!
– Elijah Adams
Nov 10 at 1:15
add a comment |
1
Adde.Graphics.SmoothingMode = SmoothingMode.AntiAlias
ande.Graphics.PixelOffsetMode = PixelOffsetMode.Half
before the loop. See the difference. + You should use single, not double. In your loop you have constant casts from double to single inpoints.Add()
+Dim apothem
andDim half
should be moved outside the loop. You have to calculate those just once.
– Jimi
Nov 10 at 0:45
1
Cast to single when needed (e.g.,CSng((Math.Sqrt(3) / 2.0F) * side)
). Use single values for all the other varialbles: side, width etc. Btw,width
andheight
are bad names (same as Controls properties)). Use something likeGridWidth
,GridHeight
etc.
– Jimi
Nov 10 at 0:53
I did the 2dGraphics suggestions and I liked them, but you've lost me on the casting integers part.
– Elijah Adams
Nov 10 at 1:01
1
Simple. All of you local variables should be declared asSingle
. When you do, you'll have consistent behaviour on all the calculations. You need to use aList(Of PointF)
and then add aNew PointF()
and not cast again toInteger
. That's bad. Use thePointF
structure, it accepts aSingle
data type. => Do not useIntegers
in this procedure anywhere.
– Jimi
Nov 10 at 1:06
1
I edited my code in my answer to fit your suggestions. Constant casts fixed and improved graphics. Thanks!
– Elijah Adams
Nov 10 at 1:15
1
1
Add
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
and e.Graphics.PixelOffsetMode = PixelOffsetMode.Half
before the loop. See the difference. + You should use single, not double. In your loop you have constant casts from double to single in points.Add()
+ Dim apothem
and Dim half
should be moved outside the loop. You have to calculate those just once.– Jimi
Nov 10 at 0:45
Add
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
and e.Graphics.PixelOffsetMode = PixelOffsetMode.Half
before the loop. See the difference. + You should use single, not double. In your loop you have constant casts from double to single in points.Add()
+ Dim apothem
and Dim half
should be moved outside the loop. You have to calculate those just once.– Jimi
Nov 10 at 0:45
1
1
Cast to single when needed (e.g.,
CSng((Math.Sqrt(3) / 2.0F) * side)
). Use single values for all the other varialbles: side, width etc. Btw, width
and height
are bad names (same as Controls properties)). Use something like GridWidth
, GridHeight
etc.– Jimi
Nov 10 at 0:53
Cast to single when needed (e.g.,
CSng((Math.Sqrt(3) / 2.0F) * side)
). Use single values for all the other varialbles: side, width etc. Btw, width
and height
are bad names (same as Controls properties)). Use something like GridWidth
, GridHeight
etc.– Jimi
Nov 10 at 0:53
I did the 2dGraphics suggestions and I liked them, but you've lost me on the casting integers part.
– Elijah Adams
Nov 10 at 1:01
I did the 2dGraphics suggestions and I liked them, but you've lost me on the casting integers part.
– Elijah Adams
Nov 10 at 1:01
1
1
Simple. All of you local variables should be declared as
Single
. When you do, you'll have consistent behaviour on all the calculations. You need to use a List(Of PointF)
and then add a New PointF()
and not cast again to Integer
. That's bad. Use the PointF
structure, it accepts a Single
data type. => Do not use Integers
in this procedure anywhere.– Jimi
Nov 10 at 1:06
Simple. All of you local variables should be declared as
Single
. When you do, you'll have consistent behaviour on all the calculations. You need to use a List(Of PointF)
and then add a New PointF()
and not cast again to Integer
. That's bad. Use the PointF
structure, it accepts a Single
data type. => Do not use Integers
in this procedure anywhere.– Jimi
Nov 10 at 1:06
1
1
I edited my code in my answer to fit your suggestions. Constant casts fixed and improved graphics. Thanks!
– Elijah Adams
Nov 10 at 1:15
I edited my code in my answer to fit your suggestions. Constant casts fixed and improved graphics. Thanks!
– Elijah Adams
Nov 10 at 1:15
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53220042%2fmy-math-seems-fine-but-my-drawlines-look-weird-hexagon-grid%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
So write some test code. Draw one hexagon at a time and see exactly where/when things go wrong and then you can observe the actual values in use at the time. You fix bugs by debugging and testing, not just by reading code.
– jmcilhinney
Nov 9 at 5:18
1
Also, I would be inclined to look at a single call to
DrawLines
rather than multiple calls toDrawLine
. Finally, you should be disposing yourPen
, which you should do by creating it with aUsing
statement.– jmcilhinney
Nov 9 at 5:29
In the process of doing that. The only thing that makes my hexagons smooth is when the length of the side is an even number. Odd numbers may not be as accurate I suppose. I'll continue to tinker. And I'll look into those improvements! Thanks!
– Elijah Adams
Nov 9 at 5:29
2
Before debugging, set Option Strict On. Correct the assignments (and the errors) using all floating points values (single). Also, note that there's a
e.Graphics.DrawLines()
method (plural) but alsoe.Graphics.DrawPolygon()
. All of those accept floating point positions. You could also exploreGraphicsPath.AddPolygon()
. Since you're using a Pen on size 1, you could use a StockObject (Pens.Gray
) which doesn't need disposing of. Or a pre-defined custom Pen that you Dispose() of at the end (when closing the Form/App)– Jimi
Nov 9 at 6:01
2
Put
Option Strict On
at the very top beforePublic Class Form1
. VS will then highlight your problem. Replace the highlightedInteger
s withSingle
and it will look smooth.– GSerg
Nov 9 at 9:28