<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>how to convert pixel coords to tile coords for isometric slopes?</title>
		<link>http://www.allegro.cc/forums/view/616445</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Wed, 14 Sep 2016 09:56:18 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>If you have standard isometric tiles 64x32 pixels (or diamond 64x64 pixels)<br />with straight slopes:</p><p>How do you convert the x,y pixel coordinates to tile coordinates (0.0-1.0)<br />for the slopes for all 8 directions?<br />Assuming they all have the same elevation.</p><p>For flat tiles I know the equations are:<br />map.x = screen.x / TILE_WIDTH + screen.y / TILE_HEIGHT;<br />map.y = screen.y / TILE_HEIGHT - screen.x / TILE_WIDTH;</p><p>What about the slopes?</p><p>Can anyone help?</p><p>Cheers.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Pho75_)</author>
		<pubDate>Fri, 19 Aug 2016 06:32:57 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>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:
</p><pre>
0.............TILE_WIDTH
.      /`-_
.     /    `-_
.    /       /|
.   /   _   / |
.  / _-´ `-/  |
. /-´     / `-| 
.  `-_   / _-´
.     `-/-´
TILE_HEIGHT * 2
</pre><p>

So clearly:</p><p>screen.x = map.x * TILE_WIDTH / 2 - map.y * TILE_WIDTH / 2<br />screen.y = map.x * TILE_HEIGHT / 2 + map.y * TILE_HEIGHT / 2 - TILE_HEIGHT * (1 - map.y)</p><p>Now just solve for map.x and map.y:</p><p>1) screen.x * 2 / TILE_WIDTH = map.x - map.y<br />2) screen.y * 2 / TILE_HEIGHT = map.x + map.y - (2 - 2 * map.y) = map.x + 3 * map.y - 2<br />1-2) screen.x * 2 / TILE_WIDTH - screen.y * 2 / TILE_HEIGHT = - 4 * map.y + 2<br />Therefore:<br />map.y = screen.y / TILE_HEIGHT / 2 - screen.x / TILE_WIDTH / 2 + 0.5<br />map.x = screen.x * 1.5 / TILE_WIDTH + screen.y / TILE_HEIGHT / 2 + 0.5<br />(I probably did that wrong, it&#39;s late...)</p><p>The same works for the other 3 directions and for arbitrary slopes.</p><p>The 4 additional &quot;diagonal&quot; 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.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Elias)</author>
		<pubDate>Fri, 19 Aug 2016 10:05:51 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>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 &quot;Battle Isle&quot; had such a system.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ariesnl)</author>
		<pubDate>Fri, 19 Aug 2016 14:07:20 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/616445/1024491#target">Ariesnl</a> said:</div><div class="quote"><p>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 &quot;Battle Isle&quot; had such a system. </p></div></div><p>

Depends on the game. Most often for something like selecting units with the mouse you don&#39;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.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Elias)</author>
		<pubDate>Fri, 19 Aug 2016 17:11:37 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I think I get where you&#39;re going.<br />I haven&#39;t been able to solve this simultaneous equation though.<br />But thanks for the help, Elias.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Pho75_)</author>
		<pubDate>Thu, 25 Aug 2016 01:12:20 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I think you&#39;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.</p><p>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.</p><p><span class="remote-thumbnail"><span class="json">{"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"}</span><img src="http://www.allegro.cc//djungxnpq2nug.cloudfront.net/image/cache/b/b/bb3158e45a4dabe61c646d94a35ba7f9-240.jpg" alt="610536" width="240" height="218" /></span></p><p>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.</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">int</span> mapx <span class="k3">=</span> <span class="k2">(</span>tilex <span class="k3">*</span> TILE_WIDTH<span class="k2">)</span><span class="k3">/</span><span class="n">2</span><span class="k2">;</span>
