土法炼钢兴趣小组的算法知识备份

游戏中的数学 (4) - 距离与检测

目录

引言

“距离”是游戏中判断互动的核心标准。 - 玩家是否进入了怪物的攻击范围? - 赛车离终点还有多远? - 摄像机是否穿墙了?

1. 距离公式

Distance Types

欧几里得距离 (Euclidean Distance)

这是最常用的直线距离。 \[ d = \sqrt{(x_2-x_1)^2 + (y_2-y_1)^2} \]

在代码中:

float dist = Vector3.Distance(a, b);
// 或者
float dist = (a - b).magnitude;

曼哈顿距离 (Manhattan Distance)

在网格地图(如《火焰纹章》或《文明》)中,你不能斜着走,只能沿格子走。此时距离是 x 轴差值与 y 轴差值的和。 \[ d = |x_2-x_1| + |y_2-y_1| \]

性能优化:平方距离 (Squared Distance)

计算 sqrt (开平方) 是一个相对昂贵的操作。 如果你只是想比较距离(例如:谁离我更近?或者是否在攻击范围内?),你完全不需要开平方。

判断 dist < range 等价于判断 distSq < range * range

float distSq = (target.position - player.position).sqrMagnitude;
float attackRangeSq = attackRange * attackRange;

if (distSq < attackRangeSq) {
    // 在攻击范围内
}

这在需要检测成百上千个物体时能显著提升性能。

2. 点与平面 (Point & Plane)

平面在游戏中通常用于墙壁、地面或触发区域。 一个平面由一个法线 (Normal) \(\vec{n}\) 和一个距离常数 \(d\) 定义。 方程:\(\vec{n} \cdot P + d = 0\)

有符号距离 (Signed Distance)

将任意点 \(P\) 代入平面方程,得到的结果不仅仅是 0。 \[ dist = \vec{n} \cdot P + d \]

游戏应用

3. 点与直线 (Point & Line)

如何计算点 \(P\) 到直线 \(AB\) 的最短距离? 这需要用到投影 (Projection)

  1. 计算向量 \(\vec{AP} = P - A\)
  2. 计算直线方向 \(\vec{AB} = B - A\) 并归一化为 \(\vec{u}\)
  3. 计算投影长度 \(t = \vec{AP} \cdot \vec{u}\)
  4. 最近点 \(C = A + \vec{u} \times t\)
    • 注意:如果线段有限长,需要限制 \(t\)\([0, length]\) 之间。
  5. 距离 = \(|P - C|\)

这在赛车游戏中非常有用,用于计算车辆偏离赛道中心线的距离。


< 上一篇: 四元数 | 回到目录 | 下一篇: 相交检测 >


By .