<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>碰撞检测 on 方糖猫Blog</title>
    <link>https://ftmao.com/blog/tags/%E7%A2%B0%E6%92%9E%E6%A3%80%E6%B5%8B/</link>
    <description>AI 视频、AI Agent 与工程实践笔记</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Thu, 16 Jan 2020 11:00:00 +0800</lastBuildDate><atom:link href="https://ftmao.com/blog/tags/%E7%A2%B0%E6%92%9E%E6%A3%80%E6%B5%8B/index.xml" rel="self" type="application/rss+xml" /><item>
      <title>《游戏开发物理学》学习笔记：从运动学到刚体碰撞的新手实战指南</title>
      <link>https://ftmao.com/blog/bookstore/game-physics-bourg-notes/</link>
      <pubDate>Thu, 16 Jan 2020 11:00:00 +0800</pubDate>
      <guid>https://ftmao.com/blog/bookstore/game-physics-bourg-notes/</guid>
      <description>&lt;h1 id=&#34;游戏开发物理学学习笔记从运动学到刚体碰撞的新手实战指南&#34;&gt;《游戏开发物理学》学习笔记：从运动学到刚体碰撞的新手实战指南&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;参考书籍：《Physics for Game Developers》（David M. Bourg，O&amp;rsquo;Reilly，中译名《游戏开发物理学》）
目标读者：想自己做物理效果（而不是只会调引擎参数）的游戏开发者、图形学/仿真方向的新手。
阅读建议：这篇文章帮你建立&lt;strong&gt;主干知识框架&lt;/strong&gt;：先数学，再运动学 → 动力学 → 载具模拟 → 实时积分 → 碰撞 → 粒子，最后给出避坑清单和主流引擎对照。公式只保留实战中真正会用的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一这本书到底讲什么&#34;&gt;一、这本书到底讲什么？&lt;/h2&gt;
&lt;p&gt;很多新手做游戏的物理效果，路径是这样的：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用 Unity/UE 拖一个 Rigidbody，调调质量、摩擦力，能跑就行；&lt;/li&gt;
&lt;li&gt;遇到「球穿过墙了」「车开起来像肥皂盒」「碰撞后能量爆炸越弹越高」就抓瞎；&lt;/li&gt;
&lt;li&gt;回头发现：不是引擎不行，是自己不懂底层的物理模型。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Bourg 这本书的价值就在于：&lt;strong&gt;它把物理引擎内部在干什么，用程序员能实现的粒度讲了一遍&lt;/strong&gt;。它不追求物理学的严谨完备，而是追求「在 60 FPS 的游戏循环里，用可承受的计算量，得到看起来正确、玩起来稳定的结果」。&lt;/p&gt;
&lt;p&gt;全书知识地图：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;mindmap
  root((游戏开发物理学))
    数学基础
      向量与运算
      矩阵与坐标变换
      四元数
    运动学 Kinematics
      位移 速度 加速度
      抛体运动
    动力学 Dynamics
      牛顿定律
      力与力矩
      流体阻力
    载具模拟
      飞机
      舰船
      气垫船
      汽车
    实时模拟
      数值积分
      游戏循环
      时间步长
    碰撞
      碰撞检测
      碰撞反应 冲量
    粒子系统&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;一句话总纲&lt;/strong&gt;：游戏物理 = 用力计算加速度，用数值积分把加速度变成速度和位置，用碰撞检测发现问题，用冲量修正速度。整本书就是在把这句话的每个环节讲细。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二核心数学基础速成&#34;&gt;二、核心数学基础速成&lt;/h2&gt;
&lt;p&gt;物理引擎 90% 的代码是向量、矩阵和四元数运算。这一关不过，后面全看不懂。&lt;/p&gt;
&lt;h3 id=&#34;21-向量物理量的通用语言&#34;&gt;2.1 向量：物理量的通用语言&lt;/h3&gt;
&lt;p&gt;位置、速度、力、动量，全部是向量。必须熟练的运算：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;加减&lt;/strong&gt;：力的合成（$F = F_1 + F_2$）、相对速度；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;点积&lt;/strong&gt;（结果是一个数）：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$$
\mathbf{a} \cdot \mathbf{b} = |\mathbf{a}||\mathbf{b}|\cos\theta
$$&lt;/p&gt;
&lt;p&gt;实战用途：求投影（比如速度沿碰撞法线方向的分量）、判断两个方向夹角是锐角还是钝角（点积大于 0 还是小于 0）。碰撞反应里「物体是否在相互靠近」就是靠点积判断的。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;叉积&lt;/strong&gt;（结果是一个垂直向量，仅 3D；2D 中退化为一个标量）：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$$
|\mathbf{a} \times \mathbf{b}| = |\mathbf{a}||\mathbf{b}|\sin\theta
$$&lt;/p&gt;
&lt;p&gt;实战用途：&lt;strong&gt;力矩&lt;/strong&gt; $\tau = \mathbf{r} \times \mathbf{F}$（力作用点偏离质心会产生转动）、2D 碰撞冲量里的旋转项。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;归一化&lt;/strong&gt;：$\hat{\mathbf{v}} = \mathbf{v} / |\mathbf{v}|$，只要方向不要大小（碰撞法线必须归一化，忘记这步是经典 bug）。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;避坑：2D 里叉积 $\mathbf{r} \times \mathbf{F}$ 是标量 $r_x F_y - r_y F_x$，正负号代表顺时针/逆时针，和引擎的坐标系朝向约定有关，写之前先定好「逆时针为正」并全程统一。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;22-矩阵与坐标变换&#34;&gt;2.2 矩阵与坐标变换&lt;/h3&gt;
&lt;p&gt;旋转、缩放、坐标系切换都靠矩阵。新手只需要先建立两个直觉：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;矩阵乘法 = 变换的复合，&lt;strong&gt;顺序不可交换&lt;/strong&gt;（先旋转再平移 ≠ 先平移再旋转）；&lt;/li&gt;
&lt;li&gt;每个刚体都活在两个坐标系里：&lt;strong&gt;局部坐标系&lt;/strong&gt;（物体自己的，转动惯量、几何形状在这里算最方便）和&lt;strong&gt;世界坐标系&lt;/strong&gt;（所有物体一起碰撞、渲染的地方）。物理计算每天的工作就是在这两个系之间来回变换。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;23-四元数3d-姿态的正确打开方式&#34;&gt;2.3 四元数：3D 姿态的正确打开方式&lt;/h3&gt;
&lt;p&gt;3D 中表示朝向有三种方式：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;方式&lt;/th&gt;
					&lt;th&gt;优点&lt;/th&gt;
					&lt;th&gt;缺点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;欧拉角（roll/pitch/yaw）&lt;/td&gt;
					&lt;td&gt;直观，3 个数&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;万向锁&lt;/strong&gt;（gimbal lock），插值不平滑&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;旋转矩阵&lt;/td&gt;
					&lt;td&gt;直接用于向量变换&lt;/td&gt;
					&lt;td&gt;9 个数冗余，数值误差积累会「变形」&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;四元数&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;4 个数紧凑，插值平滑，无万向锁&lt;/td&gt;
					&lt;td&gt;不直观，乘法规则要背&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;游戏物理的标准做法：&lt;strong&gt;内部存储和积分用四元数，给玩家看的时候转欧拉角&lt;/strong&gt;。四元数必须经常归一化，否则数值漂移会让物体悄悄缩放变形。&lt;/p&gt;
