我在弄清楚放置图 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 的顶部;换句话说,已经下降了三分之二。我们从上面看到ty
是 floor(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 = 2H
和O = H
是可能的参数;采用上述解决方案并替换 O
和L
会将结果减少到一个依赖项 H
.
关于javascript - 如何将像素坐标转换为等距网格坐标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18852333/