本文介绍了如何实现具有时间增量的到达行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试基于雷诺的经典Boids论文,更具体地说是Dan Shiffman在natureofcode.com上的实现,来创建具有到达行为的自治代理.这两种方法都易于理解(和工作),但是它们都采用固定的标称更新步骤,而不是查询自上一帧更新以来经过的时间并在Euler积分步骤中应用此时间增量.即,他们只是建议:

I'm trying to create an autonomous agent with arriving behaviour based on Reynolds classic Boids paper and more specifically Dan Shiffman's implementation on natureofcode.com. Both of these approaches are easy to understand (and work) but they both assume a fixed nominal update step rather than querying the elapsed time since the last frame update and applying this time delta during the Euler integration step. Ie they suggest simply:

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

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

however if I want to include a time delta then various physics papers suggest I should rewrite this as:

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

这也有效,直到我尝试实现转向行为,尤其是即将到来的行为.有关方法的参考,请参见此处的链接中的示例6.2:

This also works until I try to implement the steering behaviours and specifically the arriving behaviour. For reference to the methodology see example 6.2 in the link here:

代码指导行为的本质

有问题的步骤(用伪代码)是steeringForce =期望的-速度;

The problematic step (in pseudocode) is steeringForce = desired - velocity;

在没有施加时间增量的情况下,'-速度'对转向力的作用会正确抵消当前保持的速度矢量,并使物体在到达目的地时减速停止.

Without a time delta applied the contribution of '- velocity' to the steering force correctly counteracts the currently held velocity vector and brings the object to a decelerating stop at the arrival destination.

在应用时间增量的情况下,当我将加速度乘以增量时,steeringForce会有效地由分数时间增量来缓和,因此对累积的速度没有施加足够的减速度,无法使对象及时停止并发生振荡行为.

With a time delta applied however the steeringForce is effectively moderated by the fractional time delta when I multiply acceleration by delta and hence doesn't apply sufficient deceleration to the accumulated velocity to bring the object to a halt in time and I get oscillating behaviour.

我可以通过不将累积的力(即加速度)乘以时间增量来解决"这一问题,但这似乎并不正确.

I can 'fix' this by not multiplying accumulated forces (i.e. acceleration) by time delta but this doesn't seem correct.

所以,我的问题:

应如何生成用于到达行为的steeringForce来解释可变的增量时间?

How should a steeringForce for arrival behaviour be generated to account for variable delta time?

任何帮助表示感谢!

推荐答案

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

I missed the main part of your question. There are many ways to get the result you want, but they do so by different means. The easiest I can come up with is probably to skip the steeringForce for now all together and instead just modify the velocity.

我们想要一个这样的向量

We want a vector such that

desired_velocity = velocity + correction

这与您之前写的相同(但对于'steeringForce'):

This is the same as you wrote previously (but for 'steeringForce'):

correction = desired_velocity - velocity

通过执行velocity + correction,您将立即达到所需的速度,通常这不是您想要的速度,因为它会导致非常剧烈的运动.取而代之的是,您可以将校正值固定在某个值上,以使运动更平滑:

By doing velocity + correction you will immediately get to the desired velocity, which is usually not what you want as it leads to a very jerky motion. Instead, you could clamp the correction to some value which would lead to a smoother motion:

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

现在您可以做

velocity += correction

这应该导致某种动态运动,而不会产生振荡.

This should lead to a somewhat dynamic motion, without oscillation.

明确的时间步长积分(例如您的情况下为前向欧拉)通常写为

Explicit time step integration (e.g. an forward Euler in your case) is usually written as

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

类似地,

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

因此,要回答您的问题,您需要乘以时间步长才能累积:

So to answer your question, you need to multiply by the time step before accumulating:

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

这篇关于如何实现具有时间增量的到达行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 02:53