Archived

This topic is now archived and is closed to further replies.

krez

rotating a hexagonal grid...

Recommended Posts

i have a hexagonal grid as follows:
    <10><20><30>
  <11><21><31><41>
<02><12><22><32><42>
  <13><23><33><43>
    <14><24><34>
 
it is stored in a 2-dimensional array... the 2 digits in each hex above are the array''s indices (ie first hex is in GRID(1,0), last hex is in GRID(3,4))... i want to allow the player to rotate the map (by 60 degrees) so any one of the six sides can be "up" on the screen... i hope to accomplish this by keeping another 2D-array whose indices are the coordinates on the screen, that reference the correct element in the original array:
rotated 180:           rotated 60 (CW):
    <34><24><14>           <42><43><34>
  <43><33><23><13>       <41><32><33><24>
<42><32><22><12><02>   <30><21><22><23><14>
  <41><31><21><11>       <20><21><12><13>
    <30><20><10>           <10><11><02>
 
in the above diagram, the array indices are the same as in the first diagram, and the data in the array points to the tiles in the original GRID... the two digits in _these_ hexes are the array indices of the original grid it is pointing to. i would just hard code these in, but the problem is the maps are different sizes, and some are quite large... so i need a way to do it algorithmically (is that a word?)... i am currently hacking out something ugly to do this, but i think (hope) there might be a faster/nicer/sweeter way of doing it... so if anyone has any ideas please post them. oh, and please don''t tell me to use D3D or that this method sucks... obviously i don''t want to waste all my work so far and start over with the whole hex-tile engine ;: heh heh i just read this over and i''m not sure if it will make sense to anyone except me ... well, if you have any questions about what i just wrote please ask me to clarify, rather than just leaving me hanging... this is really driving me mad! thanks in advance! --- krez (krezisback@aol.com)

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I''ve been tinkering with this too. So far paper only, but here is what I was thinking.

First, I''m using a three axis system. Each axis (x, y, z) corresponds to one 60 degree direction (each axis is normal to a pair of hex sides). Since the three axes are all in a plane, x+y+z = 0 for all hexes on the map.

Since the hexes are stored in a 2d array, I have a function to convert from the (x,y,z) set to the array dimensions (a,b). One of the axes corresponds exactly, the other is a quick addition (I think).

The other thing to do is handle the rotation. Since the rotation is 60 degree interals and the axes are 60 degree intervals, it''s just a matter of lining up the screen axes with the hex axes. I''m thinking about storing two vectors in hex coords. One that represents an increment in the screenX direction and one that represetns an increment in the screenY direction.

The drawing loop goes from one screen location to the next, and the increment is converted to a hex coord vector (x,y,z), which is added to the current hex coordinate. This then calls the appropriate array
Make sense? ' Target=_Blank>Link

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Dang ubb code!

I''ve repeated the last paragraph and the rest which got mangled by the ubb code in my post.

The drawing loop goes from one screen location to the next, and the increment is converted to a hex coord vector (x,y,z), which is added to the current hex coordinate. This then calls the appropriate array (a, b) and returns the correct tile.

Rotation simply means changing the vectors that convert screenX and screenY to hex coords.

My hexes are also turned 90 degrees from yours (pointy bits at the top and bottom instead of the sides), but I don''t think that makes a big diff.

Make sense?

Share this post


Link to post
Share on other sites
quote:
First, I'm using a three axis system. Each axis (x, y, z) corresponds to one 60 degree direction (each axis is normal to a pair of hex sides). Since the three axes are all in a plane, x+y+z = 0 for all hexes on the map.Since the hexes are stored in a 2d array, I have a function to convert from the (x,y,z) set to the array dimensions (a,b). One of the axes corresponds exactly, the other is a quick addition (I think).