&lt;h3 id=&#34;24-微积分只需要两个直觉&#34;&gt;2.4 微积分：只需要两个直觉&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;导数&lt;/strong&gt; = 变化率。速度是位置的导数，加速度是速度的导数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;积分&lt;/strong&gt; = 累积。已知加速度，累加得到速度；累加速度得到位置。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;游戏里你永远不会真的去解符号积分——而是用数值积分一步步逼近（见第六章）。理解「导数是斜率、积分是累加」就够了。&lt;/p&gt;
&lt;h3 id=&#34;25-单位制与坐标系开工前先立规矩&#34;&gt;2.5 单位制与坐标系：开工前先立规矩&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;避坑（这是新手第一大坑）：开工前必须白纸黑字定下来——&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;长度单位是&lt;strong&gt;米&lt;/strong&gt;还是&lt;strong&gt;像素&lt;/strong&gt;？重力加速度是 9.81 m/s² 还是 981 px/s²？混用必出灵异现象。&lt;/li&gt;
&lt;li&gt;2D 屏幕坐标 &lt;strong&gt;y 轴向下&lt;/strong&gt;，而物理教科书 y 轴向上。直接照抄公式会把「下落」写成「飞天」。&lt;/li&gt;
&lt;li&gt;角度用&lt;strong&gt;弧度&lt;/strong&gt;，所有三角函数接口都是弧度，传角度进去结果毫无明显错误提示。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;三运动学kinematics只描述运动不问原因&#34;&gt;三、运动学（Kinematics）：只描述运动，不问原因&lt;/h2&gt;
&lt;p&gt;运动学关心「物体怎么动」，不关心「为什么动」（那是动力学的事）。&lt;/p&gt;
&lt;h3 id=&#34;31-三个基本量&#34;&gt;3.1 三个基本量&lt;/h3&gt;
&lt;p&gt;$$
\text{速度 } \mathbf{v} = \frac{d\mathbf{x}}{dt}, \qquad \text{加速度 } \mathbf{a} = \frac{d\mathbf{v}}{dt}
$$&lt;/p&gt;
&lt;p&gt;匀加速运动（加速度恒定）下的三个实用公式：&lt;/p&gt;
&lt;p&gt;$$
v = v_0 + at
$$&lt;/p&gt;
&lt;p&gt;$$
x = x_0 + v_0 t + \frac{1}{2} a t^2
$$&lt;/p&gt;
&lt;p&gt;$$
v^2 = v_0^2 + 2a(x - x_0)
$$&lt;/p&gt;
&lt;h3 id=&#34;32-抛体运动游戏里最值钱的运动学&#34;&gt;3.2 抛体运动：游戏里最值钱的运动学&lt;/h3&gt;
&lt;p&gt;抛体（炮弹、篮球、跳跃的角色）的核心思想一句话：&lt;strong&gt;水平方向和竖直方向互相独立，分开算&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;水平：无加速度，匀速 $x = v_0 \cos\theta \cdot t$&lt;/li&gt;
&lt;li&gt;竖直：受重力，$y = v_0 \sin\theta \cdot t - \frac{1}{2} g t^2$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;由这两个式子可以推出（落回同一高度时）：&lt;/p&gt;
&lt;p&gt;$$
\text{射程 } R = \frac{v_0^2 \sin 2\theta}{g}, \qquad \text{最高点 } H = \frac{v_0^2 \sin^2\theta}{2g}
$$&lt;/p&gt;
&lt;p&gt;两个直接能用在游戏里的结论：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;45 度抛射射程最远&lt;/strong&gt;（不计空气阻力时）；&lt;/li&gt;
&lt;li&gt;已知初速度和目标距离，可以反解出抛射角——这就是「抛物线命中目标」的数学基础。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;典型问题：炮弹打移动目标的提前量。&lt;/strong&gt; 设目标当前位置 $\mathbf{p}$、速度 $\mathbf{v}_t$，炮弹速度 $s$，求解命中时间 $t$：&lt;/p&gt;
&lt;p&gt;$$
|\mathbf{p} + \mathbf{v}_t t| = s t
$$&lt;/p&gt;
&lt;p&gt;两边平方得到一个关于 $t$ 的一元二次方程，取最小正根，瞄准点就取 $\mathbf{p} + \mathbf{v}_t t$。AI 炮塔、技能预判全是这个套路。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;避坑：二次方程可能无解（目标跑得太快炮弹追不上），代码里必须处理判别式小于 0 的情况，否则 AI 会对着永远打不中的目标开火。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;四作用力与动力学dynamics运动的原因&#34;&gt;四、作用力与动力学（Dynamics）：运动的原因&lt;/h2&gt;
&lt;h3 id=&#34;41-牛顿三定律的程序员版本&#34;&gt;4.1 牛顿三定律的程序员版本&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;惯性定律&lt;/strong&gt;：不受力的物体保持匀速直线运动——所以你不用写代码让它「继续动」，它不减速只是因为没人让它减速；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;核心公式&lt;/strong&gt; $\mathbf{F} = m\mathbf{a}$：所有物理引擎的心脏。&lt;strong&gt;先把作用在物体上的所有力加起来（合力），除以质量得到加速度，然后交给积分器&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;作用力与反作用力&lt;/strong&gt;：碰撞反应、火箭推力的理论基础。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;旋转版本的对应关系（这对应表值得背下来）：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;直线运动&lt;/th&gt;
					&lt;th&gt;旋转运动&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;质量 $m$&lt;/td&gt;
					&lt;td&gt;转动惯量 $I$&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;力 $\mathbf{F}$&lt;/td&gt;
					&lt;td&gt;力矩 $\tau = \mathbf{r} \times \mathbf{F}$&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;加速度 $\mathbf{a} = \mathbf{F}/m$&lt;/td&gt;
					&lt;td&gt;角加速度 $\alpha = \tau / I$&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;速度 $\mathbf{v}$&lt;/td&gt;
					&lt;td&gt;角速度 $\omega$&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;转动惯量的直觉：质量分布离转轴越远越难转（花样滑冰收手加速）。2D 里 $I$ 就是一个标量（如均匀圆盘 $I = \frac{1}{2}mr^2$，细杆绕中心 $I = \frac{1}{12}mL^2$）；3D 里是一个 3×3 张量矩阵，通常直接在&lt;strong&gt;局部坐标系&lt;/strong&gt;下预计算并求逆，避免每帧重复。&lt;/p&gt;
