Reputation: 183
I didn't have too much trouble figuring out where to place my tiles or finding the tile corners, but I can't figure out the math/formula for determining what grid unit the pixel I'm hovering over belongs to. My grid runs like this:
y0,x0|y0,x1|y0,x2
y1,x0|y1,x1|y1,x2
y2,x0|y2,x1|y2,x2
With y0,x0 being the top/back and centered against the top edge of the canvas. Tiles are twice as wide as long as usual. I have gotten the offset code to work, so that my mouse pixel coordinate offsets are the same as my tiles, but I'm stumped.
Edit: Sorry for the confusing question. All-night code session fatigue.
I have this function (simplified here):
getTilePixelCoord(x,y)
{
p.x = S-yH+xH;
p.y = yM+xM;
return p;
}
That I use to place my tiles. S is the origin point, where 0y,0x is always placed, H is tile pixel height, and M is H/2. What I need is the opposite of this, a getPixelTileCoord(pixelx,pixely); for getting which tile I'm hovering on.
Upvotes: 1
Views: 1793
Reputation: 3787
The isometric tile grid just a regular rectangular grid with the x-coordinate shifted, depending on how many rows there are.
Rectangular Grid (y,x)
v length (L)
+_____+xxxxx+xxxxx+
x x x x
No offset>+xxxxx+xxxxx+xxxxx+
x x x x
+xx|xx+xxxxx+xxxxx+
x | x x x
+xx|xx+xxxxx+xxxxx+
^ height (H)
+: corners
Each tile's length edge is L
px and height perpendicular to that edge is H
px. The isometric pixel offset per row will be O
px.
Isometric Grid (y,x)
V length (L) is the same as above
height ......+_____+xxxxx+xxxxx+
dependent >_____x 0,0 x x x
offset ....+xxxxx+xxxxx+xxxxx+
(O) ...x x x 1,2 x
..+x|xxx+xxxxx+xxxxx+
.x | x x x
+xxx|x+xxxxx+xxxxx+
^ height (H) is the same as above
+: corners
t(ty,tx)
refers to the tile vertically located at ty
and horizontally located at tx
p(i,j)
refers to the pixel location (in pixels)MAX_Y
refers to the number of tile rows(All locations are always listed with the vertical component first.)
If you count, you'll notice that the corners of t(0,0)
are located at the following pixel locations:
p(0, 3O)
: top leftp(H, 2O)
: bottom leftp(0, 3O+L)
: top rightp(H, 2O+L)
: bottom rightEach of these four points are corners of other tiles as well.
We can see t(1,2)
as another example. Their corners are at the following pixel locations:
p(H, 2O+2L)
: top leftp(2H, O+2L)
: bottom leftp(H, 2O+3L)
: top rightp(2H, O+3L)
: bottom rightFor each unit increase in tx
(from t(ty,tx)
to t(ty,tx+1)
), the horizontal pixel location of the corners changes by L px
.
For each unit increase in ty
(from t(ty,tx)
to t(ty+1,tx)
), the horizontal pixel location of the corners changes by -O px
and the vertical pixel location of the corners changes by H px
.
To generalize, the corners of tile t(ty,tx)
(where the number of rows is Y_MAX
, so for our example, Y_MAX = 3
) are at the following pixel locations:
p( ty*H, (Y_MAX-ty)*O + tx*L) - top left
p((ty+1)*H, (Y_MAX-ty-1)*O + tx*L) - bottom left
p( ty*H, (Y_MAX-ty)*O + (tx+1)*L) - top right
p((ty+1)*H, (Y_MAX-ty-1)*O + (tx+1)*L) - bottom right
You can plug in the above examples to show that these are the correct locations.
For a tile t(ty,tx)
and p(i,j)
, ty*H <= i < (ty+1)*H
.
ty*H <= i < (ty+1)*H
ty <= i/H < ty+1
ty = floor(i/H)
Thus, ty = floor(i/H)
.
The horizontal location is a little more complex because the offset, and thus the horizontal location, depends on the vertical location of the pixel. We can see that the offset starts at O*Y_MAX px
at the top and decreases linearly to 0
px at the bottom.
At the top of tile t(ty,tx)
and pixel p(i,j)
, (Y_MAX-ty)*O + tx*L <= j < (Y_MAX-ty)*O + (tx+1)*L
.
At the bottom of tile t(ty,tx)
and pixel p(i,j)
, (Y_MAX-ty-1)*O + tx*L <= j < (Y_MAX-ty-1)*O + (tx+1)*L
.
The difference between the two is linear, totaling O px
.
To find out far we are down the tile, we can use frac(i/H)
, the fractional part of i/H
. For example, at p(80,0)
, if each tile has a height H=30
, we would be frac(80/30) = 20 px
relative to the top of the tile; in other words, two-thirds of the way down. We see from above that ty
is floor(i/H)
is actually the integer part of i/H
. Thus, ty+frac(i/H) = i/H
.
Thus, for tile t(ty,tx)
and pixel p(i,j)
, (Y_MAX-i/H)*O + tx*L < j < (Y_MAX-i/H)*O + (tx+1)*L
(Y_MAX-i/H)*O + tx*L <= j < (Y_MAX-i/H)*O + (tx+1)*L
tx*L <= j-((Y_MAX-i/H)*O) < (tx+1)*L
tx <= (j-((Y_MAX-i/H)*O))/L < tx+1
tx = floor((j-((Y_MAX-i/H)*O))/L)
Thus, tx = floor((j-((Y_MAX-i/H)*O))/L)
.
For any point p(i,j)
, the tile t(ty,tx)
is at t(floor(i/H),floor((j-((Y_MAX-i/H)*O))/L))
.
For your purposes, L = 2H
and O = H
are likely parameters; taking the above solution and replacing O
and L
would reduce the result down to one dependency H
.
Upvotes: 1