这是一份从零开始的XPBD(Extended Position Based Dynamics)完整推导文档。我们将从最基础的物理原理出发,通过清晰的逻辑链条,最终得到可在计算机上实现的算法。


第一部分:基础概念

1.1 牛顿第二定律

概念:物体的加速度与所受合外力成正比,与质量成反比。

公式:

例子:一个1kg的小球,受到10N的力,加速度为10 m/s²。

1.2 时间离散化

概念:计算机无法处理连续时间,需要将时间分成小段(时间步长 )。

例子:秒表示每秒更新100次。

1.3 欧拉积分

概念:用差分近似微分,从当前状态推算下一时刻状态。

前向欧拉(显式):

问题:不稳定,大步长容易“爆炸”。

1.4 隐式欧拉

概念:使用未来时刻的力来计算当前更新,数值稳定。

公式:

问题: 同时出现在两边,需要解方程。

例子:弹簧力 ,隐式欧拉会产生一个关于 的方程:


第二部分:从隐式欧拉到优化问题

2.1 消去速度

将第二式代入第一式:

2.2 引入预测位置

定义预测位置:

代入得:

物理意义:位置修正量 = 时间步长平方 × 加速度。

2.3 保守力与势能

概念:保守力是可以用势能函数描述的力,满足 。

例子:重力势能 ,重力 。

在XPBD中,约束力来自约束势能:

其中 是约束函数(如距离约束 )。

2.4 转化为优化问题

关键定理:方程 的解,等价于以下最小化问题的解:

验证:对 求梯度:

令梯度为零,即得方程(1)。


第三部分:Legendre变换

3.1 为什么需要Legendre变换?

问题:式(2)中的势能项 是 的二次函数,而 本身是非线性的。直接处理很困难。

目标:引入一个辅助变量 ,将二次项变成线性项。

3.2 Legendre变换的定义

概念:对于凸函数 ,其Legendre变换为:

推导:

恒等式:

例子:,左边 ;右边对 最大化,,。

3.3 应用到约束势能

令 ,,:

3.4 重写优化问题

将(4)代入(2):

这是一个鞍点问题:对 最小化,对 最大化。


第四部分:最优性条件

4.1 对位置求导

固定 ,对 求导:

得到位置更新公式:

4.2 对 求导

固定 ,对 求导:

得到约束条件:


第五部分:线性化与单约束求解

5.1 为什么需要线性化?

问题:式(6)和(7)是耦合的非线性方程组,不能直接求解。

策略:在当前位置 附近线性化约束,然后一次只处理一个约束。

5.2 泰勒展开

5.3 代入位置更新

对于单个约束 ,假设其他约束的贡献已被吸收进当前位置,我们有:

代入(8)并利用(7):

记 ,其中 。

5.4 解出

5.5 增量形式

设 ,代入(9):

物理意义:分子是当前约束误差减去已有约束力产生的形变。


第六部分:Gauss-Seidel迭代

6.1 什么是Gauss-Seidel迭代?

概念:求解方程组的一种方法,每次更新一个变量,立即使用最新值。

例子:解方程组

Gauss-Seidel迭代:

  1. 假设 ,得
  2. 用 ,得
  3. 用 ,得
  4. 收敛到

6.2 为什么需要Gauss-Seidel?

问题:多个约束共享粒子,不能独立求解。

XPBD的策略:

  • 一次只处理一个约束
  • 立即更新受影响的粒子位置
  • 下一个约束看到的是更新后的位置
  • 多次迭代逼近全局解

6.3 完整算法

输入: 当前位置 p, 逆质量 w, 时间步长 Δt
输出: 更新后的位置 p
 
for iteration = 1 to solver_iterations:
    for each constraint j:
        # 计算当前约束值
        C = C_j(p)
        
        # 计算梯度平方和
        denom = Σ_i w_i * ||∇C_i||²
        
        # 更新 λ
        Δλ = (C - α_j * λ_j) / (α_j + Δt² * denom)
        λ_j = λ_j + Δλ
        
        # 更新位置
        for each particle i in constraint j:
            Δp = -w_i * Δt² * Δλ * ∇C_i
            p_i = p_i + Δp

第七部分:距离约束的具体推导

7.1 约束函数

7.2 梯度计算

设 ,则:

7.3 分母计算

7.4 修正公式

7.5 数值例子

参数:,,,,,。

初始:,,,。

新位置:,,新距离 。


第八部分:完整算法总结

初始化: p, v, λ = 0

每一时间步 Δt:
    # 1. 预测位置
    p* = p + Δt·v + Δt²·M⁻¹·f_ext
    
    # 2. 迭代求解约束
    for iteration = 1 to solver_iterations:
        for each constraint j:
            # 计算当前值
            C = C_j(p)
            ∇C = gradient(C_j, p)
            denom = Σ w_i ||∇C_i||²
            
            # 更新 λ
            Δλ = (C - α_j·λ_j) / (α_j + Δt²·denom)
            λ_j = λ_j + Δλ
            
            # 更新位置
            for each particle i in constraint j:
                p_i = p_i - w_i·Δt²·Δλ·∇C_i
    
    # 3. 更新速度
    v = (p - p_old) / Δt

附录:概念速查表

符号含义公式
位置-
速度-
质量矩阵
逆质量
时间步长-
预测位置
约束函数如 $
柔度(刚度倒数)
拉格朗日乘子约束力大小
分母

文档结束