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.



Hexagonal grid



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









share|improve this question




















  • 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 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








  • 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






  • 2




    Put Option Strict On at the very top before Public Class Form1. VS will then highlight your problem. Replace the highlighted Integers with Single and it will look smooth.
    – GSerg
    Nov 9 at 9:28

















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.



Hexagonal grid



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









share|improve this question




















  • 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 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








  • 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






  • 2




    Put Option Strict On at the very top before Public Class Form1. VS will then highlight your problem. Replace the highlighted Integers with Single and it will look smooth.
    – GSerg
    Nov 9 at 9:28















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.



Hexagonal grid



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









share|improve this question















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.



Hexagonal grid



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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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








  • 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






  • 2




    Put Option Strict On at the very top before Public Class Form1. VS will then highlight your problem. Replace the highlighted Integers with Single and it will look smooth.
    – GSerg
    Nov 9 at 9:28
















  • 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 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








  • 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






  • 2




    Put Option Strict On at the very top before Public Class Form1. VS will then highlight your problem. Replace the highlighted Integers with Single 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 Integers 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 Integers with Single and it will look smooth.
– GSerg
Nov 9 at 9:28














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





share|improve this answer



















  • 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








  • 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












  • 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 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




    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













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















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

























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





share|improve this answer



















  • 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








  • 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












  • 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 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




    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

















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





share|improve this answer



















  • 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








  • 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












  • 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 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




    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















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





share|improve this answer














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






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 10 at 1:14

























answered Nov 10 at 0:16









Elijah Adams

317




317








  • 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








  • 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












  • 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 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




    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




    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




    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






  • 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








  • 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




















 

draft saved


draft discarded



















































 


draft saved


draft discarded














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





















































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







Popular posts from this blog

Guess what letter conforming each word

Port of Spain

Run scheduled task as local user group (not BUILTIN)