2025-11-30 · game_math
【游戏中的数学】游戏中的数学 (8) - 运动学基础
如何让物体动起来?详解速度、加速度与积分器。比较欧拉积分与韦尔莱积分的优劣,以及如何模拟抛物线运动。
检测到碰撞只是第一步(我们在几何章节讨论了检测),更重要的是响应 (Response)。 物体是反弹?是停下?还是滑行?这取决于物理材质的属性:弹力 (Bounciness) 和摩擦力 (Friction)。
上一篇我们学习了运动学 (Kinematics)——描述物体如何运动。 本篇将进入动力学 (Dynamics)——回答物体为什么这样运动,并用它来构建完整的碰撞响应系统。
最常见的响应是”反弹”。例如光线反射、台球撞击。 我们需要根据入射向量 \(\vec{v}\) 和碰撞表面的法线 \(\vec{n}\) 计算出反射向量 \(\vec{r}\)。
公式如下: \[ \vec{r} = \vec{v} - 2(\vec{v} \cdot \vec{n})\vec{n} \]
推导: 1. \(\vec{v}\) 在法线方向的分量是 \((\vec{v} \cdot \vec{n})\vec{n}\)。 2. 要反转这个分量,我们需要减去它两次(一次抵消,一次反向)。
代码实现:
// Unity 内置函数
Vector3 reflection = Vector3.Reflect(velocity, hitNormal);
// 手动实现
Vector3 Reflect(Vector3 v, Vector3 n) {
return v - 2f * Vector3.Dot(v, n) * n;
}现实世界中,能量总会损耗。我们引入一个恢复系数 (Coefficient of Restitution, \(e\)),通常称为 Bounciness。
恢复系数的严格定义基于碰撞前后的相对速度在法线方向上的比值:
\[ e = -\frac{v_{rel}' \cdot \vec{n}}{v_{rel} \cdot \vec{n}} \]
对于简单的墙壁反弹,法线方向的速度分量取反并乘以 \(e\):
\[ v_n' = -e \cdot v_n \]
在深入碰撞冲量之前,我们需要从运动学过渡到动力学。运动学告诉我们位置、速度和加速度的关系,而动力学则引入了力 (Force) 和质量 (Mass) 来解释运动的原因。
力是使物体加速的原因:
\[ \vec{F} = m \vec{a} \]
其中 \(m\) 是质量 (Mass),\(\vec{a}\) 是加速度 (Acceleration)。 质量越大的物体,同样的力产生的加速度越小——这就是惯性 (Inertia)。
动量是物体运动状态的量度,定义为质量与速度的乘积:
\[ \vec{p} = m\vec{v} \]
动量是一个矢量,方向与速度相同。 一辆 2000 kg 的卡车以 10 m/s 行驶,动量为 \(20000 \text{ kg·m/s}\); 一个 0.17 kg 的台球以 5 m/s 滚动,动量仅为 \(0.85 \text{ kg·m/s}\)。
当两个物体组成的系统不受外力时,总动量守恒:
\[ m_1\vec{v}_1 + m_2\vec{v}_2 = m_1\vec{v}_1' + m_2\vec{v}_2' \]
这是碰撞响应最核心的约束条件——碰撞前后,系统的总动量不变。
牛顿第二定律可以改写为动量的变化率形式:
\[ \vec{F} = \frac{d\vec{p}}{dt} \]
对时间积分得到冲量 (Impulse) \(\vec{J}\):
\[ \vec{J} = \int \vec{F} \, dt = \Delta \vec{p} = m\vec{v}' - m\vec{v} \]
碰撞发生在极短的时间内(\(\Delta t \to 0\)),力非常大但持续时间极短。 我们不关心力的具体大小,只关心它对速度的总效果——这正是冲量。
碰撞时物体 A 对物体 B 施加的冲量与 B 对 A 施加的冲量大小相等、方向相反:
\[ \vec{J}_A = -\vec{J}_B \]
这保证了总动量的守恒。
有了动力学工具,我们可以正式推导两个刚体碰撞时的冲量公式。
设两个球体质量分别为 \(m_1\), \(m_2\),碰撞前速度为 \(\vec{v}_1\), \(\vec{v}_2\),碰撞法线为 \(\vec{n}\)(从物体 1 指向物体 2),恢复系数为 \(e\)。
相对速度 (Relative Velocity): \[ \vec{v}_{rel} = \vec{v}_1 - \vec{v}_2 \]
如果 \(\vec{v}_{rel} \cdot \vec{n} > 0\),说明两物体正在分离,无需响应。
由冲量-动量定理,碰撞后速度为:
\[ \vec{v}_1' = \vec{v}_1 + \frac{j}{m_1}\vec{n} \] \[ \vec{v}_2' = \vec{v}_2 - \frac{j}{m_2}\vec{n} \]
其中 \(j\) 是冲量的标量大小(沿法线方向),正值表示将物体 1 推离物体 2。
代入恢复系数的定义 \(e = -\frac{\vec{v}_{rel}' \cdot \vec{n}}{\vec{v}_{rel} \cdot \vec{n}}\),展开碰撞后的相对速度:
\[ \vec{v}_{rel}' \cdot \vec{n} = (\vec{v}_1' - \vec{v}_2') \cdot \vec{n} = \vec{v}_{rel} \cdot \vec{n} + j\left(\frac{1}{m_1} + \frac{1}{m_2}\right) \]
代入恢复系数方程并求解 \(j\):
\[ \boxed{j = \frac{-(1 + e) \, \vec{v}_{rel} \cdot \vec{n}}{\frac{1}{m_1} + \frac{1}{m_2}}} \]
这就是碰撞冲量公式,是所有刚体物理引擎的核心。
struct RigidBody {
public Vector3 velocity;
public float mass;
public float inverseMass; // 1/mass,静态物体设为 0
}
void ResolveCollision(ref RigidBody a, ref RigidBody b,
Vector3 normal, float restitution)
{
Vector3 vRel = a.velocity - b.velocity;
float vAlongNormal = Vector3.Dot(vRel, normal);
// 正在分离则跳过
if (vAlongNormal > 0f) return;
float j = -(1f + restitution) * vAlongNormal
/ (a.inverseMass + b.inverseMass);
Vector3 impulse = j * normal;
a.velocity += a.inverseMass * impulse;
b.velocity -= b.inverseMass * impulse;
}提示: 使用
inverseMass而非mass是物理引擎的常见做法。 静态/不可移动物体的inverseMass = 0,无需特殊判断就自然不会受力移动。
碰撞不仅在法线方向产生冲量,在切线方向 (Tangential Direction) 也会因摩擦产生冲量。 真实的摩擦模型遵循库仑摩擦定律 (Coulomb Friction Law)。
碰撞点的相对速度可以分解为法线分量和切线分量:
\[ v_n = (\vec{v}_{rel} \cdot \vec{n}) \vec{n} \] \[ \vec{v}_t = \vec{v}_{rel} - v_n \]
切线方向的单位向量为: \[ \vec{t} = \frac{\vec{v}_t}{|\vec{v}_t|} \]
如果 \(|\vec{v}_t| \approx 0\),说明没有滑动,可跳过摩擦计算。
库仑摩擦将摩擦分为静摩擦 (Static Friction) 和动摩擦 (Kinetic Friction):
切线方向的摩擦冲量大小 \(j_t\) 首先按无摩擦约束求解:
\[ j_t = \frac{-\vec{v}_{rel} \cdot \vec{t}}{\frac{1}{m_1} + \frac{1}{m_2}} \]
然后应用库仑约束:
\[ j_t^{final} = \begin{cases} j_t & \text{if } |j_t| \leq \mu_s |j| \quad \text{(静摩擦,完全停止滑动)} \\ -\mu_k |j| & \text{if } |j_t| > \mu_s |j| \quad \text{(动摩擦,部分减速)} \end{cases} \]
其中 \(j\) 是法线方向的冲量大小(上一节求出的值)。
void ApplyFriction(ref RigidBody a, ref RigidBody b,
Vector3 normal, float jNormal,
float staticFriction, float kineticFriction)
{
Vector3 vRel = a.velocity - b.velocity;
// 切线分量
Vector3 vt = vRel - Vector3.Dot(vRel, normal) * normal;
if (vt.sqrMagnitude < 1e-6f) return;
Vector3 tangent = vt.normalized;
float jt = -Vector3.Dot(vRel, tangent)
/ (a.inverseMass + b.inverseMass);
Vector3 frictionImpulse;
if (Mathf.Abs(jt) <= staticFriction * Mathf.Abs(jNormal)) {
// 静摩擦:完全抵消切线速度
frictionImpulse = jt * tangent;
} else {
// 动摩擦:施加固定大小的摩擦冲量
frictionImpulse = -kineticFriction * Mathf.Abs(jNormal) * tangent;
}
a.velocity += a.inverseMass * frictionImpulse;
b.velocity -= b.inverseMass * frictionImpulse;
}让我们用一个完整的台球碰撞例子把前面的知识串联起来。
场景设定: - 球 A:\(m = 0.17\) kg,\(\vec{v}_A = (2, 0)\) m/s(向右运动)。 - 球 B:\(m = 0.17\) kg,\(\vec{v}_B = (0, 0)\) m/s(静止)。 - 碰撞法线:\(\vec{n} = (1, 0)\)(A 正面撞 B)。 - 恢复系数:\(e = 0.95\)(台球接近完全弹性)。 - 动摩擦系数:\(\mu_k = 0.05\)。
第一步:检查碰撞
\[ \vec{v}_{rel} = (2, 0) - (0, 0) = (2, 0) \] \[ \vec{v}_{rel} \cdot \vec{n} = 2 \times 1 + 0 \times 0 = 2 > 0 \]
等等——结果大于零?这是因为我们的法线从 A 指向 B,相对速度沿法线正方向意味着 A 正在靠近 B。在本文的约定中,法线从物体 1 指向物体 2,所以 \(\vec{v}_{rel} \cdot \vec{n} < 0\) 才表示靠近。让我们修正法线方向:\(\vec{n} = (-1, 0)\)(从 B 指向 A,即碰撞面法线指向物体 1)。
\[ \vec{v}_{rel} \cdot \vec{n} = 2 \times (-1) = -2 < 0 \quad \checkmark \text{(正在靠近)} \]
第二步:计算法线冲量
\[ j = \frac{-(1 + 0.95) \times (-2)}{\frac{1}{0.17} + \frac{1}{0.17}} = \frac{3.9}{11.76} \approx 0.3316 \text{ N·s} \]
第三步:更新速度
\[ \vec{v}_A' = (2, 0) + \frac{0.3316}{0.17} \times (-1, 0) = (2 - 1.95, 0) = (0.05, 0) \] \[ \vec{v}_B' = (0, 0) - \frac{0.3316}{0.17} \times (-1, 0) = (1.95, 0) \]
验证动量守恒: - 碰撞前:\(0.17 \times 2 + 0.17 \times 0 = 0.34\) - 碰撞后:\(0.17 \times 0.05 + 0.17 \times 1.95 = 0.34\) ✓
验证恢复系数: \[ e = -\frac{(0.05 - 1.95) \cdot (-1)}{(2 - 0) \cdot (-1)} = -\frac{1.9}{-2} = 0.95 \quad \checkmark \]
球 A 几乎停下,球 B 获得了大部分速度——这正是台球中”定杆”的效果。
第四步:摩擦(侧旋场景)
如果球 A 带有侧向速度 \(\vec{v}_A = (2, 0.5)\),碰撞后切线分量 \(\vec{v}_t\) 不为零:
\[ \vec{v}_t = (0, 0.5) \quad \Rightarrow \quad \vec{t} = (0, 1) \]
摩擦冲量约束:\(\mu_k |j| = 0.05 \times 0.3316 = 0.0166\) N·s, 切线方向的速度变化很小,球会保留大部分侧向运动——这就是台球中”偏杆”产生的走位效果。
工程提示:在实际物理引擎中,静摩擦与动摩擦的切换需要加入 Hysteresis(迟滞)死区。如果不加死区,当切线速度在静/动摩擦阈值附近振荡时,物体会出现抖动。常见做法是:当切线力超过 \(\mu_s \cdot |j|\) 时切换到动摩擦,但要等切线速度降到某个更低阈值时才切回静摩擦。
inverseMass
可以统一处理静态物体和动态物体。< 上一篇: 运动学基础 | 回到目录 | 下一篇: 渲染管线 >
把当前热点继续串成多页阅读,而不是停在单篇消费。
2025-11-30 · game_math
如何让物体动起来?详解速度、加速度与积分器。比较欧拉积分与韦尔莱积分的优劣,以及如何模拟抛物线运动。
2025-11-30 · game_math
从射线检测到包围盒碰撞。详解 Raycast 原理、AABB 碰撞检测算法以及它们在物理引擎中的应用。
2025-11-30 · game_math
详解游戏引擎中常用的标量数学函数:Lerp, InverseLerp, Remap, Clamp, SmoothStep 等。不仅有公式,更有实际应用场景。
2025-11-30 · game_math
深入浅出地讲解游戏开发中的三角函数:Sin, Cos, Atan2。从单位圆原理到圆周运动、波浪动画和朝向计算的实际应用。
检测到碰撞只是第一步(我们在几何章节讨论了检测),更重要的是响应 (Response)。 物体是反弹?是停下?还是滑行?这取决于物理材质的属性:弹力 (Bounciness) 和摩擦力 (Friction)。
上一篇我们学习了运动学 (Kinematics)——描述物体如何运动。 本篇将进入动力学 (Dynamics)——回答物体为什么这样运动,并用它来构建完整的碰撞响应系统。
最常见的响应是”反弹”。例如光线反射、台球撞击。 我们需要根据入射向量 \(\vec{v}\) 和碰撞表面的法线 \(\vec{n}\) 计算出反射向量 \(\vec{r}\)。
公式如下: \[ \vec{r} = \vec{v} - 2(\vec{v} \cdot \vec{n})\vec{n} \]
推导: 1. \(\vec{v}\) 在法线方向的分量是 \((\vec{v} \cdot \vec{n})\vec{n}\)。 2. 要反转这个分量,我们需要减去它两次(一次抵消,一次反向)。
代码实现:
// Unity 内置函数
Vector3 reflection = Vector3.Reflect(velocity, hitNormal);
// 手动实现
Vector3 Reflect(Vector3 v, Vector3 n) {
return v - 2f * Vector3.Dot(v, n) * n;
}现实世界中,能量总会损耗。我们引入一个恢复系数 (Coefficient of Restitution, \(e\)),通常称为 Bounciness。
恢复系数的严格定义基于碰撞前后的相对速度在法线方向上的比值:
\[ e = -\frac{v_{rel}' \cdot \vec{n}}{v_{rel} \cdot \vec{n}} \]
对于简单的墙壁反弹,法线方向的速度分量取反并乘以 \(e\):
\[ v_n' = -e \cdot v_n \]
在深入碰撞冲量之前,我们需要从运动学过渡到动力学。运动学告诉我们位置、速度和加速度的关系,而动力学则引入了力 (Force) 和质量 (Mass) 来解释运动的原因。
力是使物体加速的原因:
\[ \vec{F} = m \vec{a} \]
其中 \(m\) 是质量 (Mass),\(\vec{a}\) 是加速度 (Acceleration)。 质量越大的物体,同样的力产生的加速度越小——这就是惯性 (Inertia)。
动量是物体运动状态的量度,定义为质量与速度的乘积:
\[ \vec{p} = m\vec{v} \]
动量是一个矢量,方向与速度相同。 一辆 2000 kg 的卡车以 10 m/s 行驶,动量为 \(20000 \text{ kg·m/s}\); 一个 0.17 kg 的台球以 5 m/s 滚动,动量仅为 \(0.85 \text{ kg·m/s}\)。
当两个物体组成的系统不受外力时,总动量守恒:
\[ m_1\vec{v}_1 + m_2\vec{v}_2 = m_1\vec{v}_1' + m_2\vec{v}_2' \]
这是碰撞响应最核心的约束条件——碰撞前后,系统的总动量不变。
牛顿第二定律可以改写为动量的变化率形式:
\[ \vec{F} = \frac{d\vec{p}}{dt} \]
对时间积分得到冲量 (Impulse) \(\vec{J}\):
\[ \vec{J} = \int \vec{F} \, dt = \Delta \vec{p} = m\vec{v}' - m\vec{v} \]
碰撞发生在极短的时间内(\(\Delta t \to 0\)),力非常大但持续时间极短。 我们不关心力的具体大小,只关心它对速度的总效果——这正是冲量。
碰撞时物体 A 对物体 B 施加的冲量与 B 对 A 施加的冲量大小相等、方向相反:
\[ \vec{J}_A = -\vec{J}_B \]
这保证了总动量的守恒。
有了动力学工具,我们可以正式推导两个刚体碰撞时的冲量公式。
设两个球体质量分别为 \(m_1\), \(m_2\),碰撞前速度为 \(\vec{v}_1\), \(\vec{v}_2\),碰撞法线为 \(\vec{n}\)(从物体 1 指向物体 2),恢复系数为 \(e\)。
相对速度 (Relative Velocity): \[ \vec{v}_{rel} = \vec{v}_1 - \vec{v}_2 \]
如果 \(\vec{v}_{rel} \cdot \vec{n} > 0\),说明两物体正在分离,无需响应。
由冲量-动量定理,碰撞后速度为:
\[ \vec{v}_1' = \vec{v}_1 + \frac{j}{m_1}\vec{n} \] \[ \vec{v}_2' = \vec{v}_2 - \frac{j}{m_2}\vec{n} \]
其中 \(j\) 是冲量的标量大小(沿法线方向),正值表示将物体 1 推离物体 2。
代入恢复系数的定义 \(e = -\frac{\vec{v}_{rel}' \cdot \vec{n}}{\vec{v}_{rel} \cdot \vec{n}}\),展开碰撞后的相对速度:
\[ \vec{v}_{rel}' \cdot \vec{n} = (\vec{v}_1' - \vec{v}_2') \cdot \vec{n} = \vec{v}_{rel} \cdot \vec{n} + j\left(\frac{1}{m_1} + \frac{1}{m_2}\right) \]
代入恢复系数方程并求解 \(j\):
\[ \boxed{j = \frac{-(1 + e) \, \vec{v}_{rel} \cdot \vec{n}}{\frac{1}{m_1} + \frac{1}{m_2}}} \]
这就是碰撞冲量公式,是所有刚体物理引擎的核心。
struct RigidBody {
public Vector3 velocity;
public float mass;
public float inverseMass; // 1/mass,静态物体设为 0
}
void ResolveCollision(ref RigidBody a, ref RigidBody b,
Vector3 normal, float restitution)
{
Vector3 vRel = a.velocity - b.velocity;
float vAlongNormal = Vector3.Dot(vRel, normal);
// 正在分离则跳过
if (vAlongNormal > 0f) return;
float j = -(1f + restitution) * vAlongNormal
/ (a.inverseMass + b.inverseMass);
Vector3 impulse = j * normal;
a.velocity += a.inverseMass * impulse;
b.velocity -= b.inverseMass * impulse;
}提示: 使用
inverseMass而非mass是物理引擎的常见做法。 静态/不可移动物体的inverseMass = 0,无需特殊判断就自然不会受力移动。
碰撞不仅在法线方向产生冲量,在切线方向 (Tangential Direction) 也会因摩擦产生冲量。 真实的摩擦模型遵循库仑摩擦定律 (Coulomb Friction Law)。
碰撞点的相对速度可以分解为法线分量和切线分量:
\[ v_n = (\vec{v}_{rel} \cdot \vec{n}) \vec{n} \] \[ \vec{v}_t = \vec{v}_{rel} - v_n \]
切线方向的单位向量为: \[ \vec{t} = \frac{\vec{v}_t}{|\vec{v}_t|} \]
如果 \(|\vec{v}_t| \approx 0\),说明没有滑动,可跳过摩擦计算。
库仑摩擦将摩擦分为静摩擦 (Static Friction) 和动摩擦 (Kinetic Friction):
切线方向的摩擦冲量大小 \(j_t\) 首先按无摩擦约束求解:
\[ j_t = \frac{-\vec{v}_{rel} \cdot \vec{t}}{\frac{1}{m_1} + \frac{1}{m_2}} \]
然后应用库仑约束:
\[ j_t^{final} = \begin{cases} j_t & \text{if } |j_t| \leq \mu_s |j| \quad \text{(静摩擦,完全停止滑动)} \\ -\mu_k |j| & \text{if } |j_t| > \mu_s |j| \quad \text{(动摩擦,部分减速)} \end{cases} \]
其中 \(j\) 是法线方向的冲量大小(上一节求出的值)。
void ApplyFriction(ref RigidBody a, ref RigidBody b,
Vector3 normal, float jNormal,
float staticFriction, float kineticFriction)
{
Vector3 vRel = a.velocity - b.velocity;
// 切线分量
Vector3 vt = vRel - Vector3.Dot(vRel, normal) * normal;
if (vt.sqrMagnitude < 1e-6f) return;
Vector3 tangent = vt.normalized;
float jt = -Vector3.Dot(vRel, tangent)
/ (a.inverseMass + b.inverseMass);
Vector3 frictionImpulse;
if (Mathf.Abs(jt) <= staticFriction * Mathf.Abs(jNormal)) {
// 静摩擦:完全抵消切线速度
frictionImpulse = jt * tangent;
} else {
// 动摩擦:施加固定大小的摩擦冲量
frictionImpulse = -kineticFriction * Mathf.Abs(jNormal) * tangent;
}
a.velocity += a.inverseMass * frictionImpulse;
b.velocity -= b.inverseMass * frictionImpulse;
}让我们用一个完整的台球碰撞例子把前面的知识串联起来。
场景设定: - 球 A:\(m = 0.17\) kg,\(\vec{v}_A = (2, 0)\) m/s(向右运动)。 - 球 B:\(m = 0.17\) kg,\(\vec{v}_B = (0, 0)\) m/s(静止)。 - 碰撞法线:\(\vec{n} = (1, 0)\)(A 正面撞 B)。 - 恢复系数:\(e = 0.95\)(台球接近完全弹性)。 - 动摩擦系数:\(\mu_k = 0.05\)。
第一步:检查碰撞
\[ \vec{v}_{rel} = (2, 0) - (0, 0) = (2, 0) \] \[ \vec{v}_{rel} \cdot \vec{n} = 2 \times 1 + 0 \times 0 = 2 > 0 \]
等等——结果大于零?这是因为我们的法线从 A 指向 B,相对速度沿法线正方向意味着 A 正在靠近 B。在本文的约定中,法线从物体 1 指向物体 2,所以 \(\vec{v}_{rel} \cdot \vec{n} < 0\) 才表示靠近。让我们修正法线方向:\(\vec{n} = (-1, 0)\)(从 B 指向 A,即碰撞面法线指向物体 1)。
\[ \vec{v}_{rel} \cdot \vec{n} = 2 \times (-1) = -2 < 0 \quad \checkmark \text{(正在靠近)} \]
第二步:计算法线冲量
\[ j = \frac{-(1 + 0.95) \times (-2)}{\frac{1}{0.17} + \frac{1}{0.17}} = \frac{3.9}{11.76} \approx 0.3316 \text{ N·s} \]
第三步:更新速度
\[ \vec{v}_A' = (2, 0) + \frac{0.3316}{0.17} \times (-1, 0) = (2 - 1.95, 0) = (0.05, 0) \] \[ \vec{v}_B' = (0, 0) - \frac{0.3316}{0.17} \times (-1, 0) = (1.95, 0) \]
验证动量守恒: - 碰撞前:\(0.17 \times 2 + 0.17 \times 0 = 0.34\) - 碰撞后:\(0.17 \times 0.05 + 0.17 \times 1.95 = 0.34\) ✓
验证恢复系数: \[ e = -\frac{(0.05 - 1.95) \cdot (-1)}{(2 - 0) \cdot (-1)} = -\frac{1.9}{-2} = 0.95 \quad \checkmark \]
球 A 几乎停下,球 B 获得了大部分速度——这正是台球中”定杆”的效果。
第四步:摩擦(侧旋场景)
如果球 A 带有侧向速度 \(\vec{v}_A = (2, 0.5)\),碰撞后切线分量 \(\vec{v}_t\) 不为零:
\[ \vec{v}_t = (0, 0.5) \quad \Rightarrow \quad \vec{t} = (0, 1) \]
摩擦冲量约束:\(\mu_k |j| = 0.05 \times 0.3316 = 0.0166\) N·s, 切线方向的速度变化很小,球会保留大部分侧向运动——这就是台球中”偏杆”产生的走位效果。
工程提示:在实际物理引擎中,静摩擦与动摩擦的切换需要加入 Hysteresis(迟滞)死区。如果不加死区,当切线速度在静/动摩擦阈值附近振荡时,物体会出现抖动。常见做法是:当切线力超过 \(\mu_s \cdot |j|\) 时切换到动摩擦,但要等切线速度降到某个更低阈值时才切回静摩擦。
inverseMass
可以统一处理静态物体和动态物体。< 上一篇: 运动学基础 | 回到目录 | 下一篇: 渲染管线 >
把当前热点继续串成多页阅读,而不是停在单篇消费。
2025-11-30 · game_math
如何让物体动起来?详解速度、加速度与积分器。比较欧拉积分与韦尔莱积分的优劣,以及如何模拟抛物线运动。
2025-11-30 · game_math
从射线检测到包围盒碰撞。详解 Raycast 原理、AABB 碰撞检测算法以及它们在物理引擎中的应用。
2025-11-30 · game_math
详解游戏引擎中常用的标量数学函数:Lerp, InverseLerp, Remap, Clamp, SmoothStep 等。不仅有公式,更有实际应用场景。
2025-11-30 · game_math
深入浅出地讲解游戏开发中的三角函数:Sin, Cos, Atan2。从单位圆原理到圆周运动、波浪动画和朝向计算的实际应用。