&lt;h3 id=&#34;42-游戏里最常见的几种力&#34;&gt;4.2 游戏里最常见的几种力&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;重力&lt;/strong&gt;：$F = mg$，恒定向下，人人有份；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;弹簧力&lt;/strong&gt;：胡克定律 $F = -kx$（$k$ 是劲度系数），悬挂、软绳、镜头跟随弹性都靠它；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;摩擦力&lt;/strong&gt;：静摩擦（小于阈值时完全抵消切向力）与动摩擦 $F = \mu N$（$\mu$ 摩擦系数，$N$ 法向压力）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;流体阻力&lt;/strong&gt;（空气/水）：低速近似线性 $F = -k_1 v$，高速用二次项：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$$
F_d = -\frac{1}{2} \rho v^2 C_d A , \hat{\mathbf{v}}
$$&lt;/p&gt;
&lt;p&gt;$\rho$ 是流体密度，$C_d$ 阻力系数，$A$ 是迎流面积。飞机、舰船、弹道下坠感全靠它。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;避坑：二次阻力在速度很大时力也爆炸式增大，直接积分容易数值不稳定（物体来回震荡甚至飞出屏幕）。实战技巧是给阻力加速度设上限，或改用半隐式积分。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;五载具物理本书的招牌四章&#34;&gt;五、载具物理：本书的招牌四章&lt;/h2&gt;
&lt;p&gt;Bourg 用飞机、舰船、气垫船、汽车四个例子，展示同一套框架（合力 → 加速度 → 积分）如何套出完全不同的手感。掌握套路比记住每个参数重要。&lt;/p&gt;
&lt;h3 id=&#34;51-飞机四力平衡&#34;&gt;5.1 飞机：四力平衡&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    T[推力 Thrust&amp;lt;br/&amp;gt;发动机] --&amp;gt;|向前| P((飞机))
    D[阻力 Drag&amp;lt;br/&amp;gt;空气摩擦与压差] --&amp;gt;|向后| P
    L[升力 Lift&amp;lt;br/&amp;gt;机翼上下压差] --&amp;gt;|向上| P
    W[重力 Weight&amp;lt;br/&amp;gt;mg] --&amp;gt;|向下| P&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;核心公式是升力和阻力，共享同一个「动压」结构：&lt;/p&gt;
