gpt4 book ai didi

c# - Verlet Integration 正在炸毁我的物理引擎

转载 作者:太空狗 更新时间:2023-10-29 23:35:34 27 4
gpt4 key购买 nike

我正在构建一个物理引擎,我有某种“伪 verlet”的东西在运行,我想将它升级到“真正的”verlet。所以我找到了一篇文章并开始工作。在我添加了我认为是一个很好的近似值之后,引擎不再工作了。有人可以帮助我了解我做错了什么吗?

我的主要物理体类的更新、施加力和应用脉冲系统:

public void Update(float timestepLength)
{
if (!this._isStatic)
{
Vector2 velocity = Vector2.Subtract(_position, _lastPosition);
Vector2 nextPos = _position + (_position - _lastPosition) + _acceleration * (timestepLength * timestepLength);
_lastPosition = _position;
_position = nextPos;
_acceleration = Vector2.Zero;
}
}

public void ApplyForce(Vector2 accelerationValue)
{
if (!this._isStatic)
_acceleration += (accelerationValue) * _mass;
}
public void ApplyImpulse(Vector2 impulse)
{
if (!this._isStatic)
_acceleration +=-1 * impulse;
}

编辑:我已经修复它并且它像一个魅力一样工作,但我对以下代码有两个问题:

  • 脉冲应用代码是否正确,如果不正确应该是什么?
  • 如何更改位置属性,以便在设置时保持 body 的当前速度?

代码如下:

public Vector2 Position
{
get { return _position; }
set { _position = value;}
}
public void Update(float timestepLength)
{
if (!this._isStatic)
{
Vector2 velocity = Vector2.Subtract(_position, _lastPosition);
Vector2 velocityChange = Vector2.Subtract(velocity, Vector2.Subtract(_lastPosition, _twoStepsAgoPosition));
Vector2 nextPos = _position + (_position - _lastPosition) + _acceleration * (timestepLength * timestepLength);
_twoStepsAgoPosition = _lastPosition;
_lastPosition = _position;
_position = nextPos;
_acceleration = Vector2.Multiply(velocityChange, timestepLength);
}
}

public void ApplyForce(Vector2 force)
{
if (!this._isStatic)
_lastPosition -= force;
}
public void ApplyImpulse(Vector2 impulse)
{
if (!this._isStatic)
_acceleration +=-1 * impulse;
}

最佳答案

作为对其他人的引用...您可能引用的 verlet 论文是这样的:advanced character physics由创造 killer 的团队制作,并且是最早拥有基于布娃娃的物理学的团队之一

无论如何...他们使用的原始代码是:

 void ParticleSystem::Verlet() {
for(int i=0; i<NUM_PARTICLES; i++) {
Vector3& x = m_x[i];
Vector3 temp = x;
Vector3& oldx = m_oldx[i];
Vector3& a = m_a[i];
x += x-oldx+a*fTimeStep*fTimeStep;
oldx = temp;
}
}

你说得对,你的代码做了类似的事情。

总是让我的模拟失败的一件事是使用了太大的时间步长。此外,通过此 verlet 集成,确保您使用的时间步长在整个游戏中保持不变。 (例如 30 帧/秒(因此时间步长为 1/30))并且不会波动。如果是这样,您应该使用 time corrected verlet integration这说明了这一点

编辑:

问题 2 的答案:要移动您的位置(不改变速度/加速度)只需将位置更新为新位置,然后作为额外步骤将此移动的增量(所以 newPosition-oldPosition)添加到 oldposs,所以这会相应更新。

问题 1 的答案:冲量是在一段时间内施加在物体上的力。所以你的解决方案是不正确的。冲动是在 X 时间步(或帧)上,您使用固定力调用 applyForce 函数。

关于c# - Verlet Integration 正在炸毁我的物理引擎,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1599376/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com