斜投影

我这两天在研究diablo那样的投影方式。

菱形的2个角一般是30度、120度。但是由于tan(30度)=sqrt(3)/3 约等于0.58,是一个无理数不利于计算,所以一般采用tan(x)=0.5的角,也就是26.5度。因为减少了误差,所以画出来没那么强的锯齿感。

下面称新的坐标系为斜角坐标系。那么从直角坐标系到斜角坐标系是一个线性变换。

根据前面的假设,设斜角坐标系的x轴和y轴在直角坐标系中分别是:y=x/2,y=-x/2;

那么可推得从斜角坐标系到直角坐标系的变换矩阵为:

$$$$ \begin{align} \left( \begin{array}{ccc} 1 & -1 \\
\frac{1}{2} & \frac{1}{2} \\ \end{array} \right) \end{align}$$$$ 求逆可得,从直角坐标系到斜角坐标系变换矩阵为:

$$$$ \begin{align}
\left(
\begin{array}{ccc}
\frac{1}{2} & 1 \\ -\frac{1}{2} & 1 \\ \end{array} \right)
\end{align}$$$$

假设地图采用菱形的格子,格子的边长在直角坐标系为m。屏幕的正中心恰好是某个菱形的正中心。假如一个玩家站在屏幕正中心,它在斜角坐标系下的格子坐标是(x,y)。那么它在平面坐标系下的值是(x-y)m,(x+y)m/2,那么屏幕正中心的值就是(x-y)m,(x+y)m/2+m/2。如果点P相对于屏幕中心的直角坐标是(a,b),那么它的坐标就是\( ( (x-y)m+a,\frac{(x+y)m}{2}+\frac{m}{2} +b )\),那么换算回去就是\( (mx+\frac{a+m}{2}+b,my-\frac{a-m}{2}+b) \),除以m换算回去是\( (x+ \frac{1}{2}+\frac{a+2b}{2m},y-\frac{1}{2}+\frac{2b-a}{2m}) \) 。用这个公式就可以算出屏幕4个角的格子值。不过我一直在怀疑是否应该补那半个格子。如果去掉那些二分之一,结果简单的很多。

由直角坐标系到斜角坐标系变换矩阵可以推出,与x轴平行的线(比如屏幕上边线),转换成斜角坐标系后,都具有x+y=m这样的形式。而与y轴平行的线,如屏幕的左边线,都具有x-y=m这样的形式。计算视野内的格子,依然是在一个矩形内算,只不过这个矩形的边不再是和坐标轴平行的。

另外,可否使用RTree这样的方法寻找视野内玩家?因为,假设屏幕的大小是1024x768,格子的大小是20x20。那么每个屏幕有1900个格子。做广播的时候需要遍历这1900个格子,看他们里面是否有玩家。但是一般的游戏,一个服务器总共也才2000-3000角色,整张地图也才几百个角色。所以大多数格子都是空的,如果把这种方式看作是二维的hash,那么load factor也太低了,范围查找效率太低了!

此博客中的热门博文

在windows下使用llvm+clang

少写代码,多读别人写的代码

tensorflow distributed runtime初窥