【问题标题】:How do I convert pixel coordinates to isometric grid coordinates?如何将像素坐标转换为等距网格坐标?
【发布时间】:2013-09-22 00:55:06
【问题描述】:

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

        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);用于获取我悬停在哪个图块上。

【问题讨论】:

  • “我很难过”

标签: javascript jquery math canvas


【解决方案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开始,线性减小到底部的0px。

平铺顶部t(ty,tx) 和像素p(i,j)(Y_MAX-ty)*O + tx*L &lt;= j &lt; (Y_MAX-ty)*O + (tx+1)*L

在平铺t(ty,tx) 和像素p(i,j)(Y_MAX-ty-1)*O + tx*L &lt;= j &lt; (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;换句话说,下降了三分之二。我们从上面看到tyfloor(i/H) 实际上是i/H 的整数部分。因此,ty+frac(i/H) = i/H


因此,对于图块t(ty,tx) 和像素p(i,j)(Y_MAX-i/H)*O + tx*L &lt; j &lt; (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 = 2HO = H 可能是参数;采用上述解决方案并替换 OL 会将结果减少到一个依赖项 H

【讨论】:

  • 对不起,我知道我的帖子不清楚;我真的很难理解其中的数学。我有这个功能(假的):
  • 抱歉,我掌握了这个系统的窍门。请参阅已编辑问题中的功能。这些解决方案是像素到网格还是网格到像素?
  • @DanieClawson:这是像素到网格。我将编辑我的帖子以使其更清晰。
  • @DanieClawson:告诉我你的想法!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 2020-07-05
  • 2013-08-08
  • 2013-12-16
  • 1970-01-01
相关资源
最近更新 更多