&lt;p&gt;$$
L = \frac{1}{2} \rho v^2 S C_L, \qquad D = \frac{1}{2} \rho v^2 S C_D
$$&lt;/p&gt;
&lt;p&gt;其中 $S$ 是机翼面积，$C_L$ 升力系数。关键知识点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$C_L$ 随&lt;strong&gt;迎角&lt;/strong&gt;（机翼与气流的夹角）增大而增大，但超过临界迎角后骤减——这就是&lt;strong&gt;失速&lt;/strong&gt;，飞机升力瞬间消失往下掉。模拟飞行手感，失速是必须实现的；&lt;/li&gt;
&lt;li&gt;滚转、俯仰、偏航三个通道各自独立输入力矩，组合出飞行姿态；&lt;/li&gt;
&lt;li&gt;升力正比于 $v^2$：速度不够就拉不起来，这是「起飞需要跑道」的物理原因。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;避坑：完整的空气动力学模型极复杂，游戏里几乎没人真做 CFD。标准做法是&lt;strong&gt;查表/分段线性&lt;/strong&gt;：把 $C_L$ 和 $C_D$ 做成关于迎角的查找表，手感调好就是胜利。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;52-舰船浮力与流体阻力的天下&#34;&gt;5.2 舰船：浮力与流体阻力的天下&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;浮力&lt;/strong&gt;：阿基米德原理，浮力等于排开水的重量。简化模拟常用「浮力采样点」——在船底布若干采样点，每个点按入水深度产生向上的力，自然涌现出船的横摇和纵摇；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;稳性&lt;/strong&gt;：浮心与重心的相对位置决定船会不会翻。重心太高、浮心太低 = 头重脚轻，一晃就翻；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;阻力&lt;/strong&gt;：水的密度约为空气的 800 多倍，所以舰船阻力以&lt;strong&gt;粘性阻力&lt;/strong&gt;为主，低速近似线性即可；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;转弯&lt;/strong&gt;：舵产生侧向水动力，船不是「拐过去」而是「漂着转过去」，模拟时要给船体侧向很大的阻力、纵向较小的阻力，才有「船感」。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;53-气垫船低摩擦的特殊手感&#34;&gt;5.3 气垫船：低摩擦的特殊手感&lt;/h3&gt;
&lt;p&gt;气垫船悬在气垫上，&lt;strong&gt;与地面的摩擦几乎为零&lt;/strong&gt;，带来两个标志性的操控特性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;推力方向和运动方向可以长期不一致——船头朝东，船还在往西漂；&lt;/li&gt;
&lt;li&gt;转向靠舵/侧推产生力矩，但&lt;strong&gt;转弯时船身会侧滑&lt;/strong&gt;，直到横向水/气阻力把侧向速度消耗掉。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;实现上就是在普通刚体模型里把接触摩擦调得极小，再加分方向差异很大的阻力系数（横向阻力大、纵向阻力小）。「阻力系数各向异性」是气垫船和所有水上载具手感的灵魂。&lt;/p&gt;
&lt;h3 id=&#34;54-汽车一切手感都在轮胎上&#34;&gt;5.4 汽车：一切手感都在轮胎上&lt;/h3&gt;
&lt;p&gt;汽车的驱动力链路：&lt;strong&gt;发动机扭矩 → 变速箱/挡位 → 驱动轮 → 轮胎与地面的摩擦 → 牵引力&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;最重要的概念是&lt;strong&gt;抓地力有限&lt;/strong&gt;：轮胎能提供的摩擦力有上限（摩擦圆/摩擦椭圆），加速、刹车、转向消耗的抓地力共享同一个预算。转向打满还猛踩油门，抓地力透支——打滑、漂移就这么来的。&lt;/p&gt;
&lt;p&gt;简化模型三件套：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;驱动力 $F = \text{engineForce}$，随速度衰减（极速的来源：驱动力 = 阻力时不再加速）；&lt;/li&gt;
&lt;li&gt;阻力 = 滚动阻力 + 空气阻力（二次项主导高速）；&lt;/li&gt;
&lt;li&gt;转向时按当前速度把车头方向「往速度方向拉」，拉伸强度代表抓地力——强度低就是漂移手感。&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;避坑：很多新手给汽车直接用「速度 = 车头方向 × 油门」，车像轨道车一样瞬间转向，毫无惯性。正确做法是&lt;strong&gt;转向改的是车头朝向，速度方向靠轮胎力逐渐跟上&lt;/strong&gt;，这个「跟不上」就是车感的来源。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;六实时模拟数值积分与时间步长&#34;&gt;六、实时模拟：数值积分与时间步长&lt;/h2&gt;
&lt;p&gt;前面所有公式给出的是「这一瞬间的加速度」。游戏是一帧一帧跑的，核心问题是：&lt;strong&gt;怎么从加速度一步步推出位置和姿态？&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;61-游戏物理主循环&#34;&gt;6.1 游戏物理主循环&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    A[读取输入] --&amp;gt; B[计算所有作用力与力矩&amp;lt;br/&amp;gt;重力/推力/阻力/弹簧...]
    B --&amp;gt; C[求合力 F 与合力矩 τ&amp;lt;br/&amp;gt;a = F/m, α = τ/I]
    C --&amp;gt; D[数值积分&amp;lt;br/&amp;gt;更新速度 v、角速度 ω]
    D --&amp;gt; E[再积分&amp;lt;br/&amp;gt;更新位置 x、姿态 q]
    E --&amp;gt; F[碰撞检测]
    F --&amp;gt; G{有碰撞?}
    G --&amp;gt;|是| H[碰撞反应&amp;lt;br/&amp;gt;施加冲量修正速度]
    G --&amp;gt;|否| I[渲染]
    H --&amp;gt; I
    I --&amp;gt; A&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;h3 id=&#34;62-三种积分方法对比&#34;&gt;6.2 三种积分方法对比&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;方法&lt;/th&gt;
					&lt;th&gt;公式（以位置为例）&lt;/th&gt;
					&lt;th&gt;精度&lt;/th&gt;
					&lt;th&gt;速度&lt;/th&gt;
					&lt;th&gt;适用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;显式欧拉&lt;/td&gt;
					&lt;td&gt;$x(t+h) = x(t) + v(t),h$&lt;/td&gt;
					&lt;td&gt;差，能量发散&lt;/td&gt;
					&lt;td&gt;最快&lt;/td&gt;
					&lt;td&gt;不推荐单独用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;半隐式欧拉&lt;/strong&gt;（Symplectic Euler）&lt;/td&gt;
					&lt;td&gt;先 $v(t+h) = v(t) + a,h$，再 $x(t+h) = x(t) + v(t+h),h$&lt;/td&gt;
					&lt;td&gt;一阶但&lt;strong&gt;能量稳定&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;快&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;游戏物理默认选择&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;RK4&lt;/td&gt;
					&lt;td&gt;四次采样加权平均&lt;/td&gt;
					&lt;td&gt;四阶，很准&lt;/td&gt;
					&lt;td&gt;4 倍开销&lt;/td&gt;
					&lt;td&gt;需要精确的离线仿真&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;半隐式欧拉只比显式欧拉改了一个顺序（&lt;strong&gt;用新速度更新位置&lt;/strong&gt;），稳定性却有质的飞跃——这是书里最划算的「一行代码的智慧」。&lt;/p&gt;