<span class="k1">int</span> mapy <span class="k3">=</span> <span class="k2">(</span>tiley <span class="k3">*</span> TILE_HEIGHT<span class="k2">)</span><span class="k3">/</span><span class="n">2</span><span class="k2">;</span>
</pre></div></div><p>

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.</p><p><span class="remote-thumbnail"><span class="json">{"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"}</span><img src="http://www.allegro.cc//djungxnpq2nug.cloudfront.net/image/cache/9/8/9818c2559c390dc7dc591b7909196523-240.jpg" alt="610537" width="240" height="161" /></span></p><p>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 :
</p><div class="source-code snippet"><div class="inner"><pre>y <span class="k3">=</span> <span class="k2">(</span><span class="k2">(</span>y2 <span class="k3">-</span> y1<span class="k2">)</span><span class="k2">(</span>x2 <span class="k3">-</span> x1<span class="k2">)</span><span class="k2">)</span><span class="k3">*</span>x <span class="k3">+</span> b<span class="k2">;</span>
</pre></div></div><p>

This gives us 4 lines
</p><div class="source-code snippet"><div class="inner"><pre><span class="c">/// Line 1 [Y = -X + 1]</span>
<span class="c">/// Line 2 [Y = X - 1]</span>
<span class="c">/// Line 3 [Y = X + 1]</span>
<span class="c">/// Line 4 [Y = X + 3]</span>
</pre></div></div><p>

First, find the grid sector where the point falls. I&#39;ll call this tile quadrant x and y. Simply apply the inverse scale from above to go from map coordinates to tile space.</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">float</span> TileQuadrantX <span class="k3">=</span> <span class="k2">(</span><span class="k2">(</span><span class="k1">float</span><span class="k2">)</span>mapx<span class="k2">)</span><span class="k3">/</span><span class="k2">(</span>TILE_WIDTH<span class="k3">/</span><span class="n">2</span>.<span class="n">0f</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="k1">float</span> TileQuadrantY <span class="k3">=</span> <span class="k2">(</span><span class="k2">(</span><span class="k1">float</span><span class="k2">)</span>mapy<span class="k2">)</span><span class="k3">/</span><span class="k2">(</span>TILE_HEIGHT<span class="k3">/</span><span class="n">2</span>.<span class="n">0f</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>

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.
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">int</span> BaseTileX <span class="k3">=</span> <span class="k2">(</span><span class="k2">(</span><span class="k1">int</span><span class="k2">)</span>TileQuadrantX<span class="k2">)</span><span class="k3">/</span><span class="n">2</span><span class="k2">)</span><span class="k3">*</span><span class="n">2</span><span class="k2">;</span>
<span class="k1">int</span> BaseTileY <span class="k3">=</span> <span class="k2">(</span><span class="k2">(</span><span class="k1">int</span><span class="k2">)</span>TileQuadrantY<span class="k2">)</span><span class="k3">/</span><span class="n">2</span><span class="k2">)</span><span class="k3">*</span><span class="n">2</span><span class="k2">;</span>
</pre></div></div><p>

To test against our line pattern we need the tile quadrant position modulus 2.0 to find the position relative to our 2x2 space.
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">float</span> QuadrantX <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_332.html" target="_blank">fmod</a><span class="k2">(</span>TileQuadrantX , <span class="n">2</span>.<span class="n">0f</span><span class="k2">)</span><span class="k2">;</span>
<span class="k1">float</span> QuadrantY <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_332.html" target="_blank">fmod</a><span class="k2">(</span>TileQuadrantY , <span class="n">2</span>.<span class="n">0f</span><span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>

