javascript - 如何将像素坐标转换为等距网格坐标?

标签 javascript jquery math canvas

我在弄清楚放置图 block 的位置或找到图 block Angular 时没有遇到太多麻烦,但我无法弄清楚用于确定我悬停的像素属于哪个网格单元的数学/公式。我的网格运行如下:

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

y0,x0 为顶部/背面,并以 Canvas 的顶部边缘为中心。瓷砖的宽度是平时的两倍。我已经让偏移代码可以工作,这样我的鼠标像素坐标偏移就与我的图 block 相同,但我被难住了。

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

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

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

我用它来放置我的瓷砖。 S 是原点,其中始终放置 0y,0x,H 是图 block 像素高度,M 是 H/2。我需要的是与此相反的 getPixelTileCoord(pixelx,pixely);用于获取我悬停在哪个图 block 上。

最佳答案

初步观察

等距平铺网格只是一个规则的矩形网格,其 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

每个图 block 的边长为L px 和垂直于该边缘的高度是 H像素。每行的等距像素偏移将为 O像素。

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

(所有位置始终首先列出垂直组件。)

示例

例如。 1

如果你数一下,你会发现 t(0,0) 的 Angular 位于以下像素位置:

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

这四个点中的每一个也是其他图 block 的 Angular 。

例如。 2

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

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

一般情况

每增加一个单位tx (从 t(ty,tx)t(ty,tx+1) ), Angular 点的水平像素位置变化 L px .

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

概括来说,瓷砖的 Angular 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

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

像素到平铺

垂直位置

对于图 block 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 在底部。

位于图 block 顶部 t(ty,tx)和像素p(i,j) , (Y_MAX-ty)*O + tx*L <= j < (Y_MAX-ty)*O + (tx+1)*L .

在图 block 底部t(ty,tx)和像素p(i,j) , (Y_MAX-ty-1)*O + tx*L <= j < (Y_MAX-ty-1)*O + (tx+1)*L .

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

要了解我们在图 block 上的位置,我们可以使用 frac(i/H)i/H 的小数部分。例如,在 p(80,0) ,如果每个图 block 都有高度 H=30 ,我们将是frac(80/30) = 20 px相对于图 block 的顶部;换句话说,已经下降了三分之二。我们从上面看到tyfloor(i/H)实际上是 i/H 的整数部分。因此,ty+frac(i/H) = i/H .

<小时/>

因此,对于瓷砖 t(ty,tx)和像素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 = 2HO = H是可能的参数;采用上述解决方案并替换 OL会将结果减少到一个依赖项 H .

关于javascript - 如何将像素坐标转换为等距网格坐标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18852333/

相关文章:

javascript - CSS,JavaScript : random image loader with array removes the first part of my variable how to fix this?

javascript - jQuery:提取部分动态加载的 html

java - 如何用 Java 求解 ODE?

c++ - 通过 MPI 在集群中进行主成分分析

javascript - Jquery:如何将所有键盘输入动态重定向到文本框?

javascript - 通过 Javascript 计算数组中排列的计数而不重复

javascript - 根据像素宽度 chop 字符串

javascript - 异步回调不会被调用

javascript - 选项卡在 HTML CSS Javascript 中不起作用

javascript - 如何向 jquery 创建的元素添加数据?