Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/465.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用时间增量实现到达行为?_Javascript_Physics - Fatal编程技术网

Javascript 如何使用时间增量实现到达行为?

Javascript 如何使用时间增量实现到达行为?,javascript,physics,Javascript,Physics,我试图创建一个具有到达行为的自治代理,它基于Reynolds经典Boids论文,更具体地说是Dan Shiffman在natureofcode.com上的实现。这两种方法都很容易理解(也很有效),但它们都假定一个固定的标称更新步骤,而不是查询自上次帧更新以来经过的时间,并在Euler积分步骤中应用此时间增量。即他们简单地建议: //pseudocode acceleration.add(force); velocity.add(acceleration); location.add(veloci

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

//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:

有问题的步骤(在伪代码中)是steeringForce=所需-速度

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

然而,当我将加速度乘以增量时,应用时间增量,转向力有效地由分数时间增量调节,因此没有对累积速度施加足够的减速度,以使物体及时停止,我得到振荡行为

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

所以,我的问题是:

如何为到达行为生成steeringForce,以考虑可变的增量时间


感谢您的帮助

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

我们需要这样一个向量

desired_velocity = velocity + correction
这与您之前所写的相同(但适用于“steeringForce”):

通过执行
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变量和操纵速度可以提供一个解决方案,但它似乎打破了转向行为的整个原则,即对力求和,以确定应用于加速度的净转向力,而加速度反过来会影响决定位置的速度。在可变时间步长增量的情况下,是否没有办法在这种范式下工作?Ie获得适当的转向力?@MattGreenhalgh你是对的,这种方法“物理上不太正确”,因为我们在现实生活中无法做到这一点。然而,我要说的是,对于许多应用来说,这种方法(以及对它的微小修改)就足够了。这是一个控制速度的小型PID控制器(参见参考资料);您也可以对
steeringForce
执行相同的操作,但是它会涉及更多内容。由于我不知道你的学术水平,我想首先提出最直接的解决方案。再次感谢你的回复。在我的学术水平上,你的直觉是正确的,我可以从(非常有趣的)PID文章中看出,找到一个“正确”的解决方案是非常重要的。谢谢你的帮助。
acceleration.add(force.mult(delta_t/mass));
velocity.add(acceleration.mult(delta_t));
location.add(velocity.mult(delta_t));