Next we test against the lines that divide our 2x2 space. This will give us the correct tile offset for our base tile position.
</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="k1">const</span> <span class="k1">float</span> QX <span class="k3">=</span> QuadrantX<span class="k2">;</span>
<span class="number">  2</span><span class="k1">const</span> <span class="k1">float</span> QY <span class="k3">=</span> QuadrantY<span class="k2">;</span>
<span class="number">  3</span><span class="c">/// Line 1 [QY = -QX + 1]</span>
<span class="number">  4</span><span class="k1">if</span> <span class="k2">(</span>QY <span class="k3">&gt;</span><span class="k3">=</span> <span class="k2">(</span><span class="k3">-</span>QX <span class="k3">+</span> <span class="n">1</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span><span class="c">/// line condition 1b</span>
<span class="number">  5</span>   BaseTileX <span class="k3">+</span><span class="k3">=</span> <span class="n">1</span><span class="k2">;</span>
<span class="number">  6</span>   BaseTileY <span class="k3">+</span><span class="k3">=</span> <span class="n">1</span><span class="k2">;</span>
<span class="number">  7</span>   <span class="c">/// Test against line 4 [QY = -QX + 3]</span>
<span class="number">  8</span>   <span class="k1">if</span> <span class="k2">(</span>QY <span class="k3">&gt;</span><span class="k3">=</span> <span class="k2">(</span><span class="k3">-</span>QX <span class="k3">+</span> <span class="n">3</span>.<span class="n">0</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span><span class="c">/// line condition 4b</span>
<span class="number">  9</span>      BaseTileX <span class="k3">+</span><span class="k3">=</span> <span class="n">1</span><span class="k2">;</span>
<span class="number"> 10</span>      BaseTileY <span class="k3">+</span><span class="k3">=</span> <span class="n">1</span><span class="k2">;</span>
<span class="number"> 11</span>   <span class="k2">}</span>
<span class="number"> 12</span>   <span class="k1">else</span> <span class="k2">{</span><span class="c">/// line condition 4a</span>
<span class="number"> 13</span>      <span class="c">/// Test against line 2 [QY = QX - 1] and line 3 [QY = QX + 1]</span>
<span class="number"> 14</span>      <span class="k1">if</span> <span class="k2">(</span>QY <span class="k3">&lt;</span> <span class="k2">(</span>QX <span class="k3">-</span> <span class="n">1</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span><span class="c">/// line condition 2a</span>
<span class="number"> 15</span>         BaseTileX <span class="k3">+</span><span class="k3">=</span> <span class="n">1</span><span class="k2">;</span>
<span class="number"> 16</span>         BaseTileY <span class="k3">-</span><span class="k3">=</span> <span class="n">1</span><span class="k2">;</span>
<span class="number"> 17</span>      <span class="k2">}</span>
<span class="number"> 18</span>      <span class="k1">else</span> <span class="k1">if</span> <span class="k2">(</span>QY <span class="k3">&gt;</span><span class="k3">=</span> <span class="k2">(</span>QX <span class="k3">+</span> <span class="n">1</span>.<span class="n">0f</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span><span class="c">/// line condition 3b</span>
<span class="number"> 19</span>         BaseTileX <span class="k3">-</span><span class="k3">=</span> <span class="n">1</span><span class="k2">;</span>
<span class="number"> 20</span>         BaseTileY <span class="k3">+</span><span class="k3">=</span> <span class="n">1</span><span class="k2">;</span>
<span class="number"> 21</span>      <span class="k2">}</span>
<span class="number"> 22</span>      <span class="k1">else</span> <span class="k2">{</span>
<span class="number"> 23</span>         <span class="c">/// We are in the center, already taken care of by case 1b</span>
<span class="number"> 24</span>      <span class="k2">}</span>
<span class="number"> 25</span>   <span class="k2">}</span>
<span class="number"> 26</span><span class="k2">}</span>
</div></div><p>

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.</p><p>However, despite all this, I may have misunderstood the question. If you&#39;re asking for fractional tile coordinates I&#39;m not sure I know how to do that. I think it&#39;s just a series of transformations though.</p><p><b>EDIT</b><br />I think I see what you&#39;re asking. To answer your questions, to get the 8 slopes, just use map coordinates for each tile. So to get from one tile to another, make a line from the two points in map coordinates. It will still travel the same direction.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Sun, 28 Aug 2016 01:20:17 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thanks Edgar for the detailed reply.<br />Elias solution proved to be correct, (although his math wasn&#39;t <img src="http://www.allegro.cc/forums/smileys/grin.gif" alt=";D" />). It even works for slopes with arbitrary elevation.<br />I was finally able to resolve the simultaneous equations for the N,S,E,W slopes.<br />I just need to do the 4 corners now.</p><p>Thanks.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Pho75_)</author>
		<pubDate>Mon, 29 Aug 2016 07:22:46 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>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&#39;t have to ask it again.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Mon, 29 Aug 2016 08:04:59 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>It gets you sub-tile accuracy.<br />So you can get the exact coordinates under the mouse cursor.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Pho75_)</author>
		<pubDate>Wed, 31 Aug 2016 09:10:27 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>And my question is, what do you use that for? Why not just use map coordinates? Do you really need fractional tile coordinates?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Thu, 01 Sep 2016 01:12:04 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>If I wanted my characters to only stand on the center of a tile, you&#39;d be right.<br />I&#39;d only need tile coordinates. But I don&#39;t want tile-locked movement, so I need sub-tile accuracy.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Pho75_)</author>
		<pubDate>Fri, 02 Sep 2016 04:51:39 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You&#39;re totally missing what I&#39;m getting at. What I&#39;m saying is why can&#39;t you simply track your game object&#39;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).
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Fri, 02 Sep 2016 05:06:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I do track my objects in map coordinates. I need to click on the screen to tell my character where to go.<br />if you have 3D there is no way to guarantee that 2 pixels next to each other on screen are indeed next to each other in actual coordinates.<br />If you&#39;re looking at a picture on screen, how can you tell if the pixel you&#39;re pointing at is close or off in the horizon. you can&#39;t unless you can convert x,y screen coords into world coordinates.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Pho75_)</author>
		<pubDate>Fri, 02 Sep 2016 12:00:22 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>This is the first time you mentioned 3D. I don&#39;t think you would need fractional tile coordinates if it was just a standard 2D isometric map though. I won&#39;t bug you any more about it.</p><p>Please do post the solution though, for future reference for other&#39;s sake.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Fri, 02 Sep 2016 21:47:58 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>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).</p><p><span class="remote-thumbnail"><span class="json">{"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"}</span><img src="http://www.allegro.cc//djungxnpq2nug.cloudfront.net/image/cache/a/3/a3043314ff5c121b96d07e5ad63cae05-240.jpg" alt="610546" width="240" height="48" /></span></p><p>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.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Neil Roy)</author>
		<pubDate>Sun, 04 Sep 2016 09:58:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I only used a 2 color mouse map: do determine if I&#39;m over the tile or not.<br />since I use a heightmap it&#39;s possible to have tiles behind each other.<br />So I can&#39;t predict all the intersection types.</p><p>I&#39;ll post the solution when i get it working. It&#39;s still broken since I only get to work on it in my spare time, and my math skills aren&#39;t that great.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Pho75_)</author>
		<pubDate>Sun, 04 Sep 2016 14:24:21 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Is this 2D or 3D?!  For 2D, the mouse map works.  You&#39;re very confusing as to what you are working on.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Neil Roy)</author>
		<pubDate>Tue, 06 Sep 2016 04:25:58 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>It&#39;s isometric 2.5D with heightmap support.<br />I did say that I&#39;m also using a mousemap. I&#39;m just not familiar with your multi-color technique.<br />My mouse-map only has 2 colors, for on or off.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Pho75_)</author>
		<pubDate>Thu, 08 Sep 2016 05:02:46 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Here&#39;s an excellent article that explains the mouse maps, and it has a terrain with varying heights etc...  check this out.</p><p><a href="http://archive.gamedev.net/archive/reference/programming/features/mm4ihm/index.html">http://archive.gamedev.net/archive/reference/programming/features/mm4ihm/index.html</a>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Neil Roy)</author>
		<pubDate>Wed, 14 Sep 2016 09:56:18 +0000</pubDate>
	</item>
</rss>
