摘要
向量是既有大小又有方向的量,可以用箭头形象表示,例如速度、力等。向量空间则是向量的集合,支持向量的加法和数乘操作,类似于一个可以自由绘制箭头的世界。在游戏中,向量和向量空间广泛应用于角色移动、物理碰撞、AI导航、光照效果和动画骨骼变换等系统。例如,角色的速度和加速度用向量表示,物理碰撞中的反弹方向通过向量计算,AI寻路依赖向量规划路径,光照效果通过光线向量和表面法向量计算亮度,动画骨骼的变换则通过向量和旋转实现平滑过渡和动作混合。向量和向量空间是游戏开发中不可或缺的数学工具,支撑了游戏世界的动态表现和交互逻辑。
一、什么是向量?
1. 生活比喻
向量就像一支有方向的箭。
- 它有长度(表示大小,比如速度有多快、力有多大)。
- 它有方向(箭头指向哪里,比如往东、往上、往斜前方)。
比如:
- 你骑自行车向东北骑,速度是20公里/小时,这个“速度”就是一个向量(既有大小,也有方向)。
- 你用力推箱子,推的方向和力度合起来,也是一个向量。
2. 数学定义
- 向量通常用一组数字表示,比如二维向量 (x, y),三维向量 (x, y, z)。
- 例如 (3, 4) 表示从原点出发,向右3格、向上4格的箭头。
二、什么是向量空间?
1. 生活比喻
向量空间就像一个“可以自由画箭头的世界”。
- 你可以在这个空间里随意画箭头(向量)。
- 你可以把两个箭头“首尾相接”合成一个新箭头(向量加法)。
- 你可以把箭头拉长、缩短、反向(数乘)。
比如:
- 在平面上(二维空间),你可以画任意方向、任意长度的箭头。
- 在三维空间(比如现实世界),你可以画出任意朝向、任意长度的箭头。
2. 数学定义
- 向量空间是一组向量的集合,满足加法和数乘的运算规则。
- 常见的有二维空间(平面)、三维空间(现实世界)、甚至更高维的空间。
三、向量与向量空间在游戏中的实际应用
1. 角色移动与速度
- 角色的“速度”是一个向量,决定了角色每一帧往哪个方向、以多快的速度移动。
- 角色的“加速度”也是向量,比如跳跃时的上升力。
2. 物理碰撞与反弹
- 小球撞墙后,反弹方向和速度用向量计算。
- 力的叠加、摩擦力、重力等都用向量描述。
3. 镜头与视角控制
- 摄像机的朝向、旋转、移动都用向量和向量空间来描述。
- 例如“第一人称视角”就是用向量来表示玩家的视线方向。
4. AI寻路与导航
- AI角色要从A点走到B点,路径上的每一步都是一个向量。
- AI判断目标是否在自己视野范围内,也是用向量夹角计算。
5. 光照与阴影
- 光线的方向、表面的法向量,都是向量。
- 计算光照强度时,用向量夹角判断光线照射的效果。
6. 动画与骨骼变换
- 角色骨骼的每一根骨头的位置和旋转都用向量和向量空间描述。
- 动画插值、混合等操作都离不开向量空间。
四、形象图示
原点
|
| /
| /
| / ← 这是一个向量(箭头)
| /
| /
| /
|/____________________
- 你可以在空间里画出无数这样的箭头,这就是向量空间。
五、口诀总结
“向量像箭头,
有大小有方向;
空间任你画,
游戏全靠它!”
六、简单代码示例(角色移动)
# 角色当前位置
position = [0, 0, 0]
# 角色速度向量
velocity = [1, 0, 0] # 每秒向X轴正方向移动1单位
# 每帧更新
dt = 0.016 # 假设每帧16毫秒
position[0] += velocity[0] * dt
position[1] += velocity[1] * dt
position[2] += velocity[2] * dt
七、总结
- 向量:有大小和方向的量,像一支箭头。
- 向量空间:可以自由画箭头的世界,支持加法和数乘。
- 游戏应用:角色移动、物理、AI、光照、动画等方方面面都离不开向量和向量空间。
我们继续深入、形象地讲解向量和向量空间在游戏各大系统中的实际应用,让你对它们的作用有更直观的理解。
一、角色移动
1. 方向与速度
- 向量表示方向:比如玩家按下“W”键,角色要向前走,这个“前”就是一个方向向量(如(0,0,1))。
- 速度向量:角色的移动速度和方向合成一个速度向量,比如(0,0,5)表示每秒向前5米。
2. 移动计算
- 每一帧,角色的新位置 = 当前位置 + 速度向量 × 时间
- 这样角色就能平滑地在三维空间中移动。
3. 斜坡与跳跃
- 跳跃时,速度向量会有一个向上的分量(如(0,5,0))。
- 斜坡上移动时,速度向量会根据地形法线(也是向量)调整。
二、物理系统
1. 力与加速度
- 力是向量:比如重力(0,-9.8,0),推力、摩擦力等都用向量表示。
- 加速度=力/质量,也是向量。
2. 碰撞与反弹
- 物体碰撞后,反弹方向用法向量和入射速度向量计算。
- 反射公式:
反射向量 = 入射向量 - 2 × (入射向量·法向量) × 法向量
3. 旋转与角速度
- 旋转轴和角速度也用向量描述,方便实现陀螺仪、飞盘等物理效果。
三、AI与导航
1. 路径规划
- AI从A点到B点,路径上的每一步都是一个位移向量。
- AI可以用向量加法/减法判断距离、方向。
2. 视野与感知
- 判断目标是否在视野内:
计算AI朝向向量与目标方向向量的夹角,夹角小于视野角度则“看见”目标。
3. 避障
- AI检测到障碍物时,用障碍物法向量调整自己的移动向量,实现绕行。
四、光照与阴影
1. 光线方向
- 太阳光、手电筒等光源都有一个方向向量。
- 物体表面有法向量,表示“朝上”或“朝外”的方向。
2. 光照强度
- 计算光线与表面法向量的夹角,夹角越小,表面越亮。
- 公式:
亮度 = max(0, 光线方向向量 · 表面法向量)
3. 阴影投射
- 判断光线是否被其他物体挡住(射线检测),也是用向量做空间计算。
五、动画与骨骼
1. 骨骼位置与旋转
- 每根骨头的位置、朝向都是向量。
- 动画关键帧之间的插值(平滑过渡)用向量插值(如线性插值Lerp、球面插值Slerp)。
2. 角色朝向
- 角色转身、看向目标,用向量计算目标方向,然后平滑旋转过去。
3. 动作混合
- 跑步、跳跃、攻击等动作的混合,底层也是对骨骼向量的加权组合。
六、形象小结
- 向量就像游戏世界里的“万能箭头”,描述一切方向和大小。
- 向量空间是这些箭头自由组合、变化的舞台。
- 游戏中的移动、碰撞、AI、光照、动画……几乎每个系统都在用向量做底层计算。
七、简单代码示例
1. 角色朝向目标
import numpy as np
# 角色当前位置
pos = np.array([1, 0, 1])
# 目标位置
target = np.array([5, 0, 4])
# 方向向量
dir = target - pos
# 单位化
dir = dir / np.linalg.norm(dir)
# 角色朝向dir方向
2. 光照强度计算
# 光线方向
light_dir = np.array([0, -1, 0]) # 直射下方
# 表面法向量
normal = np.array([0, 1, 0]) # 朝上
# 亮度
brightness = max(0, np.dot(light_dir, normal))
八、口诀总结
“箭头指方向,
游戏全靠它;
移动、光影、AI,
动画骨骼都不差!”
下面我们用生动形象的方式,详细讲解动画与骨骼变换中向量和向量空间的应用,并结合实际游戏场景、原理和常见实现方法。
一、什么是骨骼动画?
生活比喻
想象你在玩布娃娃:
- 布娃娃的身体里有一根根“骨头”,比如脊椎、手臂、腿。
- 你掰动娃娃的手臂,整个手臂就会跟着动,手也会跟着动。
- 这些“骨头”连接成一棵树,叫骨骼层级结构。
在3D游戏里,角色的骨骼其实就是一组向量和旋转,用来控制模型的各个部分怎么动。
二、骨骼变换的原理
1. 骨骼的“位置”和“朝向”
- 每根骨头有自己的位置向量(在父骨骼坐标系下的位置)。
- 每根骨头有自己的旋转(通常用四元数或欧拉角,底层也是向量空间的运算)。
2. 层级变换
- 比如:手臂的移动会带动手的移动,手的移动又会带动手指。
- 这叫父子变换,每根骨头的最终位置=父骨骼的变换 × 自己的变换。
3. 变换矩阵
- 每根骨头的变换可以用一个4x4矩阵表示,里面包含了平移(位置向量)、旋转、缩放。
- 这些矩阵可以连乘,最终得到每个骨头在世界空间中的位置和朝向。
三、动画的实现
1. 关键帧动画
- 动画师在不同时间点设置骨骼的“关键姿势”(关键帧)。
- 游戏运行时,自动在关键帧之间插值,让动作平滑过渡。
- 插值用到向量线性插值(Lerp)和旋转球面插值(Slerp)。
2. 动作混合
- 比如角色边跑边挥手,动画系统会把“跑步”和“挥手”两个动画的骨骼变换加权混合,得到最终姿势。
- 这也是对向量和旋转的加权平均。
3. 动画驱动物理
- 有些游戏角色的动画会影响物理系统,比如跳跃时给角色一个向上的速度向量。
四、实际游戏场景举例
-
角色行走、奔跑、跳跃
- 每一帧,骨骼动画系统根据当前动画状态,计算出所有骨头的变换,驱动模型变形。
-
表情动画
- 脸部的骨骼(或称“骨骼点”)控制嘴巴、眼睛、眉毛的运动,实现丰富表情。
-
动作混合
- 角色在跑步时突然攻击,动画系统会把“跑步”和“攻击”两个动画的骨骼变换混合,动作自然流畅。
-
布娃娃物理
- 角色死亡后,骨骼不再受动画控制,而是交给物理引擎模拟真实摔倒、翻滚。
五、形象图示
脑袋
|
脖子
|
脊椎
/ \
左臂 右臂
| |
左手 右手
- 每个节点就是一根骨头,连接成树状结构。
- 每根骨头的变换都可以用向量和旋转描述。
六、简单代码示例(伪代码)
1. 骨骼变换
class Bone:
def __init__(self, parent, local_position, local_rotation):
self.parent = parent
self.local_position = local_position # 向量
self.local_rotation = local_rotation # 四元数或欧拉角
def get_world_transform(self):
if self.parent:
parent_pos, parent_rot = self.parent.get_world_transform()
# 先旋转再平移
world_pos = parent_rot.rotate(self.local_position) + parent_pos
world_rot = parent_rot * self.local_rotation
return world_pos, world_rot
else:
return self.local_position, self.local_rotation
2. 动画插值
# 骨骼在t0和t1时刻的位置和旋转
pos0, rot0 = ...
pos1, rot1 = ...
t = 0.5 # 当前时间在t0和t1之间的插值因子
# 位置线性插值
interp_pos = pos0 * (1-t) + pos1 * t
# 旋转球面插值
interp_rot = slerp(rot0, rot1, t)
七、口诀总结
“骨骼是骨架,
动画靠插值;
向量定位置,
旋转定姿势;
混合出新招,
动作更真实!”
八、补充说明
- 向量空间让骨骼动画可以在三维空间中自由组合、变换。
- 向量和旋转是骨骼动画的数学基础,保证动作自然、流畅。
- 动画系统通过对骨骼的向量和旋转不断插值、混合,实现各种复杂动作。