Mouse to Hex coordinates
Seems like everyone has ignored my last question... Well, I''ve solved this problem allready, although it still works differently on Windows NT and 98...
Here is another question, and I hope you will help me this time.
Can anyone suggest where to find or provide a good formula, algorithm, code, whatever for the convertion from mouse to hex coordinates?
My hexes are numbered like this:
00 01 02 ...
10 11 12 ...
...
And yes, I can''t use MouseMap color scheme, just can''t. Since there is some graphics that heavily overlap the background tiles... So, I have to use some mathematical way.
Ok, let me start by saying that I am a self taught programmer and tend to use things that work vs. what I am sure is better ways of doing things... I had the same problem in a game I was working on, not only on the screen you saw but also I had a radar type box in the upper left that had a red rectangel u could drag around to recenter the screen on another part of the map. I solved it by going back to my Square algorithims. I know that it is not an optimal solution but u might give it a try...
I simply used a formula similiar to below
For X = 0 to (Number of Hexs Horizontal)
For Y = 0 to (Number of Hexs Vertical)
If MouseX > Hex(X) and MouseX < Hex(X+1) then
If MouseY > Hex(Y) and MouseY < Hex(Y+1) then
Hex Clicked = X,Y
End If
End if
I am writing this without looking at my code but it should stear u in the right direction... Also Hex(X) and Hex(Y) were arrays that held the coords in pixels for each Hex. This was because my hex game used a scanned in graphic as opposed to tiles so each hex was not perfectly 60 pixels wide or long or some such. If you know that you hexs are perfect in size then you can use an algorithim that simply recursively checks the hexes since u can simply multiply X by the width of the hex and add any remainder P... When Mouse X and Y are braceted that is your X and Y...
{-P-}[----W----]{-P-}
-----------
/...../.....\
/....../...... /......./....... \.......H......./
\....../....../
\_____/_____/
Hope it helps... I will check back to see if it answres question or feel free to e-mail at Kbs4k@home.com
P.S. That is NOT some fancy txt signiture I was trying to make a txt hex... W = top flat portion of hex, P is the runover to the actual edge of points of hex on either side of W, and H is the center line hieght of the Hex.
Similiar to the way that tool bars and Nav Bars are actually long stretche Hot frames... If you use this idea you will never notice that clicking on the very edge of Hex does not register since u automatically click within a few pixels of the center anyway and a misclick simply does not register... also considering hex games are not real-time there really is no noticable issue I have found...
Edited by - Zz on June 22, 2000 9:37:46 AM
Edited by - Zz on June 22, 2000 9:38:42 AM
Edited by - Zz on June 22, 2000 9:42:11 AM
I simply used a formula similiar to below
For X = 0 to (Number of Hexs Horizontal)
For Y = 0 to (Number of Hexs Vertical)
If MouseX > Hex(X) and MouseX < Hex(X+1) then
If MouseY > Hex(Y) and MouseY < Hex(Y+1) then
Hex Clicked = X,Y
End If
End if
I am writing this without looking at my code but it should stear u in the right direction... Also Hex(X) and Hex(Y) were arrays that held the coords in pixels for each Hex. This was because my hex game used a scanned in graphic as opposed to tiles so each hex was not perfectly 60 pixels wide or long or some such. If you know that you hexs are perfect in size then you can use an algorithim that simply recursively checks the hexes since u can simply multiply X by the width of the hex and add any remainder P... When Mouse X and Y are braceted that is your X and Y...
{-P-}[----W----]{-P-}
-----------
/...../.....\
/....../...... /......./....... \.......H......./
\....../....../
\_____/_____/
Hope it helps... I will check back to see if it answres question or feel free to e-mail at Kbs4k@home.com
P.S. That is NOT some fancy txt signiture I was trying to make a txt hex... W = top flat portion of hex, P is the runover to the actual edge of points of hex on either side of W, and H is the center line hieght of the Hex.
Similiar to the way that tool bars and Nav Bars are actually long stretche Hot frames... If you use this idea you will never notice that clicking on the very edge of Hex does not register since u automatically click within a few pixels of the center anyway and a misclick simply does not register... also considering hex games are not real-time there really is no noticable issue I have found...
Edited by - Zz on June 22, 2000 9:37:46 AM
Edited by - Zz on June 22, 2000 9:38:42 AM
Edited by - Zz on June 22, 2000 9:42:11 AM
Dark Pastor-
I came up with the following formula for my hex based game before finding any other source of information on doing it. So you know what it is based on, my hex bitmaps fit withing a 32 by 32 square. At the time, I created my entire map at startup on a form, with scrollbars, which worked well for the size I was using (about 10,000 hexes). If you draw a screen at a time, you will need to adjust the formula to account for the scrolling position - the way I did it, the mouse coordinates are from the top left of the form (even if it is offscreen) rather than from the screen coordinates. Also, my staggering is as follows:
1,1...1,3...1,5
...1,2...1,4...
2,1...2,3...2,5
...2,2...2,4
The formula does not correctly choose the right and left corners of the hex, but it does work for the other areas, and it is only off by 3 pixels in width. Each column is offset by 26 pixels which is why it is in the X calc). Y is complex (using the %2) to calculate whether it is an up hex or down hex in the row based on the column it is in.
xMap = ((Xpos-4)/26+1);
yMap = (Ypos+((Xpos-4)/26%2)*16)/32+1;
I hope this helps.
Ricky B
Edited by - RickyB on June 22, 2000 11:26:52 AM
Edited by - RickyB on June 22, 2000 11:29:42 AM
I came up with the following formula for my hex based game before finding any other source of information on doing it. So you know what it is based on, my hex bitmaps fit withing a 32 by 32 square. At the time, I created my entire map at startup on a form, with scrollbars, which worked well for the size I was using (about 10,000 hexes). If you draw a screen at a time, you will need to adjust the formula to account for the scrolling position - the way I did it, the mouse coordinates are from the top left of the form (even if it is offscreen) rather than from the screen coordinates. Also, my staggering is as follows:
1,1...1,3...1,5
...1,2...1,4...
2,1...2,3...2,5
...2,2...2,4
The formula does not correctly choose the right and left corners of the hex, but it does work for the other areas, and it is only off by 3 pixels in width. Each column is offset by 26 pixels which is why it is in the X calc). Y is complex (using the %2) to calculate whether it is an up hex or down hex in the row based on the column it is in.
xMap = ((Xpos-4)/26+1);
yMap = (Ypos+((Xpos-4)/26%2)*16)/32+1;
I hope this helps.
Ricky B
Edited by - RickyB on June 22, 2000 11:26:52 AM
Edited by - RickyB on June 22, 2000 11:29:42 AM
Here is formula for a hex of size 48 across by 32 in height, the hex is oriented so that the top and bottom are flat edges, and the left side is the 'less then' and the right side is a 'greater then' symbol. The hex is 15-18-15 (= 48) pixels going across for each of the 3 parts from left to right. So here is the formula I used:
I hope it helps
Edited by - Possibility on June 22, 2000 6:55:07 PM
void MAIN_DISPLAY::MouseOver(){ //Remove the mouse cursor from the tile it was in previously int box_x; int box_y; //(box_x,box_y) is the tile box that the mouse is in box_x = (mouse_x + x_screen_pos - x_start_pixel_pt)/tile_width; if (box_x % 2 == 1) //if box_x is odd box_y = (mouse_y + y_screen_pos - y_start_pixel_pt - tile_height/2)/tile_height; else box_y = (mouse_y + y_screen_pos - y_start_pixel_pt)/tile_height; //is the mouse over one of the edge of map tiles? if (box_x < 0 // box_y < 0 // box_x >= map_width // box_y >= map_height) { tile[mouse_in_x][mouse_in_y].bMouse_In = FALSE; //the mouse is no longer over a tile //so remove the cursor from the last tile it was in return; } else //if not, then its on the map, so set the old position to false and find the new position tile[mouse_in_x][mouse_in_y].bMouse_In = FALSE; //(box_x_pos,box_y_pos) is the position in pixels of the box int box_x_pos = box_x * tile_width; int box_y_pos = box_y * tile_height;//********************************************* //(box_mouse_x,box_mouse_y) is the position of the mouse relative to the box int box_mouse_x = mouse_x + x_screen_pos - x_start_pixel_pt - box_x_pos; // the +x_screen_pos here causes this it to crash int box_mouse_y; if (box_x % 2 == 1) //if box_x is odd box_mouse_y = mouse_y + y_screen_pos - y_start_pixel_pt - tile_height/2 - box_y_pos; else box_mouse_y = mouse_y + y_screen_pos - y_start_pixel_pt - box_y_pos;//********************************************* if (box_mouse_x > 15) //then the mouse is in the box { mouse_in_x = box_x; mouse_in_y = box_y; tile[mouse_in_x][mouse_in_y].bMouse_In = TRUE; } else //then the mouse is in a possible of 3 tiles, find which one { double temp1 = tile_height; double temp2 = box_mouse_y; double temp3 = box_mouse_x; double temp = (temp1/2 - temp2)/temp3; //(tile_height/2 - box_mouse_y)/box_mouse_x double angle = atan(temp); //find the angle with arctan //set the new tile the mouse is in if (angle > 0.7854) //if the angle is greater then 45 degrees { if (box_x % 2 == 1) //is it odd? { mouse_in_x = box_x -1; mouse_in_y = box_y; tile[mouse_in_x][mouse_in_y].bMouse_In = TRUE; } else //else if its even { mouse_in_x = box_x -1; mouse_in_y = box_y -1; tile[mouse_in_x][mouse_in_y].bMouse_In = TRUE; } } else if (angle < -0.7854) //if the angle is < -45 degrees { if (box_x % 2 == 1) //is it odd? { mouse_in_x = box_x -1; mouse_in_y = box_y +1; tile[mouse_in_x][mouse_in_y].bMouse_In = TRUE; } else //else if its even { mouse_in_x = box_x -1; mouse_in_y = box_y; tile[mouse_in_x][mouse_in_y].bMouse_In = TRUE; } } else { mouse_in_x = box_x; mouse_in_y = box_y; tile[mouse_in_x][mouse_in_y].bMouse_In = TRUE; } }}
I hope it helps
Edited by - Possibility on June 22, 2000 6:55:07 PM
Also for almost any size of tile and/or shape you cna do a simple point within a polygon test. Look around for how to test if a point is within a polygon... All tiles should be convex and less then 10 or 12 points/angles. So it should be fast... Just an idea.... The formula''s look better, but hey store this idea in your toolkit for some weird shaped tile someday...
See ya,
Ben
See ya,
Ben
Yah, my code can be altered for any size hex in about 3 seconds, and its Alot faster then the testing if a point is in a polygon. I saw that used in one of TANSTFALLS programs. Basically, my method is just like the mouse map method, it would be easier to show mine with some hand drawn paper. I have a picture, but I dont know how to show it here.
Possibility
Edited by - Possibility on June 22, 2000 9:51:17 PM
Possibility
Edited by - Possibility on June 22, 2000 9:51:17 PM
One of the things I got really hung up about over mouse maps was that the they were an image. After a few minutes I decided data is data and that mouse maps would do the trick. Using lookup tables has long been the standard for making things faster. The mouse map is just another lookup table - the only difference is that the data for the table is being read from a file instead of generated at run time. Lookup tables are the fastest. Even if you are working in multiple bit depths, there''s nothing that says your mouse map can''t be 8 bit or even 4 bit if you wanted to save space (but the operations would be slower). I spent a lot of time writing equations to do this stuff and have come to the conclusion that mouse maps are the fastest. Maybe I''m just not doing somethine that you are.
I am curious what that mouse map is. How can you use an image to calculate where the mouse is, you need to use a mathematical forumal dont you? And that math isnt to hard, it only took me 20 minutes to figure out my math forumal from scratch and then another 15 min to put it into code, it works extremely well and it is quick, and it also doesnt use up any memory (system or vidoe ram). The math should be hard to do, it only requires highschool level trigonometry and some algebra, and the hex map is more complex then the iso.
All you need to know where you mouse is on the screen, and then convert that point to the pixel point on the map, so now you know what pixel the mouse is on the map, now the hard part is determing what tile that pixel is in, but even that is not very complex.
Possibility
All you need to know where you mouse is on the screen, and then convert that point to the pixel point on the map, so now you know what pixel the mouse is on the map, now the hard part is determing what tile that pixel is in, but even that is not very complex.
Possibility
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement