第一步:问题设定

我们有一个物理系统,包含 个粒子。每个粒子的位置为 ,质量为 。系统的总位置向量记作:

质量矩阵为对角矩阵:

系统受到一组约束,但我们不要求约束被严格满足。相反,我们给每个约束赋予一个弹性势能。对于单个约束 (C(x) \in \mathbb{R}),其势能定义为:

其中 是柔度(compliance),物理意义是刚度的倒数,单位是米/牛顿。对于多个约束,总势能是各约束势能之和。


第二步:隐式时间积分

我们采用隐式欧拉法进行时间步进。从时间 到 ,运动方程为:

为了方便,定义预测位置(也叫惯性位置):

(这里假设速度是 ,所以 。)

代入运动方程,整理得:

令 ,则方程变为:


第三步:引入拉格朗日乘子

对于每个约束 ,其势能梯度为:

代入运动方程:

令

注意: 是时间尺度调整后的柔度,它的引入是 XPBD 能够解耦时间步长的关键。

现在,我们定义一个拉格朗日乘子向量(对于多约束系统):

注意:这是定义,不是推导。它的作用是把非线性方程拆成两个联立的线性方程。

根据这个定义,我们有:

并且运动方程可以改写为:


第四步:联立方程组

我们现在有了一个关于 和 的联立方程组:

注意这里 。


第五步:线性化(牛顿迭代的一步)

方程组是非线性的,因为 和 都依赖于未知的 。我们采用单步牛顿法来近似求解。

将 在预测位置 处一阶泰勒展开:

将梯度也近似为在 处的值:

代入联立方程组:

其中 ,。


第六步:求解 (\Delta \lambda) 和 (\Delta x)

从第一个方程解出 :

代入第二个方程:

解得:

然后代回求 :


第七步:迭代形式(XPBD 的核心)

上面的推导给出的是单次牛顿步的解。但在实际模拟中,我们需要多次迭代来收敛到非线性方程组的真解。更重要的是,XPBD 的 是累积的,它代表从时间步开始以来累积的总约束冲量。

因此,我们采用迭代更新的形式。设当前迭代步的乘子为 (初始为上一帧结束时保留的值,或零),我们计算增量 :

由约束方程的一阶展开(注意此时当前位置是 ,而不是 ):

代入 :

整理得:

解得:

然后更新:


第八步:完整算法流程

对于每一帧:

  1. 对于所有粒子,计算预测位置
  2. 初始化所有约束的 (或者保留上一帧的值)
  3. 重复若干次(求解迭代):
    • 对于每个约束:
      • 计算 和
      • 计算
      • 更新
      • 计算
      • 更新
  4. 更新速度:
  5. 更新位置:

推导中的关键点总结

步骤关键操作物理/数学意义
1定义弹性势能,赋予约束物理刚度
2时间步长解耦,保证材料属性一致
3引入对偶变量,将非线性方程拆为联立方程
4泰勒展开 线性化,使问题可解
5迭代更新 累积乘子,解耦迭代次数与刚度
6分母加 正则化项,防止柔度为零时除零

这就是 XPBD 从物理原理到数值算法的完整推导链条。