455,033 Members | 1,285 Online Need help? Post your question and get tips & solutions from a community of 455,033 IT Pros & Developers. It's quick & easy.

# Nearest point to the mouse cursor?

 P: n/a I have been developing a little project which draw's a hexgrid on a panel within a form similar to this - it:s used as a client from a e-mail based strategy game: ____ ____ / \ / \ / (0,0) \____/ (2,0) \____/ \ / \ / \ \____/(1,1) \____/ (3,1) \_ / \ / \ / (0,1) \____/ (2,1) \____/ \ / \ / \ \____/(1,2) \____/ (3,2) \_ / \ / \ / (0,2) \____/ (2,2) \____/ \ / \ / \ \____/(1,3) \____/ (3,3) \_ The number of hexes can vary depending on the mapsize. now the problem I currently have is trying to get a label.text to display which hex coord the mouse is currently in. Using the mouse move function I can get it to automatically change when it passes over the lines in the (1,y) columns by using the following formula: (for these purposes HexHeight = 44 pixels, HexWidth = 50 pixels) MouseYpos = LocalMousePosition.Y / HexHeight Label1.text = "Coords: " & MouseXpos & "," & MouseYpos however, because the colums are staggered any column starting with an even number get's the new coords changed halfway through it. So I'm now leaning towards trying mark the centre point of each hex, and then establishing which one the mousepointer is nearest to. However I'm having difficulty in figuring out how to do this. Can anyone help? Nov 21 '05 #1
