1 · 质点和距离约束
没有「刚体」这种东西,全场只有一堆质点。用 Verlet 积分推它们往下掉, 再反复把每两个相连的质点拉回原本的距离。这就是 mass-spring model。
原项目是个 C++ 写的 2D 软体物理引擎,效果很好,但要看到得先装 SFML 和 CMake 编译。 这里把它的算法用 JS 重写了一遍,直接用鼠标(或手指)拖、甩、扔。
没有「刚体」这种东西,全场只有一堆质点。用 Verlet 积分推它们往下掉, 再反复把每两个相连的质点拉回原本的距离。这就是 mass-spring model。
果冻不塌,是因为它的轮廓面积被约束住了:算出当前围成的面积, 和静止面积差多少,就顺着面积对每个质点的梯度方向把它们推回去。拖压强滑块就是在改这个目标面积。
箱子能堆四层不倒,靠的是每帧求一个最贴合原始形状的旋转, 再把质点往这个「理想位置」拉。拉满就接近刚体,拉一点点就是有记忆的软体。
质点掉进别人的多边形里,就沿最近的边推出来,反作用力按质量分给这条边的两个端点, 再削掉一点切向速度当摩擦。整套求解器是 PBD——只改位置,速度自己就对了。
想看这几条约束在代码里长什么样:算法笔记 →
QuarkPhysics 是Eray Zesen 写的 2D 物理引擎,C++,MIT 协议,2023 年 4 月开源,至今仍在更新。 它同时支持刚体和软体:mass-spring、面积体积保持、形状匹配、自碰撞、PBD dynamics, 还有一个 Godot 引擎的绑定版本。
本站不是移植,是照着它公开的算法思路用 JavaScript 重新实现的一个玩具版, 手感和精度都不代表原引擎水平。要认真做游戏,请直接用原项目。