【问题标题】:How to implement arriving behavior with time delta?如何实现具有时间增量的到达行为?
【发布时间】:2016-08-10 10:28:50
【问题描述】:

我正在尝试根据 Reynolds 的经典 Boids 论文,更具体地说是 Dan Shiffman 在 natureofcode.com 上的实现,创建一个具有到达行为的自主代理。这两种方法都很容易理解(并且有效),但它们都假设一个固定的标称更新步骤,而不是查询自上次帧更新以来经过的时间并在欧拉积分步骤中应用这个时间增量。即他们简单地建议:

//pseudocode
acceleration.add(force);
velocity.add(acceleration);
location.add(velocity);

但是,如果我想包含时间增量,那么各种物理论文建议我应该将其重写为:

//pseudocode
delta = timeElpasedSinceLastFrameUpdate();
acceleration.add(force);
deltaAcceleration = acceleration.mult(delta);
velocity.add(deltaAcceleration );
deltaVelocity = velocity.mult(delta);
location.add(deltaVelocity);

这也有效,直到我尝试实现转向行为,特别是到达行为。有关该方法的参考,请参见此处链接中的示例 6.2:

Nature of Code Steering Behaviours

有问题的步骤(在伪代码中)是转向力 = 期望 - 速度;

在没有时间增量的情况下,“-速度”对转向力的贡献正确地抵消了当前保持的速度矢量,并使物体在到达目的地减速停止。

应用时间增量后,当我将加速度乘以增量时,steeringForce 被分数时间增量有效缓和,因此没有对累积速度施加足够的减速度以使物体及时停止并且我开始振荡行为。

我可以通过不将累积力(即加速度)乘以时间增量来“解决”这个问题,但这似乎不正确。

所以,我的问题:

应如何生成用于到达行为的转向力以考虑可变增量时间?

感谢任何帮助!

【问题讨论】:

    标签: javascript physics


    【解决方案1】:

    编辑:我错过了你问题的主要部分。有很多方法可以得到你想要的结果,但它们是通过不同的方式实现的。我能想到的最简单的方法可能是现在一起跳过steeringForce,而只是修改速度。

    我们想要一个这样的向量

    desired_velocity = velocity + correction
    

    这和你之前写的一样(除了'steeringForce'):

    correction = desired_velocity - velocity
    

    通过velocity + correction,您将立即达到所需的速度,这通常不是您想要的,因为它会导致非常不稳定的运动。相反,您可以将校正钳制为某个值,这会导致更平滑的运动:

    len = length(correction)
    corr_length = len > max_correction ? max_correction : len
    correction = correction/len*corr_length
    

    现在你可以做

    velocity += correction
    

    这应该会导致有点动态的运动,没有振荡。


    显式时间步长集成(例如,在您的情况下为正向欧拉)通常写为

    new_acceleration = old_acceleration + (delta_t/mass)*force
                                                  ^^ note
    

    同样,

    new_velocity = old_velocity + delta_t*acceleration
    new_position = old_position + delta_t*velocity
    

    所以要回答你的问题,你需要在累积之前乘以时间步长:

    acceleration.add(force.mult(delta_t/mass));
    velocity.add(acceleration.mult(delta_t));
    location.add(velocity.mult(delta_t));
    

    【讨论】:

    • 感谢您的详细回复,并对延迟回复表示歉意,我只想查询一件事。我可以看到如何避免使用steeringForce 变量和直接操纵速度可以提供解决方案,但它似乎打破了转向行为的整个原则,即您将力相加以确定施加于加速度的净转向力,其中转弯会影响确定位置的速度。在可变时间步长增量的背景下,有没有办法在这个范式中工作?即获得适当的转向力?
    • @MattGreenhalgh 你说得对,这种方法不太“物理上正确”,因为我们在现实生活中无法做到这一点。但是,我会说对于许多应用程序而言,这种方法(以及对其进行微小改动)就足够了。这实际上是一个控制速度的小型 PID 控制器(参见参考资料);你可以对steeringForce 做同样的事情,但是它会涉及更多一点。由于我不知道您的学术水平,所以我想先提出(对我而言)最直接的解决方案。
    • 再次感谢您的回复。你对我学术水平的直觉是正确的,我可以从(非常有趣的)PID 文章中看到,得出一个“正确”的解决方案并非易事。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-13
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    • 2016-02-19
    相关资源
    最近更新 更多