|
|
| how to convert pixel coords to tile coords for isometric slopes? |
|
Pho75_
Member #12,377
November 2010
|
If you have standard isometric tiles 64x32 pixels (or diamond 64x64 pixels) How do you convert the x,y pixel coordinates to tile coordinates (0.0-1.0) For flat tiles I know the equations are: What about the slopes? Can anyone help? Cheers. |
|
Elias
Member #358
May 2000
|
I would first do the other direction, go from tile to pixel coordinates. Without loss of generality, I chose the direction sloping towards the upper right edge and made it be as high as the tile: 0.............TILE_WIDTH . /`-_ . / `-_ . / /| . / _ / | . / _-´ `-/ | . /-´ / `-| . `-_ / _-´ . `-/-´ TILE_HEIGHT * 2 So clearly: screen.x = map.x * TILE_WIDTH / 2 - map.y * TILE_WIDTH / 2 Now just solve for map.x and map.y: 1) screen.x * 2 / TILE_WIDTH = map.x - map.y The same works for the other 3 directions and for arbitrary slopes. The 4 additional "diagonal" directions depend on how exactly you have them, but probably you split your tile into two triangles where one triangle is just flat and the other slopes towards one corner. -- |
|
Ariesnl
Member #2,902
November 2002
|
I saw a game once where the mouse controlled a tile shaped curser that would always snap to a tile. The cursor would just move according to the mouse mickeys (Dx,Dy).This made selecting something very easy to implement. I thought "Battle Isle" had such a system. Perhaps one day we will find that the human factor is more complicated than space and time (Jean luc Picard) |
|
Elias
Member #358
May 2000
|
Ariesnl said: I saw a game once where the mouse controlled a tile shaped curser that would always snap to a tile. The cursor would just move according to the mouse mickeys (Dx,Dy).This made selecting something very easy to implement. I thought "Battle Isle" had such a system. Depends on the game. Most often for something like selecting units with the mouse you don't really want the tile but the unit itself. E.g. if the head sticks out on top of the tile above and you click that head - it still should select the unit and not the tile. -- |
|
Pho75_
Member #12,377
November 2010
|
I think I get where you're going. |
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
I think you're making it more complicated than it needs to be. If you do it a certain way, all you need to do is apply a scale to each dimension and apply some inequalities. This figure shows the map coordinates in tile units. You can see that the tile units are just a grid of x,y values, with x increasing to the right and y increasing downwards with 0,0 in the upper left corner. This is the same coordinate system Allegro uses. {"name":"610536","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/b\/bb3158e45a4dabe61c646d94a35ba7f9.png","w":600,"h":545,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/b\/bb3158e45a4dabe61c646d94a35ba7f9"} To convert from tile units to map units all you need to do is apply the scale, which is the width and height of the tiles over 2. int mapx = (tilex * TILE_WIDTH)/2; int mapy = (tiley * TILE_HEIGHT)/2; To convert from map coordinates into whole tile coordinates, you can apply a series of transformations and inequalities. Basically, you test whether or not the point falls on a certain side of a specific line in tile space. {"name":"610537","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/8\/9818c2559c390dc7dc591b7909196523.png","w":1024,"h":689,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/8\/9818c2559c390dc7dc591b7909196523"} In the figure above, there are 4 lines to test against, numbered one through four, with the corresponding condition indicated by a or b depending on which side of the line it falls. To find the equations of the lines, use the point slope intercept formula : y = ((y2 - y1)(x2 - x1))*x + b; This gives us 4 lines /// Line 1 [Y = -X + 1] /// Line 2 [Y = X - 1] /// Line 3 [Y = X + 1] /// Line 4 [Y = X + 3] First, find the grid sector where the point falls. I'll call this tile quadrant x and y. Simply apply the inverse scale from above to go from map coordinates to tile space. float TileQuadrantX = ((float)mapx)/(TILE_WIDTH/2.0f)); float TileQuadrantY = ((float)mapy)/(TILE_HEIGHT/2.0f)); Next we want the base tile x and y to the nearest multiple of 2. Integer division works perfect for this. The reason is that we will be testing against a 2x2 space in the next step. int BaseTileX = ((int)TileQuadrantX)/2)*2; int BaseTileY = ((int)TileQuadrantY)/2)*2; To test against our line pattern we need the tile quadrant position modulus 2.0 to find the position relative to our 2x2 space. Next we test against the lines that divide our 2x2 space. This will give us the correct tile offset for our base tile position. 1const float QX = QuadrantX;
2const float QY = QuadrantY;
3/// Line 1 [QY = -QX + 1]
4if (QY >= (-QX + 1)) {/// line condition 1b
5 BaseTileX += 1;
6 BaseTileY += 1;
7 /// Test against line 4 [QY = -QX + 3]
8 if (QY >= (-QX + 3.0)) {/// line condition 4b
9 BaseTileX += 1;
10 BaseTileY += 1;
11 }
12 else {/// line condition 4a
13 /// Test against line 2 [QY = QX - 1] and line 3 [QY = QX + 1]
14 if (QY < (QX - 1)) {/// line condition 2a
15 BaseTileX += 1;
16 BaseTileY -= 1;
17 }
18 else if (QY >= (QX + 1.0f)) {/// line condition 3b
19 BaseTileX -= 1;
20 BaseTileY += 1;
21 }
22 else {
23 /// We are in the center, already taken care of by case 1b
24 }
25 }
26}
Now we have our tile coordinates from our map coordinates. I suggest making two functions to convert from map to tile and tile to map coordinates. However, despite all this, I may have misunderstood the question. If you're asking for fractional tile coordinates I'm not sure I know how to do that. I think it's just a series of transformations though. EDIT My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|
Pho75_
Member #12,377
November 2010
|
Thanks Edgar for the detailed reply. Thanks. |
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Just a question, why do you need fractional tile coordinates? What does that get you? And if you solved it, you should provide the solutions so people asking the same question in the future get to see the answer and don't have to ask it again. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|
Pho75_
Member #12,377
November 2010
|
It gets you sub-tile accuracy. |
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
And my question is, what do you use that for? Why not just use map coordinates? Do you really need fractional tile coordinates? My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|
Pho75_
Member #12,377
November 2010
|
If I wanted my characters to only stand on the center of a tile, you'd be right. |
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
You're totally missing what I'm getting at. What I'm saying is why can't you simply track your game object's coordinates in map coordinates (pixels?). You can convert map coords to whole number tile coords any time you need to. And you can more easily track offsets in pixels than you can in floating point tile coordinates (which you have to convert back to map coordinates (pixels) to draw them anyway). My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|
Pho75_
Member #12,377
November 2010
|
I do track my objects in map coordinates. I need to click on the screen to tell my character where to go. |
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
This is the first time you mentioned 3D. I don't think you would need fractional tile coordinates if it was just a standard 2D isometric map though. I won't bug you any more about it. Please do post the solution though, for future reference for other's sake. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|
Neil Roy
Member #2,229
April 2002
|
I use a mouse map for the various tile types. The white areas in this map are the tile, the coloured areas are the different sides off of it. When you click on a tile, you check where you clicked against the matching tile map to see where you clicked, or if you clicked on a neighbouring tile etc. Simple to implement (at least I think this is what you are talking about). {"name":"610546","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/3\/a3043314ff5c121b96d07e5ad63cae05.png","w":640,"h":128,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/3\/a3043314ff5c121b96d07e5ad63cae05"} And I agree with Edgar, please share any solutions you came up with as this is a subject I would like to know how others solve these problems as well. --- |
|
Pho75_
Member #12,377
November 2010
|
I only used a 2 color mouse map: do determine if I'm over the tile or not. I'll post the solution when i get it working. It's still broken since I only get to work on it in my spare time, and my math skills aren't that great. |
|
Neil Roy
Member #2,229
April 2002
|
Is this 2D or 3D?! For 2D, the mouse map works. You're very confusing as to what you are working on. --- |
|
Pho75_
Member #12,377
November 2010
|
It's isometric 2.5D with heightmap support. |
|
Neil Roy
Member #2,229
April 2002
|
Here's an excellent article that explains the mouse maps, and it has a terrain with varying heights etc... check this out. http://archive.gamedev.net/archive/reference/programming/features/mm4ihm/index.html --- |
|
|