&lt;h3 id=&#34;63-时间步长实时模拟的头号工程问题&#34;&gt;6.3 时间步长：实时模拟的头号工程问题&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;固定时间步&lt;/strong&gt;：物理每 1/60 秒（或 1/120 秒）推进一步，渲染帧率高时插值、低时多补几步。优点：结果可复现（回放、联机同步必须用它）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可变时间步&lt;/strong&gt;：直接用上一帧的耗时当 $h$。优点简单；缺点致命——帧率波动直接改变物理行为，同一台机器跑两遍结果都不一样。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;避坑（ spiral of death，死亡螺旋）：帧率突然下降 → 单帧物理步数暴增 → 物理计算更慢 → 帧率进一步下降。解法：给每帧物理步数设上限（如最多 5 步），宁可游戏慢动作也不让模拟爆炸。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;避坑（隧道效应 tunneling）：步长太大 + 速度太快 → 子弹一帧飞过了整面墙，两帧采样点都在墙外，碰撞检测永远发现不了。解法：小步长、射线扫掠检测（swept collision / CCD），或对高速物体单独细分步长。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;七刚体旋转从粒子到真正的物体&#34;&gt;七、刚体旋转：从粒子到真正的「物体」&lt;/h2&gt;
&lt;p&gt;粒子只有位置；刚体多了&lt;strong&gt;姿态&lt;/strong&gt;（orientation），一切都变复杂了。&lt;/p&gt;
&lt;p&gt;3D 姿态更新的标准流程（四元数版）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;存姿态四元数 $q$ 和角速度向量 $\omega$；&lt;/li&gt;
&lt;li&gt;每步积分：&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;$$
q(t+h) = q(t) + \frac{h}{2}, \tilde{\omega} , q(t)
$$&lt;/p&gt;
&lt;p&gt;其中 $\tilde{\omega} = (0, \omega_x, \omega_y, \omega_z)$ 是纯四元数形式的角速度（注意乘法顺序，别写反）；
3. &lt;strong&gt;归一化 $q$&lt;/strong&gt;（不做的后果：物体慢慢变大/缩小）；
4. 需要转动向量时，用 $q$ 把向量从局部系旋转到世界系。&lt;/p&gt;
&lt;p&gt;力矩链路：外力作用点相对质心的偏移 $\mathbf{r}$ 产生力矩 $\tau = \mathbf{r} \times \mathbf{F}$，角加速度 $\alpha = I^{-1}\tau$（3D 中 $I^{-1}$ 要用当前姿态把局部系的逆惯量张量变换到世界系），积分得 $\omega$。这就是为什么打在边缘的一拳会让物体边飞边转。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;避坑：3D 转动惯量张量一定要在&lt;strong&gt;局部坐标系&lt;/strong&gt;预计算并求逆；每帧变换到世界系用 $I^{-1}_{world} = R I^{-1}_{local} R^T$。直接在世界系里积分惯量是错误的经典写法。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;八碰撞检测先粗后精&#34;&gt;八、碰撞检测：先粗后精&lt;/h2&gt;
&lt;h3 id=&#34;81-两阶段流水线&#34;&gt;8.1 两阶段流水线&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    subgraph 粗阶段 Broad Phase
        A1[遍历所有物体对] --&amp;gt; A2[包围球 / AABB 快速排除]
        A2 --&amp;gt; A3[空间划分&amp;lt;br/&amp;gt;网格 / 四叉树 / BVH]
    end
    subgraph 窄阶段 Narrow Phase
        B1[候选物体对] --&amp;gt; B2[精确求交&amp;lt;br/&amp;gt;SAT / 顶点-面 / 边-边]
        B2 --&amp;gt; B3[输出碰撞信息&amp;lt;br/&amp;gt;接触点 / 法线 / 穿透深度]
    end
    A3 --&amp;gt; B1&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;关键思想：$n$ 个物体两两检测是 $O(n^2)$，先用粗阶段把 99% 不可能相碰的对子排除掉，窄阶段只处理剩下的少数。&lt;/p&gt;
