我正在对1999年的游戏进行逆向工程,我遇到了一个函数,该函数似乎正在检查玩家是否在3d点范围内以触发音频源。反编译器会破坏代码,但是我想我理解。
// Position Y delta
v1 = * (float * )(this + 16) - LocalPlayerZoneEntry - > y;
// Position X delta
v2 = * (float * )(this + 20) - LocalPlayerZoneEntry - > x;
// Absolute value
if (v1 < 0.0)
v1 = -v1;
// Absolute value
if (v2 < 0.0)
v2 = -v2;
// What is going on here?
if (v1 <= v2)
v1 = v1 * 0.5;
else
v2 = v2 * 0.5;
// Z position delta
v3 = * (float * )(this + 24) - LocalPlayerZoneEntry - > z;
// Absolute value
if (v3 < 0.0)
v3 = -v3;
result = v3 + v2 + v1;
// Radius
if (result > * (float * )(this + 28))
return 0.0;
return result;
有趣的是,在游戏中,触发似乎非常不一致,有时取决于我从哪一侧接近触发。
有人知道这是否是当今常用的算法吗?
注意:这些类型都是我添加的,因此可能不正确。我认为这是布尔类型的函数。
答案 0 :(得分:16)
可视化距离函数(metric)的最佳方法是绘制其单位球面(距离原点单位距离的点集-所讨论的度量标准是归纳的)。
首先以一种更数学的形式将其重写:
N(x,y,z) = 0.5*|x| + |y| + |z| when |x| <= |y|
= |x| + 0.5*|y| + |z| otherwise
让我们这样做2d(假设z = 0
)。绝对值使函数在四个象限中对称。 |x| <= |y|
条件使其在所有八个扇区中对称。让我们集中讨论扇区x > 0, y > 0, x <= y
。我们想在N(x,y,0) = 1
时找到曲线。对于该扇区,它减少为0.5x + y = 1
或y = 1 - 0.5x
。我们可以去画那条线。当x > 0, y > 0, x > y
时,我们得到x = 1 - 0.5y
。将其全部绘制,将得到以下单位“圆”:
为进行比较,下面是一个欧几里得单位圆:
在第三维中,它的行为类似于出租车的度量标准,有效地为您提供了“钻石”形的球体:
是的,尽管它缺乏旋转对称性,但它是一种便宜的距离函数。