16 Replies

 P: n/a Hi, Create a region for each cell. Use the region isvisble to see if the cursor is in the cell. Dim rgnCircle As Region Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim pth As New System.Drawing.Drawing2D.GraphicsPath pth.AddEllipse(100, 100, 50, 50) rgnCircle = New Region(pth) End Sub Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint e.Graphics.FillRegion(Brushes.Blue, rgnCircle) End Sub Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove Me.Text = String.Format("In Circle {0}", rgnCircle.IsVisible(New Point(e.X, e.Y))) End Sub Ken ------------------------------------- "Niels Jensen" wrote in message news:9E**********************************@microsof t.com... I have been developing a little project which draw's a hexgrid on a panel within a form similar to this - it:s used as a client from a e-mail based strategy game: ____ ____ / \ / \ / (0,0) \____/ (2,0) \____/ \ / \ / \ \____/(1,1) \____/ (3,1) \_ / \ / \ / (0,1) \____/ (2,1) \____/ \ / \ / \ \____/(1,2) \____/ (3,2) \_ / \ / \ / (0,2) \____/ (2,2) \____/ \ / \ / \ \____/(1,3) \____/ (3,3) \_ The number of hexes can vary depending on the mapsize. now the problem I currently have is trying to get a label.text to display which hex coord the mouse is currently in. Using the mouse move function I can get it to automatically change when it passes over the lines in the (1,y) columns by using the following formula: (for these purposes HexHeight = 44 pixels, HexWidth = 50 pixels) MouseYpos = LocalMousePosition.Y / HexHeight Label1.text = "Coords: " & MouseXpos & "," & MouseYpos however, because the colums are staggered any column starting with an even number get's the new coords changed halfway through it. So I'm now leaning towards trying mark the centre point of each hex, and then establishing which one the mousepointer is nearest to. However I'm having difficulty in figuring out how to do this. Can anyone help? Nov 21 '05 #2

 P: n/a Hi, Thanks for the help so far but I do have one further question - how do you do it for multiple regions? I've managed to apply the example you gave me to my program but I now have another problem... there could be hundreds of Hexregions on the form at any time - the problem is it's an unknown number of regions as the person running the server can make a map of any size. How can I take this to the next step and get the mousemove event to cover an unknown number of regions on the form? Niels Ken Tucker [MVP] wrote: Hi, Create a region for each cell. Use the region isvisble to see if the cursor is in the cell. Dim rgnCircle As Region Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim pth As New System.Drawing.Drawing2D.GraphicsPath pth.AddEllipse(100, 100, 50, 50) rgnCircle = New Region(pth) End Sub Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint e.Graphics.FillRegion(Brushes.Blue, rgnCircle) End Sub Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove Me.Text = String.Format("In Circle {0}", rgnCircle.IsVisible(New Point(e.X, e.Y))) End Sub Ken ------------------------------------- "Niels Jensen" wrote in message news:9E**********************************@microsof t.com... I have been developing a little project which draw's a hexgrid on a panel within a form similar to this - it:s used as a client from a e-mail based strategy game: ____ ____ / \ / \ / (0,0) \____/ (2,0) \____/ \ / \ / \ \____/(1,1) \____/ (3,1) \_ / \ / \ / (0,1) \____/ (2,1) \____/ \ / \ / \ \____/(1,2) \____/ (3,2) \_ / \ / \ / (0,2) \____/ (2,2) \____/ \ / \ / \ \____/(1,3) \____/ (3,3) \_ The number of hexes can vary depending on the mapsize. now the problem I currently have is trying to get a label.text to display which hex coord the mouse is currently in. Using the mouse move function I can get it to automatically change when it passes over the lines in the (1,y) columns by using the following formula: (for these purposes HexHeight = 44 pixels, HexWidth = 50 pixels) MouseYpos = LocalMousePosition.Y / HexHeight Label1.text = "Coords: " & MouseXpos & "," & MouseYpos however, because the colums are staggered any column starting with an even number get's the new coords changed halfway through it. So I'm now leaning towards trying mark the centre point of each hex, and then establishing which one the mousepointer is nearest to. However I'm having difficulty in figuring out how to do this. Can anyone help? Nov 21 '05 #3

 P: n/a "Niels Jensen" wrote Thanks for the help so far but I do have one further question - how do you do it for multiple regions? I've managed to apply the example you gave me to my program but I now have another problem... there could be hundreds of Hexregions on the form at any time - the problem is it's an unknown number of regions as the person running the server can make a map of any size. How can I take this to the next step and get the mousemove event to cover an unknown number of regions on the form? Since you have to cover some large number of cells, you might do best by calculating the results. For an example, paste the following code in a new form, under the Designer generated code (section). HTH LFS Public Image As Bitmap Private Rows(1) As Array Const SX As Integer = 30 ' Red cell sizes Const SY As Integer = 50 Const RATIO As Single = SX / SY Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Image = New Bitmap(Me.ClientSize.Width, Me.ClientSize.Height) ' Row map indicates which cells have angles Rows(0) = New Integer() {-1, 0, 0, -2, 1, 1, -1} Rows(1) = New Integer() {-2, 0, 0, -1, 1, 1, -2} DrawHex() End Sub Private Sub HexCell(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove Dim r, x, y, hx, hy As Integer Dim a As Integer() ' Get red grid cell x and y x = e.X \ SX y = e.Y \ SY ' Preliminary HexX and HexY hx = x \ 3 hy = y \ 2 ' Get row map value (r) a = CType(Rows(y And 1), Integer()) r = a(x Mod 6) ' Adjust for angled cells If r = -1 Then If (e.X - (x * SX)) < ((SY - (e.Y - (y * SY))) * RATIO) Then hx -= 1 End If 'Debug.WriteLine((e.X - (x * SX)).ToString & " X " & (SY - (e.Y - (y * SY))).ToString & " -Y " & ((SY - (e.Y - (y * SY))) * RATIO).ToString) ElseIf r = -2 Then If (e.X - (x * SX)) < ((e.Y - (y * SY)) * RATIO) Then hx -= 1 End If 'Debug.WriteLine((e.X - (x * SX)).ToString & " X " & (e.Y - (y * SY)).ToString & " -Y " & ((e.Y - (y * SY)) * RATIO).ToString) End If ' Adjust for y offset in odd hex columns If (hx And 1) = 1 AndAlso (y And 1) = 0 Then hy -= 1 ' Show values Dim msg As String = "X=" & hx.ToString & " Y=" & hy.ToString If Me.Text <> msg Then Me.Text = msg End Sub Private Sub DrawHex() ' This just draws the cells on the screen Dim grx As Graphics = Graphics.FromImage(Image) Dim r, hx, hy, x, y As Integer Dim a As Integer() For y = 0 To 12 For x = 0 To 17 grx.DrawRectangle(Pens.Red, New Rectangle(x * SX, y * SY, SX, SY)) a = CType(Rows(y And 1), Integer()) r = a(x Mod 6) hx = x * SX hy = y * SY If r = 0 Then If (y And 1) = 0 Then grx.DrawLine(Pens.Black, hx, hy, hx + SX, hy) Else grx.DrawLine(Pens.Black, hx, hy + SY, hx + SX, hy + SY) End If ElseIf r = 1 Then If (y And 1) = 1 Then grx.DrawLine(Pens.Black, hx, hy, hx + SX, hy) Else grx.DrawLine(Pens.Black, hx, hy + SY, hx + SX, hy + SY) End If ElseIf r = -1 Then grx.DrawLine(Pens.Black, hx, hy + SY, hx + SX, hy) ElseIf r = -2 Then grx.DrawLine(Pens.Black, hx, hy, hx + SX, hy + SY) End If Next Next End Sub Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint Dim grx As Graphics = Me.CreateGraphics grx.DrawImage(Image, 0, 0) grx.Dispose() End Sub Nov 21 '05 #4

 P: n/a Thanks for this code Larry it's *yet* another was that I can draw a hexmap... Is there any chance you could be so kind and explain what the complicated mathematical sections do (and how they do it?) I've been trying to figure out how the 1st section works: Rows(0) = New Integer() {-1, 0, 0, -2, 1, 1, -1} Rows(1) = New Integer() {-2, 0, 0, -1, 1, 1, -2} it doesn't make any sense to me as I thought the {} was used for formatting. If you can't tell, I'm also a bit of a newbie in this VB lark :) I'm also drawing the hexcells in a panel, not a form and although I've successfully managed to do this within my program using your code, the graphics are only drawn within the initial visible part of the panel, as soon as I use the scrollbars I get one of two things hapening. If the drawimage is in the "paint" sub then it re-draws all over the screen eventually drawing a nice big red block on the panel screen. how can I make your hexmap draw a 50hex by 50hex board and then maintain the image so that the scrollbars on the panel display the image correctly. I'll be overlaying the Hexes that have information with small .bmp graphical images such as trees or towns, the idea being that the end user can click on a hex containing a town image and get the information for the town. Niels "Larry Serflaten" wrote: "Niels Jensen" wrote Thanks for the help so far but I do have one further question - how do you do it for multiple regions? I've managed to apply the example you gave me to my program but I now have another problem... there could be hundreds of Hexregions on the form at any time - the problem is it's an unknown number of regions as the person running the server can make a map of any size. How can I take this to the next step and get the mousemove event to cover an unknown number of regions on the form? Since you have to cover some large number of cells, you might do best by calculating the results. For an example, paste the following code in a new form, under the Designer generated code (section). HTH LFS Public Image As Bitmap Private Rows(1) As Array Const SX As Integer = 30 ' Red cell sizes Const SY As Integer = 50 Const RATIO As Single = SX / SY Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Image = New Bitmap(Me.ClientSize.Width, Me.ClientSize.Height) ' Row map indicates which cells have angles Rows(0) = New Integer() {-1, 0, 0, -2, 1, 1, -1} Rows(1) = New Integer() {-2, 0, 0, -1, 1, 1, -2} DrawHex() End Sub Private Sub HexCell(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove Dim r, x, y, hx, hy As Integer Dim a As Integer() ' Get red grid cell x and y x = e.X \ SX y = e.Y \ SY ' Preliminary HexX and HexY hx = x \ 3 hy = y \ 2 ' Get row map value (r) a = CType(Rows(y And 1), Integer()) r = a(x Mod 6) ' Adjust for angled cells If r = -1 Then If (e.X - (x * SX)) < ((SY - (e.Y - (y * SY))) * RATIO) Then hx -= 1 End If 'Debug.WriteLine((e.X - (x * SX)).ToString & " X " & (SY - (e.Y - (y * SY))).ToString & " -Y " & ((SY - (e.Y - (y * SY))) * RATIO).ToString) ElseIf r = -2 Then If (e.X - (x * SX)) < ((e.Y - (y * SY)) * RATIO) Then hx -= 1 End If 'Debug.WriteLine((e.X - (x * SX)).ToString & " X " & (e.Y - (y * SY)).ToString & " -Y " & ((e.Y - (y * SY)) * RATIO).ToString) End If ' Adjust for y offset in odd hex columns If (hx And 1) = 1 AndAlso (y And 1) = 0 Then hy -= 1 ' Show values Dim msg As String = "X=" & hx.ToString & " Y=" & hy.ToString If Me.Text <> msg Then Me.Text = msg End Sub Private Sub DrawHex() ' This just draws the cells on the screen Dim grx As Graphics = Graphics.FromImage(Image) Dim r, hx, hy, x, y As Integer Dim a As Integer() For y = 0 To 12 For x = 0 To 17 grx.DrawRectangle(Pens.Red, New Rectangle(x * SX, y * SY, SX, SY)) a = CType(Rows(y And 1), Integer()) r = a(x Mod 6) hx = x * SX hy = y * SY If r = 0 Then If (y And 1) = 0 Then grx.DrawLine(Pens.Black, hx, hy, hx + SX, hy) Else grx.DrawLine(Pens.Black, hx, hy + SY, hx + SX, hy + SY) End If ElseIf r = 1 Then If (y And 1) = 1 Then grx.DrawLine(Pens.Black, hx, hy, hx + SX, hy) Else grx.DrawLine(Pens.Black, hx, hy + SY, hx + SX, hy + SY) End If ElseIf r = -1 Then grx.DrawLine(Pens.Black, hx, hy + SY, hx + SX, hy) ElseIf r = -2 Then grx.DrawLine(Pens.Black, hx, hy, hx + SX, hy + SY) End If Next Next End Sub Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint Dim grx As Graphics = Me.CreateGraphics grx.DrawImage(Image, 0, 0) grx.Dispose() End Sub Nov 21 '05 #5

 P: n/a "Niels Jensen" wrote Thanks for this code Larry it's *yet* another was that I can draw a hexmap... Is there any chance you could be so kind and explain what the complicated mathematical sections do (and how they do it?) It is very easy to get X and Y coordinates when the cells are rectangles: ' Get red grid cell x and y x = e.X \ SX y = e.Y \ SY SX and SY are the size values of the red cells, so that, dividing the current X or Y mouse position by the size of the cell give the cell's X or Y values. It is not so easy when there are angled lines or other such polygons. In your case, I first set out to identify where the angled lines are, you can see by the displayed grid they do follow a repeating pattern and that pattern is represented in the Rows array. Second, the angle the slopes are at is constant so one formula (based on the ratio of X to Y) can be used to tell when the mouse crosses the angled line. When it does, the horizontal position has to be adjusted. There is one formula for the forward slash, and another for the backward slash. With the correct X position, there is one other thing to address and that is that alternating hex columns are offset by one cell difference and that is found and altered as the last part of the process. I've been trying to figure out how the 1st section works: Rows(0) = New Integer() {-1, 0, 0, -2, 1, 1, -1} Rows(1) = New Integer() {-2, 0, 0, -1, 1, 1, -2} It is an array of arrays. These statements assign arrays of Integers to the elements of the Rows array. "New Integer()" tells VB you're creating a new array and the values inside the brackets initialize that array with those values. In this case, a -1 represents the forward slash (angle cell) and -2 represents the backward slash (angle cell). 0 and 1 were only used during the draw process to help determine if the horizontal line of the hex cell should be at the top or bottom of that group of cells. I'm also drawing the hexcells in a panel, not a form and although I've successfully managed to do this within my program using your code, the graphics are only drawn within the initial visible part of the panel, as soon as I use the scrollbars I get one of two things hapening. If the drawimage is in the "paint" sub then it re-draws all over the screen eventually drawing a nice big red block on the panel screen. how can I make your hexmap draw a 50hex by 50hex board and then maintain the image so that the scrollbars on the panel display the image correctly. I'll be overlaying the Hexes that have information with small .bmp graphical images such as trees or towns, the idea being that the end user can click on a hex containing a town image and get the information for the town. You will probably want to back up that panel with a memory bitmap such that you draw your 50X50 board to the bitmap, and then copy it over to the panel (in its Paint event) depending on the scroll position. While doing your drawing in the paint event is a low impact method, it gets a bit useless when you have several items to draw and are erasing the screen to reposition them all. In that case it is better to draw to memory and then copy the finished image in one go. Take a look at what I did, I gave the form a public Image property that was my memory bitmap. It is such a common methodology that I did it by habit! In the form's Paint event I simply copied over the image in one go. Doing it that way (and even that can be improved) allows for automatic repainting when the form is restored from being minimized, or when some other window covers and then exposes that form. Where I have 0, 0 you'd add in values from your scroll control.... HTH LFS Nov 21 '05 #6

 P: n/a Hi, Try something like this. Dim arShapes As New ArrayList Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load For x As Integer = 0 To 4 Dim pth As New System.Drawing.Drawing2D.GraphicsPath Dim rgnCircle As Region pth.AddEllipse(100, 10 + x * 50, 50, 50) rgnCircle = New Region(pth) arShapes.Add(rgnCircle) Next x End Sub Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint For Each rgnCircle As Region In arShapes e.Graphics.FillRegion(Brushes.Blue, rgnCircle) Next End Sub Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove Dim strOut As String = "Not over circle" For x As Integer = 0 To arShapes.Count - 1 If DirectCast(arShapes.Item(x), Region).IsVisible(e.X, e.Y) Then strOut = String.Format("Over Circle {0}", x) End If Next Me.Text = strOut End Sub Ken ---------------------- "Niels Jensen" wrote in message news:6Z********************@pipex.net... Hi, Thanks for the help so far but I do have one further question - how do you do it for multiple regions? I've managed to apply the example you gave me to my program but I now have another problem... there could be hundreds of Hexregions on the form at any time - the problem is it's an unknown number of regions as the person running the server can make a map of any size. How can I take this to the next step and get the mousemove event to cover an unknown number of regions on the form? Niels Ken Tucker [MVP] wrote: Hi, Create a region for each cell. Use the region isvisble to see if the cursor is in the cell. Dim rgnCircle As Region Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim pth As New System.Drawing.Drawing2D.GraphicsPath pth.AddEllipse(100, 100, 50, 50) rgnCircle = New Region(pth) End Sub Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint e.Graphics.FillRegion(Brushes.Blue, rgnCircle) End Sub Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove Me.Text = String.Format("In Circle {0}", rgnCircle.IsVisible(New Point(e.X, e.Y))) End Sub Ken ------------------------------------- "Niels Jensen" wrote in message news:9E**********************************@microsof t.com... I have been developing a little project which draw's a hexgrid on a panel within a form similar to this - it:s used as a client from a e-mail based strategy game: ____ ____ / \ / \ / (0,0) \____/ (2,0) \____/ \ / \ / \ \____/(1,1) \____/ (3,1) \_ / \ / \ / (0,1) \____/ (2,1) \____/ \ / \ / \ \____/(1,2) \____/ (3,2) \_ / \ / \ / (0,2) \____/ (2,2) \____/ \ / \ / \ \____/(1,3) \____/ (3,3) \_ The number of hexes can vary depending on the mapsize. now the problem I currently have is trying to get a label.text to display which hex coord the mouse is currently in. Using the mouse move function I can get it to automatically change when it passes over the lines in the (1,y) columns by using the following formula: (for these purposes HexHeight = 44 pixels, HexWidth = 50 pixels) MouseYpos = LocalMousePosition.Y / HexHeight Label1.text = "Coords: " & MouseXpos & "," & MouseYpos however, because the colums are staggered any column starting with an even number get's the new coords changed halfway through it. So I'm now leaning towards trying mark the centre point of each hex, and then establishing which one the mousepointer is nearest to. However I'm having difficulty in figuring out how to do this. Can anyone help? Nov 21 '05 #7

 P: n/a I'd just like to thank averyone who helped me out on this - I'm getting there..... slowly and you've all been a great help holding my hand as I go Thanks guys Niels "Larry Serflaten" wrote: "Niels Jensen" wrote Thanks for this code Larry it's *yet* another was that I can draw a hexmap... Is there any chance you could be so kind and explain what the complicated mathematical sections do (and how they do it?) It is very easy to get X and Y coordinates when the cells are rectangles: ' Get red grid cell x and y x = e.X \ SX y = e.Y \ SY SX and SY are the size values of the red cells, so that, dividing the current X or Y mouse position by the size of the cell give the cell's X or Y values. It is not so easy when there are angled lines or other such polygons. In your case, I first set out to identify where the angled lines are, you can see by the displayed grid they do follow a repeating pattern and that pattern is represented in the Rows array. Second, the angle the slopes are at is constant so one formula (based on the ratio of X to Y) can be used to tell when the mouse crosses the angled line. When it does, the horizontal position has to be adjusted. There is one formula for the forward slash, and another for the backward slash. With the correct X position, there is one other thing to address and that is that alternating hex columns are offset by one cell difference and that is found and altered as the last part of the process. I've been trying to figure out how the 1st section works: Rows(0) = New Integer() {-1, 0, 0, -2, 1, 1, -1} Rows(1) = New Integer() {-2, 0, 0, -1, 1, 1, -2} It is an array of arrays. These statements assign arrays of Integers to the elements of the Rows array. "New Integer()" tells VB you're creating a new array and the values inside the brackets initialize that array with those values. In this case, a -1 represents the forward slash (angle cell) and -2 represents the backward slash (angle cell). 0 and 1 were only used during the draw process to help determine if the horizontal line of the hex cell should be at the top or bottom of that group of cells. I'm also drawing the hexcells in a panel, not a form and although I've successfully managed to do this within my program using your code, the graphics are only drawn within the initial visible part of the panel, as soon as I use the scrollbars I get one of two things hapening. If the drawimage is in the "paint" sub then it re-draws all over the screen eventually drawing a nice big red block on the panel screen. how can I make your hexmap draw a 50hex by 50hex board and then maintain the image so that the scrollbars on the panel display the image correctly. I'll be overlaying the Hexes that have information with small .bmp graphical images such as trees or towns, the idea being that the end user can click on a hex containing a town image and get the information for the town. You will probably want to back up that panel with a memory bitmap such that you draw your 50X50 board to the bitmap, and then copy it over to the panel (in its Paint event) depending on the scroll position. While doing your drawing in the paint event is a low impact method, it gets a bit useless when you have several items to draw and are erasing the screen to reposition them all. In that case it is better to draw to memory and then copy the finished image in one go. Take a look at what I did, I gave the form a public Image property that was my memory bitmap. It is such a common methodology that I did it by habit! In the form's Paint event I simply copied over the image in one go. Doing it that way (and even that can be improved) allows for automatic repainting when the form is restored from being minimized, or when some other window covers and then exposes that form. Where I have 0, 0 you'd add in values from your scroll control.... HTH LFS Nov 21 '05 #8

 P: n/a Hi Ken, I've almost got this sorted now - I have the regions all being drawn out in a panel (around 100 for test purposes) and it looks good. however when I scroll the panel using autoscroll The regions vanish as I scroll down, I also noticed that no-matter where in the panel I scroll to the regions are always in the same position on the panel, i.e hex 1 is in the top left of the panel even though it should be hex three due to scrolling approx three hexes down. Is there any way for the regions to scroll around the panel properly and also to make the correct regions be in the correct locations? Cheers Niels "Ken Tucker [MVP]" wrote: Hi, Try something like this. Dim arShapes As New ArrayList Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load For x As Integer = 0 To 4 Dim pth As New System.Drawing.Drawing2D.GraphicsPath Dim rgnCircle As Region pth.AddEllipse(100, 10 + x * 50, 50, 50) rgnCircle = New Region(pth) arShapes.Add(rgnCircle) Next x End Sub Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint For Each rgnCircle As Region In arShapes e.Graphics.FillRegion(Brushes.Blue, rgnCircle) Next End Sub Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove Dim strOut As String = "Not over circle" For x As Integer = 0 To arShapes.Count - 1 If DirectCast(arShapes.Item(x), Region).IsVisible(e.X, e.Y) Then strOut = String.Format("Over Circle {0}", x) End If Next Me.Text = strOut End Sub Ken ---------------------- "Niels Jensen" wrote in message news:6Z********************@pipex.net... Hi, Thanks for the help so far but I do have one further question - how do you do it for multiple regions? I've managed to apply the example you gave me to my program but I now have another problem... there could be hundreds of Hexregions on the form at any time - the problem is it's an unknown number of regions as the person running the server can make a map of any size. How can I take this to the next step and get the mousemove event to cover an unknown number of regions on the form? Niels Ken Tucker [MVP] wrote: Hi, Create a region for each cell. Use the region isvisble to see if the cursor is in the cell. Dim rgnCircle As Region Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim pth As New System.Drawing.Drawing2D.GraphicsPath pth.AddEllipse(100, 100, 50, 50) rgnCircle = New Region(pth) End Sub Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint e.Graphics.FillRegion(Brushes.Blue, rgnCircle) End Sub Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove Me.Text = String.Format("In Circle {0}", rgnCircle.IsVisible(New Point(e.X, e.Y))) End Sub Ken ------------------------------------- "Niels Jensen" wrote in message news:9E**********************************@microsof t.com... I have been developing a little project which draw's a hexgrid on a panel within a form similar to this - it:s used as a client from a e-mail based strategy game: ____ ____ / \ / \ / (0,0) \____/ (2,0) \____/ \ / \ / \ \____/(1,1) \____/ (3,1) \_ / \ / \ / (0,1) \____/ (2,1) \____/ \ / \ / \ \____/(1,2) \____/ (3,2) \_ / \ / \ / (0,2) \____/ (2,2) \____/ \ / \ / \ \____/(1,3) \____/ (3,3) \_ The number of hexes can vary depending on the mapsize. now the problem I currently have is trying to get a label.text to display which hex coord the mouse is currently in. Using the mouse move function I can get it to automatically change when it passes over the lines in the (1,y) columns by using the following formula: (for these purposes HexHeight = 44 pixels, HexWidth = 50 pixels) MouseYpos = LocalMousePosition.Y / HexHeight Label1.text = "Coords: " & MouseXpos & "," & MouseYpos however, because the colums are staggered any column starting with an even number get's the new coords changed halfway through it. So I'm now leaning towards trying mark the centre point of each hex, and then establishing which one the mousepointer is nearest to. However I'm having difficulty in figuring out how to do this. Can anyone help? Nov 21 '05 #9

 P: n/a "Niels Jensen" wrote I have modified your original: x = e.X \ SX y = e.Y \ SY to: x = (e.X + HScrollBar1.Value) \ SX + (HScrollBar1.Value \ SX) y = (e.Y + VScrollBar1.Value) \ SY + (VScrollBar1.Value \ SY) ..... It also doesn't seem to work on the angles, although I have a feeling that's because I need to change the following somehow: ..... Any advice you have would be great I haven't tested anything using a scrollbar, but as you saw, it works out when the proper X and Y values are used. I am not sure why you used the new formula but I would suggest you alter the whole routine to first get the composite values of e.X and e.Y and use those in place of e.X and e.Y. First I am assuming that with a Vscroll value of 0, then clicking on 0,0, will give you the correct 0,0 result, and when the Vscroll value is 10, then clicking on 0,0 should actually be 0,10. (opposed to using any negative values) Likewise when the VScroll value is 20 and you click on 0,0 you actually need it to be 0,20 (because the hex grid has been drawn 20 pixels higher than its original position) Do you see the pattern? So the first thing to do is to get the X and Y values back to their needed values, then let the rest of the routine work, something like: Dim eX, eY as Integer eX = e.X - HScrollBar1.Value eY = e.Y - VScrollBar1.Value After that, replace every occurance of e.X with eX and every occurance of e.Y with eY: x = eX \ SX y = eY \ SY And do the same with the later formulas then see if things start to turn out right again. HTH LFS Nov 21 '05 #11

 P: n/a OMG! Larry your a genius and a star! Thanks it worked a treat and just goes to show simplicity is the key. I had a friend a I trying out some weird mathamatical formulas trying to do the simple thing you explained :p Ahh well - Thanks again! Niels "Larry Serflaten" wrote: "Niels Jensen" wrote I have modified your original: x = e.X \ SX y = e.Y \ SY to: x = (e.X + HScrollBar1.Value) \ SX + (HScrollBar1.Value \ SX) y = (e.Y + VScrollBar1.Value) \ SY + (VScrollBar1.Value \ SY) ..... It also doesn't seem to work on the angles, although I have a feeling that's because I need to change the following somehow: ..... Any advice you have would be great I haven't tested anything using a scrollbar, but as you saw, it works out when the proper X and Y values are used. I am not sure why you used the new formula but I would suggest you alter the whole routine to first get the composite values of e.X and e.Y and use those in place of e.X and e.Y. First I am assuming that with a Vscroll value of 0, then clicking on 0,0, will give you the correct 0,0 result, and when the Vscroll value is 10, then clicking on 0,0 should actually be 0,10. (opposed to using any negative values) Likewise when the VScroll value is 20 and you click on 0,0 you actually need it to be 0,20 (because the hex grid has been drawn 20 pixels higher than its original position) Do you see the pattern? So the first thing to do is to get the X and Y values back to their needed values, then let the rest of the routine work, something like: Dim eX, eY as Integer eX = e.X - HScrollBar1.Value eY = e.Y - VScrollBar1.Value After that, replace every occurance of e.X with eX and every occurance of e.Y with eY: x = eX \ SX y = eY \ SY And do the same with the later formulas then see if things start to turn out right again. HTH LFS Nov 21 '05 #12

 P: n/a Ghaaa! Larry Please save me again! I just realised that the hex cells run down in even and odd numbers depending on the column. i.e if X = 0, 2, 4... then all Y's cell Values will be even 0,2,4... if X = 1, 3, 5... then all X's cell values will be odd I'm looking at the code, and I just cant work out what needs to be done to make the X/Y valuse read right. have you got any pointers? Cheers Niels "Niels Jensen" wrote: OMG! Larry your a genius and a star! Thanks it worked a treat and just goes to show simplicity is the key. I had a friend a I trying out some weird mathamatical formulas trying to do the simple thing you explained :p Ahh well - Thanks again! Niels "Larry Serflaten" wrote: "Niels Jensen" wrote I have modified your original: x = e.X \ SX y = e.Y \ SY to: x = (e.X + HScrollBar1.Value) \ SX + (HScrollBar1.Value \ SX) y = (e.Y + VScrollBar1.Value) \ SY + (VScrollBar1.Value \ SY) ..... It also doesn't seem to work on the angles, although I have a feeling that's because I need to change the following somehow: ..... Any advice you have would be great I haven't tested anything using a scrollbar, but as you saw, it works out when the proper X and Y values are used. I am not sure why you used the new formula but I would suggest you alter the whole routine to first get the composite values of e.X and e.Y and use those in place of e.X and e.Y. First I am assuming that with a Vscroll value of 0, then clicking on 0,0, will give you the correct 0,0 result, and when the Vscroll value is 10, then clicking on 0,0 should actually be 0,10. (opposed to using any negative values) Likewise when the VScroll value is 20 and you click on 0,0 you actually need it to be 0,20 (because the hex grid has been drawn 20 pixels higher than its original position) Do you see the pattern? So the first thing to do is to get the X and Y values back to their needed values, then let the rest of the routine work, something like: Dim eX, eY as Integer eX = e.X - HScrollBar1.Value eY = e.Y - VScrollBar1.Value After that, replace every occurance of e.X with eX and every occurance of e.Y with eY: x = eX \ SX y = eY \ SY And do the same with the later formulas then see if things start to turn out right again. HTH LFS Nov 21 '05 #13

 P: n/a "Niels Jensen" wrote I just realised that the hex cells run down in even and odd numbers depending on the column. i.e if X = 0, 2, 4... then all Y's cell Values will be even 0,2,4... if X = 1, 3, 5... then all X's cell values will be odd I'm looking at the code, and I just cant work out what needs to be done to make the X/Y valuse read right. have you got any pointers? I don't understand the problem, can you explain it be little better? LFS Nov 21 '05 #14

 P: n/a Sure, At the moment if you go into the top left hex cell it'll read X = 0 Y = 0. If you go down to the next it'll read X = 0, Y = 1, the next will be X = 0 Y = 2 etc. What I should have realized is that it should be X= 0, y = 0 x = 0, y = 2 x = 0, y = 4 etc and on the odd X values i.e x = 1 it should be x = 1, y = 1. X = 1 Y = 3 etc. I can't believe how helpful you've been so far, I really would be at a loss without you help and for that I'm very grateful. Thanks Niels Larry Serflaten wrote: "Niels Jensen" wroteI just realised that the hex cells run down in even and odd numbersdepending on the column.i.e if X = 0, 2, 4... then all Y's cell Values will be even 0,2,4... if X = 1, 3, 5... then all X's cell values will be oddI'm looking at the code, and I just cant work out what needs to be done tomake the X/Y valuse read right.have you got any pointers? I don't understand the problem, can you explain it be little better? LFS Nov 21 '05 #15

 P: n/a "Niels Jensen" wrote I can't believe how helpful you've been so far, I really would be at a loss without you help and for that I'm very grateful. Thanks Just to be clear, see if the list below is correct OldX OldY NewX NewY 0 0 0 0 0 1 0 2 0 2 0 4 0 3 0 6 0 4 0 8 1 0 1 1 1 1 1 3 1 2 1 5 1 3 1 7 1 4 1 9 If that is it, there is definately a pattern there: NewX = OldX NewY = (OldY * 2) + (OldX And 1) Since the routine correctly outputs the X and Y, just tack on the formula to adjust Y as the last line of the routine.... LFS Nov 21 '05 #16

 P: n/a Yup - worked a treat... Once again :) Thanks for your help Larry, I'll make sure you're credited in my app :) Niels "Larry Serflaten" wrote: "Niels Jensen" wrote I can't believe how helpful you've been so far, I really would be at a loss without you help and for that I'm very grateful. Thanks Just to be clear, see if the list below is correct OldX OldY NewX NewY 0 0 0 0 0 1 0 2 0 2 0 4 0 3 0 6 0 4 0 8 1 0 1 1 1 1 1 3 1 2 1 5 1 3 1 7 1 4 1 9 If that is it, there is definately a pattern there: NewX = OldX NewY = (OldY * 2) + (OldX And 1) Since the routine correctly outputs the X and Y, just tack on the formula to adjust Y as the last line of the routine.... LFS Nov 21 '05 #17

### This discussion thread is closed

Replies have been disabled for this discussion. 