&lt;h3 id=&#34;82-常用包围体&#34;&gt;8.2 常用包围体&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;包围体&lt;/th&gt;
					&lt;th&gt;特点&lt;/th&gt;
					&lt;th&gt;典型场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;包围球&lt;/td&gt;
					&lt;td&gt;测试只需比较圆心距与半径和，最快&lt;/td&gt;
					&lt;td&gt;子弹、粒子、粗略筛选&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;AABB（轴对齐包围盒）&lt;/td&gt;
					&lt;td&gt;各轴区间重叠判断，简单快速&lt;/td&gt;
					&lt;td&gt;静态场景、粗阶段&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;OBB（有向包围盒）&lt;/td&gt;
					&lt;td&gt;贴合物体旋转，测试较贵&lt;/td&gt;
					&lt;td&gt;车辆、细长物体&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;凸多边形/凸包 + SAT&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;分离轴定理&lt;/strong&gt;：存在一条轴使两形体的投影不重叠 ⟺ 不相交&lt;/td&gt;
					&lt;td&gt;2D 精确检测、3D 凸体&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;避坑：SAT 的轴候选是「两个形体所有面的法线」（3D 还要加边叉积），漏掉一组轴就会在特定角度漏检。另外 SAT 只适用于&lt;strong&gt;凸体&lt;/strong&gt;，凹体要先拆成多个凸体。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;83-碰撞检测必须输出的三样东西&#34;&gt;8.3 碰撞检测必须输出的三样东西&lt;/h3&gt;
&lt;p&gt;窄阶段不是只回答「碰没碰」，而是要给出碰撞反应需要的输入：&lt;strong&gt;接触点&lt;/strong&gt;（冲量作用在哪里）、&lt;strong&gt;法线&lt;/strong&gt;（冲量沿哪个方向）、&lt;strong&gt;穿透深度&lt;/strong&gt;（位置修正多少）。缺了任何一个，后面的碰撞反应都写不出来。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;九碰撞反应冲量法&#34;&gt;九、碰撞反应：冲量法&lt;/h2&gt;
&lt;p&gt;碰撞瞬间持续时间极短、力极大，直接模拟力不现实。游戏物理的标准做法是&lt;strong&gt;冲量法&lt;/strong&gt;：把碰撞看成瞬间改变速度的一次「踢」。&lt;/p&gt;
&lt;h3 id=&#34;91-核心推导思路&#34;&gt;9.1 核心推导思路&lt;/h3&gt;
&lt;p&gt;设两物体碰撞前的&lt;strong&gt;相对速度沿法线分量&lt;/strong&gt;为 $v_r \cdot \mathbf{n}$，碰撞后变为 $-e$ 倍（$e$ 是恢复系数：$e=1$ 完全弹性，$e=0$ 完全非弹性）——这就是牛顿碰撞定律。把「冲量同时改变两物体的线速度和角速度」代入，解出法向冲量大小：&lt;/p&gt;
&lt;p&gt;$$
j = \frac{-(1+e), \mathbf{v}_{rel} \cdot \mathbf{n}}
{\dfrac{1}{m_1} + \dfrac{1}{m_2} +
\dfrac{(\mathbf{r}_1 \times \mathbf{n})^2}{I_1} +
\dfrac{(\mathbf{r}_2 \times \mathbf{n})^2}{I_2}}
$$&lt;/p&gt;
&lt;p&gt;（这是 2D 版本，$\mathbf{r}_1$、$\mathbf{r}_2$ 是接触点相对两质心的偏移；3D 版本把平方项换成矩阵形式 $\mathbf{n} \cdot [(\mathbf{r} \times \mathbf{n}) I^{-1} \times \mathbf{r}]$。）&lt;/p&gt;
&lt;p&gt;然后：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;线速度：$\mathbf{v}_1 \mathrel{-}= \frac{j}{m_1}\mathbf{n}$，$\mathbf{v}_2 \mathrel{+}= \frac{j}{m_2}\mathbf{n}$&lt;/li&gt;
&lt;li&gt;角速度：$\omega_1 \mathrel{-}= \frac{(\mathbf{r}_1 \times j\mathbf{n})}{I_1}$，$\omega_2 \mathrel{+}= \frac{(\mathbf{r}_2 \times j\mathbf{n})}{I_2}$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;打偏的一撞让物体旋转起来，就是这两个 $\mathbf{r} \times$ 项在起作用。&lt;/p&gt;
&lt;h3 id=&#34;92-摩擦冲量&#34;&gt;9.2 摩擦冲量&lt;/h3&gt;
&lt;p&gt;法向冲量解决「弹开」，摩擦冲量解决「蹭」。算出切向相对速度后施加切向冲量 $j_t$，并钳制在库仑摩擦锥内：&lt;/p&gt;
&lt;p&gt;$$
|j_t| \le \mu , j
$$&lt;/p&gt;
&lt;p&gt;不做这个钳制，摩擦会反过来给物体加速——又一个「能量爆炸」来源。&lt;/p&gt;
&lt;h3 id=&#34;93-实战避坑清单碰撞反应篇&#34;&gt;9.3 实战避坑清单（碰撞反应篇）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;穿透与抖动&lt;/strong&gt;：数值误差让物体每帧陷进去一点又弹出来。解法：允许一个微小穿透量（slop），只对超出部分做位置修正（Baumgarte 稳定化），修正量再打个 0.2 左右的折扣；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;能量爆炸&lt;/strong&gt;：单次冲量解多接触点会互相打架，恢复系数别用满 1，摩擦记得钳制，必要时加阻尼；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;迭代求解&lt;/strong&gt;：多个接触点/约束时，对速度约束循环迭代 4-10 次（顺序冲量法），直到收敛——Box2D 就是这么做的；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;静止接触&lt;/strong&gt;：物体叠放静止时，冲量趋近于零但不等于零，抖动主要来自这里。slop + 位置修正 + 休眠（速度长期低于阈值就把物体标记为睡眠，跳过模拟）三件套缺一不可；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;衝量只改速度&lt;/strong&gt;：碰完物体还插在里面是正常的，位置交给下一帧的位置修正或积分自然分离，别试图一帧内又改速度又硬掰位置（除非做的是专门的位置投影）。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;十粒子系统刚体的降维打击&#34;&gt;十、粒子系统：刚体的「降维打击」&lt;/h2&gt;
&lt;p&gt;粒子 = 没有旋转、没有形状（通常渲染成点或公告板）、数量极大的迷你刚体。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;模拟上只做：合力（重力、风、阻力）→ 半隐式欧拉积分 → 简单碰撞（对地面反弹或直接死亡）；&lt;/li&gt;
&lt;li&gt;表现上靠&lt;strong&gt;生成器&lt;/strong&gt;（发射速率、初速度锥角、寿命随机分布）和&lt;strong&gt;衰减&lt;/strong&gt;（颜色、大小、透明度随寿命变化）；&lt;/li&gt;
&lt;li&gt;典型用途：火花、烟雾、爆炸、尾迹、简单的流体/喷泉近似。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;避坑：粒子系统的瓶颈几乎从不在物理，而在&lt;strong&gt;渲染和内存&lt;/strong&gt;。对象池复用粒子、避免每帧 new/delete，CPU 模拟 + GPU 渲染分工明确，是入门就该养成的习惯。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;十一2d-刚体模拟器把全书串起来的最小实战&#34;&gt;十一、2D 刚体模拟器：把全书串起来的最小实战&lt;/h2&gt;
&lt;p&gt;书中后半部分的 2D 刚体模拟示例，是最适合新手的毕业项目。最小可用版本只需要这些模块：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    subgraph 数据结构
        D1[RigidBody2D&amp;lt;br/&amp;gt;位置/角度/线速度/角速度&amp;lt;br/&amp;gt;质量/转动惯量]
        D2[Contact&amp;lt;br/&amp;gt;接触点/法线/穿透深度]
    end
    subgraph 每帧流程
        S1[施加重力等外力] --&amp;gt; S2[半隐式欧拉积分]
        S2 --&amp;gt; S3[粗阶段: AABB 排除]
        S3 --&amp;gt; S4[窄阶段: SAT 求接触]
        S4 --&amp;gt; S5[冲量求解 迭代若干次]
        S5 --&amp;gt; S6[位置修正 slop + Baumgarte]
        S6 --&amp;gt; S7[休眠检测]
    end
    D1 --&amp;gt; S1
    S4 --&amp;gt; D2
    D2 --&amp;gt; S5&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;动手顺序建议：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先做单刚体自由落体 + 地面反弹（恢复系数可调），验证积分正确；&lt;/li&gt;
