1

我在确定放置瓷砖或找到瓷砖角的位置没有太多麻烦,但我无法弄清楚用于确定我悬停的像素属于哪个网格单元的数学/公式。我的网格是这样运行的:

        y0,x0|y0,x1|y0,x2
     y1,x0|y1,x1|y1,x2
  y2,x0|y2,x1|y2,x2

y0,x0 是顶部/后部,并以画布的顶部边缘为中心。瓷砖的宽度是平时的两倍。我已经得到了偏移代码,所以我的鼠标像素坐标偏移与我的瓷砖相同,但我很难过。

编辑:抱歉这个令人困惑的问题。通宵编码会话疲劳。

我有这个功能(在这里简化):

getTilePixelCoord(x,y)
{
    p.x = S-yH+xH;
    p.y = yM+xM;
    return p;
}

我用来放置瓷砖的。S 是原点,0y,0x 总是放在这里,H 是瓦片像素高度,M 是 H/2。我需要的是与此相反的 getPixelTileCoord(pixelx,pixely); 获取我悬停在哪个图块上。

4

1 回答 1

1

初步观察

等距平铺网格只是一个规则的矩形网格,x 坐标移动,具体取决于有多少行。

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

每个图块的长度边是Lpx,垂直于该边的高度是Hpx。每行的等距像素偏移量为Opx。

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)指垂直位于ty和水平位于tx
  • p(i,j)指像素位置(以像素为单位)
  • MAX_Y指瓦片行数

(所有位置总是首先列出垂直分量。)

例子

前任。1

如果您数数,您会注意到 的角t(0,0)位于以下像素位置:

  • p(0, 3O): 左上方
  • p(H, 2O): 左下方
  • p(0, 3O+L): 右上
  • p(H, 2O+L): 右下角

这四个点中的每一个也是其他图块的角。

前任。2

我们可以看到t(1,2)另一个例子。它们的角位于以下像素位置:

  • p(H, 2O+2L): 左上方
  • p(2H, O+2L): 左下方
  • p(H, 2O+3L): 右上
  • p(2H, O+3L): 右下角

一般情况

每增加一个单位tx(从t(ty,tx)t(ty,tx+1)),角的水平像素位置就会改变L px.

每增加一个单位ty(从t(ty,tx)t(ty+1,tx)),角的水平像素位置变化 ,角-O px的垂直像素位置变化H px

概括地说,瓦片的角t(ty,tx)(其中行数为Y_MAX,因此对于我们的示例,Y_MAX = 3)位于以下像素位置:

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

您可以插入上面的示例以显示这些是正确的位置。

像素到平铺

垂直位置

对于瓷砖t(ty,tx)p(i,j), ty*H <= i < (ty+1)*H

ty*H <= i   < (ty+1)*H
ty   <= i/H < ty+1
ty = floor(i/H)

因此,ty = floor(i/H).

水平位置

水平位置稍微复杂一些,因为偏移量以及水平位置取决于像素的垂直位置。我们可以看到偏移量从O*Y_MAX px顶部开始并线性减小0到底部的 px。

在 tilet(ty,tx)和 pixel的顶部p(i,j)(Y_MAX-ty)*O + tx*L <= j < (Y_MAX-ty)*O + (tx+1)*L.

在 tilet(ty,tx)和 pixel的底部p(i,j)(Y_MAX-ty-1)*O + tx*L <= j < (Y_MAX-ty-1)*O + (tx+1)*L.

两者之间的差异是线性的,总计O px

要找出我们在瓷砖上的距离,我们可以使用frac(i/H)的小数部分i/H。例如,在 处p(80,0),如果每个瓦片都有一个高度H=30,我们将frac(80/30) = 20 px相对于瓦片的顶部;换句话说,下降了三分之二。我们从上面看到ty实际上floor(i/H)是 的整数部分i/H。因此,ty+frac(i/H) = i/H.


因此,对于 tilet(ty,tx)和 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)

因此,tx = floor((j-((Y_MAX-i/H)*O))/L).

解决方案

对于任何一点p(i,j),瓷砖t(ty,tx)都在t(floor(i/H),floor((j-((Y_MAX-i/H)*O))/L))

您的具体案例

出于您的目的,L = 2H可能O = H是参数;采用上述解决方案并替换O并将L结果减少到一个依赖项H

于 2013-09-17T20:07:15.600 回答