将屏幕坐标转换为等距地图坐标
Converting screen coordinates to isometric map coordinates
我正在使用菱形图案生成等距图块地图:
tileWidth = 128;
tileHeight = 94;
for (var x = 0; x < rows; x++) {
for (var y = 0; y < cols; y++) {
var screenX = (x - y) * tileWidthHalf;
var screenY = (x + y) * tileHeightHalf;
drawTile(screenX, screenY);
}
}
渲染正确,但现在我无法将屏幕坐标(鼠标位置)转换回等距坐标。
我试过颠倒数学:
var x = _.floor(screenY / (tileWidth / 2) - (screenX / tileWidth / 2));
var y = _.floor(screenY / (tileHeight / 2) + (screenX / tileHeight / 2));
它对 0, 0
磁贴工作正常,但之后无法产生正确的值。
我只是无法想出正确的数学 - 我是不是遗漏了一些微不足道的东西,还是我对这个过程完全错了?
我不明白你是怎么想到这个解决方案的。您必须求解方程组,它给出以下解:
x = 0.5 * ( screenX / tileWidthHalf + screenY / tileHeightHalf)
y = 0.5 * (-screenX / tileWidthHalf + screenY / tileHeightHalf)
如果您需要图块索引,请按照您的代码使用 floor
。
我只能猜测您在坐标系中的图块对齐方式。但是从您在评论中发布的屏幕截图来看,我认为您需要将 screenX
与 (screenX - tileWidthHalf)
交换以获得准确的值。
我正在为你的tileWidth
写w
,为tileHeight
写h
。使用这个表示法,你基本上有
screenX = (x - y)*(w/2) = (w/2)*x + (-w/2)*y
screenY = (x + y)*(h/2) = (h/2)*x + (h/2)*y
这是一个线性变换,您也可以这样写成矩阵表示法:
⎛x⎞ ↦ ⎛w/2 -w/2⎞ ⎛x⎞
⎝y⎠ ⎝h/2 h/2⎠ ⎝y⎠
要反转操作,您需要将其反转。 2×2矩阵的逆矩阵有一个simple formula。交换左上角和右下角的条目。否定其他两个。将所有内容除以行列式。使用它,你就有了逆变换:
⎛x⎞ ↦ 2/ ⎛ h/2 w/2⎞ ⎛x⎞ = ⎛ 1/w 1/h⎞ ⎛x⎞
⎝y⎠ wh ⎝-h/2 w/2⎠ ⎝y⎠ ⎝-1/w 1/h⎠ ⎝y⎠
所以在你的符号中你得到
x = screenY / tileHeight + screenX / tileWidth
y = screenY / tileHeight - screenX / tileWidth
这基本上也是 Nico 写的。将非整数坐标转回整数取决于您为每个图块放置参考点的位置。
我正在使用菱形图案生成等距图块地图:
tileWidth = 128;
tileHeight = 94;
for (var x = 0; x < rows; x++) {
for (var y = 0; y < cols; y++) {
var screenX = (x - y) * tileWidthHalf;
var screenY = (x + y) * tileHeightHalf;
drawTile(screenX, screenY);
}
}
渲染正确,但现在我无法将屏幕坐标(鼠标位置)转换回等距坐标。
我试过颠倒数学:
var x = _.floor(screenY / (tileWidth / 2) - (screenX / tileWidth / 2));
var y = _.floor(screenY / (tileHeight / 2) + (screenX / tileHeight / 2));
它对 0, 0
磁贴工作正常,但之后无法产生正确的值。
我只是无法想出正确的数学 - 我是不是遗漏了一些微不足道的东西,还是我对这个过程完全错了?
我不明白你是怎么想到这个解决方案的。您必须求解方程组,它给出以下解:
x = 0.5 * ( screenX / tileWidthHalf + screenY / tileHeightHalf)
y = 0.5 * (-screenX / tileWidthHalf + screenY / tileHeightHalf)
如果您需要图块索引,请按照您的代码使用 floor
。
我只能猜测您在坐标系中的图块对齐方式。但是从您在评论中发布的屏幕截图来看,我认为您需要将 screenX
与 (screenX - tileWidthHalf)
交换以获得准确的值。
我正在为你的tileWidth
写w
,为tileHeight
写h
。使用这个表示法,你基本上有
screenX = (x - y)*(w/2) = (w/2)*x + (-w/2)*y
screenY = (x + y)*(h/2) = (h/2)*x + (h/2)*y
这是一个线性变换,您也可以这样写成矩阵表示法:
⎛x⎞ ↦ ⎛w/2 -w/2⎞ ⎛x⎞
⎝y⎠ ⎝h/2 h/2⎠ ⎝y⎠
要反转操作,您需要将其反转。 2×2矩阵的逆矩阵有一个simple formula。交换左上角和右下角的条目。否定其他两个。将所有内容除以行列式。使用它,你就有了逆变换:
⎛x⎞ ↦ 2/ ⎛ h/2 w/2⎞ ⎛x⎞ = ⎛ 1/w 1/h⎞ ⎛x⎞
⎝y⎠ wh ⎝-h/2 w/2⎠ ⎝y⎠ ⎝-1/w 1/h⎠ ⎝y⎠
所以在你的符号中你得到
x = screenY / tileHeight + screenX / tileWidth
y = screenY / tileHeight - screenX / tileWidth
这基本上也是 Nico 写的。将非整数坐标转回整数取决于您为每个图块放置参考点的位置。