应用数学计算锯齿状等距正方形的面积

时间:2019-03-13 14:43:13

标签: isometric orthogonal

我正在制作一个等距游戏,我希望能够通过鼠标位置确定所选的图块。

在使用常规图块之前,我已经完成了此操作,但是等距图要复杂得多。尽管我的代码看起来并不愉快,但我之前对此进行了许多尝试,并且取得了一定程度的成功。而且我想,任何看到该代码的人都会以为自己只是在“挥舞它”或“强行施加它”。

我以前的尝试看起来像这样。

    public static Vector2 ToIsometric( int x , int y )
    {
        float selectedTileX = ( y * 32.0f ) + ( x * 16.0f );
        float selectedTileY = ( y * 16.0f / 2 ) - ( x * 16.0f / 2 );

        return new Vector2 ( selectedTileX , selectedTileY );
    }

其中X和Y表示鼠标在屏幕上的位置。 16.0f表示每个图块的高度,32.0f表示每个图块的宽度。下图不使用这些值,但希望能帮助解释我确定鼠标悬停的锯齿状等距图块的索引的目标。

enter image description here

1 个答案:

答案 0 :(得分:0)

问了这个问题已经有很长时间了,但是没有得到回答。因此,我将尝试为它提供一个可能的解决方案。

  

我知道您没有使用JavaScript,但是在这种情况下,您的问题与进行该计算所需的数学有关,并且由于SO提供了很好的JavaScript代码段,因此该语言非常适合查看计算结果。

检查此代码段,它是一个基本的图块网格,并且根据鼠标坐标选择了图块(我将使用此代码段作为基础向您展示最终计算结果):

const floor = Math.floor;
const divs = document.querySelectorAll('.container div');
const tileSize = 40;

const tiles = Array.prototype.reduce.call(divs, (a, t, i) => {
  const ai = floor(i / 3);
  return ((a[ai] = a[ai] || []), (a[ai][i % 3] = t), a);
}, []);

const unselect = () => divs.forEach(d => d.style.background = '');
const select = (r, c) => tiles[r] && tiles[r][c] && (tiles[r][c].style.background = 'red');

document.addEventListener('mousemove', (e) => {  
  const row = floor(e.pageY / tileSize);
  const col = floor(e.pageX / tileSize);
  unselect();
  select(row, col);  
});
body {
  margin: 0;
  padding: 0;
}

.container {
  border: 1px solid black;
  display: flex;
  flex-wrap: wrap;
  height: 120px;
  width: 120px;
}

.container * {
  background: white;
  border: 1px solid black;
  box-sizing: border-box;
  height: 40px;
  width: 40px;
}
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

在开始计算之前,请看一下我前一段时间写的this post,这样您就可以检查等距投影中涉及的所有数学。如您所见,在等轴测投影中,将a作为投影前图块的宽度和高度,等轴测图块的宽度等于√3 * a,而高度等于{{ 1}}。

首先,让我们尝试做与您想做的相反的事情:给出一个等距点,让我们尝试将其转换为实点上的ax坐标屏幕。看看下一张图片:

isometric projection

可以保证以下几点:

  1. 在等轴测坐标(yIx)中,点Iy 并且点a{1, 1}在屏幕上具有相同的b{2, 2}位置。因此,在yIx相等的情况下,屏幕上的Iy坐标保持不变。
  2. y坐标减小Ix坐标,而y坐标增大。
  3. Iy的{​​{1}}位置是点x的{​​{1}}位置的两倍。
  4. b{2, 2}x坐标始终会增加a{1, 1}坐标。

因此,利用所有这些信息,让我们尝试创建一个从IxIy的转换公式:

x

因此,以该公式为起点,我们可以尝试根据{Ix, Iy}{x, y}坐标计算等距坐标(x = (Ix + Iy) * √3 / 2 y = (Ix - Iy) / 2 Ix):

Iy

另一方面:

x

所以,可以说:

y

因此,让我们使用相同的基本代码片段实时查看这些计算,但是这次是等轴测模式下的图块:

  

在下一个代码段中,等轴测坐标在x = (Ix + Iy) * √3 / 2 2 * x = (Ix + Iy) * √3 2 * x / √3 = Ix + Iy Ix = 2 * x / √3 - Iy 坐标中向下移动y = (Ix - Iy) / 2 2 * y = Ix - Iy Iy = Ix - 2 * y ,以使整个图形在屏幕上可见,因此,需要从结果中减去该数量。

Ix = 2 * x / √3 - Iy
Ix = 2 * x / √3 - (Ix - 2 * y)
Ix = 2 * x / √3 - Ix + 2 * y
2 * Ix = 2 * x / √3 + 2 * y
Ix = x / √3 + y
60px
y