this sounds like a good idea, but could you explain it a bit better? for example, how would that conversion function work with a 2D array?
quote:
The other thing to do is handle the rotation. Since the rotation is 60 degree interals and the axes are 60 degree intervals, it's just a matter of lining up the screen axes with the hex axes. I'm thinking about storing two vectors in hex coords. One that represents an increment in the screenX direction and one that represetns an increment in the screenY direction. The drawing loop goes from one screen location to the next, and the increment is converted to a hex coord vector (x,y,z), which is added to the current hex coordinate. This then calls the appropriate array (a,b) and returns the correct tile.

ah you are clever
quote:
My hexes are also turned 90 degrees from yours (pointy bits at the top and bottom instead of the sides), but I don't think that makes a big diff.

actually, mine are also, but i wasn't thinking when i typed those diagrams out...
thanks a LOT, i never would have thought of this approach... i will start toying with this...

--- krez (krezisback@aol.com)

Edited by - krez on October 19, 2001 8:32:54 PM

Share this post


Link to post
Share on other sites
I've found that for this type of scenario (a hex map that makes a hexagonally shaped map), the best coordinate system to use is the slide coordinate system.

x should move from any one corner to the opposite corner. the y direction should be one face turn to the right of the x axis (so, if your x axis increases the the "east" then the y axis increases to the "southeast", ignoring north and south for the hex map since movement in that direction is not allowed)

as long as you have the same number of tiles on each edge of the map (in your example, you had 3, but i imagine you are actually using much larger maps), you will always have an odd number of tiles when counting from one corner to the opposite corner. for 3 tiles per edge, you have 5, for 4 tiles you have 7, and so on. this follows the equation n*2-1, where n is the number of tiles on an edge of the map. if you use the coordinate system i stated earlier, the center tile of the map will always be (n-1,n-1), where n is again the number of tiles on an edge, so for a 3 tile per edge map, the center is (2,2), for 4 tiles per edge is it (3,3) and so on.

moving between tiles has a completely regular pattern (unlike the staggered coordinates you were using)

(assuming a start at the leftmost corner of the map)
NE: (+1,-1)
E: (+1,+0)
SE: (+0,+1)
SW: (-1,+1)
W: (-1,+0)
NW: (+0,-1)

when you rotate the coordinate system, the deltas move up one, like so:
NE: (+1,+0)
E: (+0,+1)
SE: (-1,+1)
SW: (-1,+0)
W: (+0,-1)
NW: (+1,-1)
this works for x moving in the NE direction, and Y moving in the W direction

since we know that the center tile is (n-1,n-1), we know that we must move n-1 steps negative on the x axis using the deltas above. the negative x axis delta is always (-1,0), we can figure out what the xy position at the start of the x axis is.

(n-1,n-1) + (n-1)*(-1,+0)=
(n-1,n-1) + (-n+1,0)=
(n-1-n+1,n-1+0)=
(0,n-1)

for each of the corners, these are the coordinates (again, based on n and starting in the leftmost corner)

NE: (2*n-2,0)
E: (2*n-2,n-1)
SE: (n-1,2*n-2)
SW: (0,2*n-2)
W: (0,n-1)
NW: (n-1,0)

for the 3 tile per edge map, these work out to be:
NE: (4,0)
E: (4,2)
SE: (2,4)
SW: (0,4)
W: (0,2)
NW: (2,0)

Since the maximum coordinate is 4, we can store this in a 5x5 array (or other similar container). for n tiles per edge, we can use a (2*n-1)x(2*n-1). some of the positions will not be used. this is what the rectangular grid will look like:

XX000
X0000
00000
0000X
000XX

0 means that the location is used, X means it is unused

the number of unused squares will be (n*n-n). for 3 tiles per edge, it will be 6 as shown above. for 4 it will be 12, and so on. with larger maps, this is a lot of wasted space, but as n approaches infinity, the number of wasted squares only approaches 25% of the total number of squares, so it's not THAT much of a waste(percentage wise).

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Ah. TANSTAAFL is right, I was wrong. It''s easier to use axes pointed at the corners than at the faces.

I was in a mood, so I did a hefty write-up of the whole thing. It''s located here

Comments welcome, and the GameDev staff is free to archive a copy on this site if they like it.

Share this post


Link to post
Share on other sites