&lt;li&gt;加旋转：给一个方块偏心施加力，看是否边飞边转；&lt;/li&gt;
&lt;li&gt;加碰撞：圆 vs 圆（最简单）→ 凸多边形 SAT；&lt;/li&gt;
&lt;li&gt;加摩擦冲量和迭代求解；&lt;/li&gt;
&lt;li&gt;加位置修正和休眠，一堆方块能稳稳叠起来——恭喜，你写出了一个迷你 Box2D。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&#34;十二典型问题-faq&#34;&gt;十二、典型问题 FAQ&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Q1：物体速度越来越快最后飞出世界（数值发散）？&lt;/strong&gt;
检查三件事：是否用了显式欧拉（换半隐式）；步长是否过大（弹簧系统等刚度大的力要求更小的步）；阻力/弹簧是否缺上限或阻尼。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q2：子弹穿墙？&lt;/strong&gt;
隧道效应。高速物体用扫掠检测（上一帧位置到这一帧位置打一条射线/扫掠体），或对其使用更小的子步长（CCD）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q3：箱子叠在一起不停抖动、慢慢沉进地里？&lt;/strong&gt;
缺 slop 容差和位置修正折扣；恢复系数设成了接近 1（静止接触应该用 0 或极小）；缺少休眠机制。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q4：联机/回放时物理结果不一致？&lt;/strong&gt;
使用了可变时间步或浮点运算顺序不一致。固定时间步 + 固定迭代次数 + 固定遍历顺序是确定性模拟的前提；跨平台完全一致还要锁定浮点模式或用定点数（如《王者荣耀》等帧同步游戏的做法）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q5：斜坡上的箱子自己往下滑 / 不会滑？&lt;/strong&gt;
检查摩擦实现：切向冲量有没有做库仑钳制 $\mu j$；法线是否归一化；静摩擦与动摩擦有没有分开处理。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q6：四元数积分后物体悄悄变形/缩放？&lt;/strong&gt;
忘记每步归一化四元数。这是四元数模拟里出现率最高的 bug。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q7：2D 里物体往天上「掉」？&lt;/strong&gt;
屏幕 y 轴向下而公式按 y 轴向上写的，重力符号反了。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;十三避坑总清单速查表&#34;&gt;十三、避坑总清单（速查表）&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;坑&lt;/th&gt;
					&lt;th&gt;症状&lt;/th&gt;
					&lt;th&gt;解法&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;单位混用（米/像素）&lt;/td&gt;
					&lt;td&gt;一切数值都「差不多但不对」&lt;/td&gt;
					&lt;td&gt;开工前定死单位制，重力常数跟着改&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;y 轴朝向&lt;/td&gt;
					&lt;td&gt;运动方向全部镜像&lt;/td&gt;
					&lt;td&gt;定好坐标约定，重力符号随之确定&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;显式欧拉&lt;/td&gt;
					&lt;td&gt;能量越来越多，逐渐爆炸&lt;/td&gt;
					&lt;td&gt;半隐式欧拉起步&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;可变时间步&lt;/td&gt;
					&lt;td&gt;帧率一掉物理就变，不可复现&lt;/td&gt;
					&lt;td&gt;固定时间步 + 步数上限&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;隧道效应&lt;/td&gt;
					&lt;td&gt;高速物体穿墙&lt;/td&gt;
					&lt;td&gt;扫掠检测 / CCD / 子步长&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;法线没归一化&lt;/td&gt;
					&lt;td&gt;碰撞反应大小诡异&lt;/td&gt;
					&lt;td&gt;所有法线使用前 normalize&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;四元数不归一化&lt;/td&gt;
					&lt;td&gt;物体缓慢缩放变形&lt;/td&gt;
					&lt;td&gt;每步积分后归一化&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;摩擦不钳制&lt;/td&gt;
					&lt;td&gt;摩擦反而加速物体&lt;/td&gt;
					&lt;td&gt;库仑摩擦锥约束&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;穿透硬修正&lt;/td&gt;
					&lt;td&gt;抖动、弹跳不止&lt;/td&gt;
					&lt;td&gt;slop + Baumgarte 折扣修正&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;无休眠&lt;/td&gt;
					&lt;td&gt;性能浪费 + 静止抖动&lt;/td&gt;
					&lt;td&gt;速度阈值休眠&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;死亡螺旋&lt;/td&gt;
					&lt;td&gt;卡顿后彻底卡死&lt;/td&gt;
					&lt;td&gt;每帧物理步数设上限&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;十四主流游戏框架与物理引擎&#34;&gt;十四、主流游戏框架与物理引擎&lt;/h2&gt;
