概述

#

SpringDescription 的公式已更改,以修正先前的错误,这会影响质量值不为 1 的欠阻尼弹簧(阻尼比小于 1)。在此更改之前创建的弹簧在升级后可能会表现出不同的回弹行为。

背景

#

SpringDescription 类描述了阻尼弹簧的行为,使 Flutter 小部件能够根据提供的参数进行逼真的动画。阻尼弹簧的物理学已被广泛研究和记录。有关阻尼的概述,请参阅维基百科:阻尼

此前,Flutter 计算欠阻尼弹簧行为的公式不正确,如问题 163858 中所述。此错误影响了所有阻尼比小于 1 且质量不为 1 的弹簧。因此,动画与预期的真实世界物理不符,并且在临界阻尼点(阻尼比恰好为 1)附近的行为表现出不连续性。具体来说,当使用 SpringDescription.withDampingRatio 时,诸如 1.0001 与 0.9999 的阻尼比等微小差异会导致动画显著不同。

该问题已在 PR Fix SpringSimulation formula for underdamping 中得到修正,该 PR 更新了底层计算。因此,之前受影响的动画现在表现不同,尽管框架没有报告任何明确的错误。

迁移指南

#

仅当弹簧的阻尼比小于 1 且质量不为 1 时,才需要进行迁移。

要恢复以前的动画行为,请相应地更新您的弹簧参数。您可以使用提供的用于迁移的 JSFiddle 计算所需的参数调整。详细的公式和解释将在后续章节中提供。

默认构造函数

#

如果 SpringDescription 是使用默认构造函数构建的,其质量为 m、刚度为 k、阻尼为 c,则应使用以下公式进行更改

new_m = 1
new_c = c * m
new_k = (4 * (k / m) - (c / m)^2 + (c * m)^2) / 4

迁移前的代码

dart
const spring = SpringDescription(
  mass: 20.0,
  stiffness: 10,
  damping: 1,
);

迁移后的代码

dart
const spring = SpringDescription(
  mass: 1.0,
  stiffness: 100.499375,
  damping: 20,
);

.withDampingRatio 构造函数

#

如果 SpringDescription 是使用 .withDampingRatio 构造函数构建的,其质量为 m、刚度为 k、比率为 z,则首先计算阻尼

c = z * 2 * sqrt(m * k)

然后应用上述公式。您还可以选择将结果转换回阻尼比,使用

new_z = new_c / 2 / sqrt(new_m * new_k)

迁移前的代码

dart
const spring = SpringDescription.withDampingRatio(
  mass: 5.0,
  stiffness: 6.0,
  damping: 0.03,
);

迁移后的代码

dart
const spring = SpringDescription.withDampingRatio(
  mass: 1,
  stiffness: 1.87392,
  ratio: 0.60017287468545,
);

时间线

#

落地版本:3.31.0-0.1.pre
稳定版本:3.32

参考资料

#

API 文档

相关问题

  • 问题 163858,此处发现了该错误,可找到更多上下文信息。

相关 PR

工具