&lt;p&gt;上面的原理，主流引擎都已内置实现；学原理的意义在于&lt;strong&gt;调得动、查得准、必要时能绕过&lt;/strong&gt;。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;引擎/框架&lt;/th&gt;
					&lt;th&gt;物理方案&lt;/th&gt;
					&lt;th&gt;备注&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Unity&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;PhysX（3D）、Box2D（2D）&lt;/td&gt;
					&lt;td&gt;Rigidbody / Rigidbody2D，FixedUpdate 即固定时间步&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Unreal Engine&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Chaos（新版）、PhysX（旧版）&lt;/td&gt;
					&lt;td&gt;Chaos 支持破坏、布料等大型模拟&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Godot&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;自研 Godot Physics，可换 Jolt&lt;/td&gt;
					&lt;td&gt;开源，2D/3D 分离&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Box2D&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;2D 物理库（C++）&lt;/td&gt;
					&lt;td&gt;本书思想的工业化实现，愤怒的小鸟、无数 2D 游戏在用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Bullet&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;3D 物理库&lt;/td&gt;
					&lt;td&gt;开源老牌，影视与游戏双用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Jolt&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;3D 物理库&lt;/td&gt;
					&lt;td&gt;《地平线》系列使用，近年性能口碑极好&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;PhysX&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;3D 物理库（NVIDIA）&lt;/td&gt;
					&lt;td&gt;Unity/UE 底层，支持 GPU 加速&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Cocos Creator&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;内置 2D（Box2D/builtin）、3D 可选 PhysX/cannon.js&lt;/td&gt;
					&lt;td&gt;国内小游戏主流&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;LayaAir&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;集成 Bullet（编译为 wasm）&lt;/td&gt;
					&lt;td&gt;国内 3D H5 主流&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Rapier&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Rust 编写，可编译 wasm&lt;/td&gt;
					&lt;td&gt;Web/独立游戏新势力，确定性模拟支持好&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;MuJoCo / PyBullet&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;科研仿真&lt;/td&gt;
					&lt;td&gt;机器人、强化学习训练场景&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;选型直觉：2D 游戏默认 Box2D 系；3D 商用项目跟着引擎走（Unity 用 PhysX、UE 用 Chaos）；网页端想要确定性（帧同步）看 Rapier；做机器人/RL 仿真看 MuJoCo。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;十五学习路径建议&#34;&gt;十五、学习路径建议&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;第一周&lt;/strong&gt;：把向量运算（点积、叉积、归一化）练到不用查，手写一个 2D 抛体模拟（重力 + 半隐式欧拉 + 地面反弹）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第二周&lt;/strong&gt;：给抛体加空气阻力和风，做「炮弹打移动目标」的提前量解算；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第三周&lt;/strong&gt;：实现 2D 刚体（加旋转和转动惯量），偏心受力看旋转；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第四周&lt;/strong&gt;：SAT 碰撞检测 + 冲量法碰撞反应 + 摩擦，让方块能撞、能停、能叠；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;之后&lt;/strong&gt;：挑一个载具（汽车最容易出成就感）做手感调优；有 3D 需求再啃四元数和惯量张量；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;贯穿始终&lt;/strong&gt;：每实现一个特性，先想「这一步在哪个引擎里对应什么参数」，原理和工具互相印证。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&#34;结语&#34;&gt;结语&lt;/h2&gt;
&lt;p&gt;《游戏开发物理学》最大的价值不是那些公式，而是一个思维框架：&lt;strong&gt;任何炫酷的物理效果，拆到最后都是「合力 → 积分 → 碰撞 → 冲量」这条流水线的变体&lt;/strong&gt;。飞机和汽车的差别只在于往「合力」里塞了什么力；刚体和粒子的差别只在于有没有旋转那一半。&lt;/p&gt;
&lt;p&gt;先把这条流水线在小项目里跑通，再去用引擎——你会发现所有参数突然都认识了。&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
