【问题标题】:Calculating the speed of a moving object based on its distance to a target根据到目标的距离计算移动物体的速度
【发布时间】:2015-01-06 01:58:46
【问题描述】:

我正在编写一个模拟,其中一个对象在 2D 世界中向目标位置移动,存储为矢量target(x,y)。对象位置也存储为位置向量pos(x,y)。该对象包含另外两个向量,所需的移动速度dv(x,y),以及当前的移动速度cv(x,y)。在模拟开始时,这两个速度矢量都是初始的,即设置为(0,0)

当物体应该向目标位置移动时,我计算所需的速度矢量dv,对其进行归一化,并按移动速度值对其进行缩放:

dv.set(target).sub(pos).normalize()
dv.scale(speed)

我想让运动看起来更逼真,这就是我使用两个速度矢量的原因。 dv 告诉我要移动对象的全速,cv 保存对象当前移动的真实速度。

然后在每一帧(更新步骤),当前速度cv 是根据所需速度dv 和加速度值acc 设置的。这是通过简单地计算cvdv 之间的差异并将此差异限制为acc 来完成的。这样,物体开始缓慢移动并逐渐加速,最终达到全速。

到目前为止,这一切正常。现在我也想使用acc 进行减速。当postarget 之间的距离为一定值时,应将所需速度dv 设置为(0,0),以便物体逐渐减速,直到在目标位置完全停止。

我的问题是:如何计算我需要将dv 设置为(0,0) 的距离(即告诉系统停止运动),以便对象正确减速以停止准确 在目标位置?

【问题讨论】:

    标签: algorithm kinematics


    【解决方案1】:

    使用运动学方程:

    vf2 = vi2 + 2 * a * d

    • vf 是你的最终速度,或 0(你想要的速度)

    • vi 是给定的初始速度(对象当前移动的速度)。

    • a 是加速度

    • d 是距离。

    求解d:

    • 2*a*d = vf2 - vi2

    • 2*a*d = 0 - vi2

    假设加速度为负,所以两边都乘以-1

    • 2*|a|*d = vi2

    |一个|是您的加速度的绝对值(在您的情况下为减速度)

    • d = vi2 / (2*|a|)

    【讨论】:

    • 这对我不起作用。我使用vi=10a=0.5,即运动以0.5 的步长增加,直到达到全速。有了这些值,你的最后一行给了我d=100.0 的距离,而通过反复试验,我知道它应该小于 1.0
    • 我在每个时间步将a 添加到速度向量中。所以我假设你的等式是基于a 在一整秒内展开的?我猜有道理。是否可以轻松地将您的解决方案转换为我的情况?
    • @Matthias,如果您的加速度为 0.5 m/s^2,并且您的时间步长为 0.5,那么每个时间步长您只需应用大约 0.25。只需将您的加速度除以您的时间步长即可。实际上,您的速度应该类似地缩放,以便保持独立于时间步长(即,如果您出于某种原因想将时间步长更改为 10,您不想神奇地看到速度增加 10 倍)。
    • 这很有道理,谢谢。所以我已经按时间步长缩放速度(这是几分之一秒,即自上一个时间步长以来的delta)。现在我也按delta 缩放加速度。通过应用你的方程,现在减速效果更好。然而,物体停止得太早了,它永远不会完全到达目标。我认为你的方程式是正确的,我需要在其他地方搜索问题......
    • 非常感谢,现在效果很好。答案被接受:-)
    【解决方案2】:

    您正在对运动进行离散时间模拟。保持简单的一种方法是以使加速和减速对称的方式执行计算。换言之,加速时行驶的距离应该与减速时行驶的距离相同。例如,假设

    • 加速度为5
    • 最高速度为 13
    • 物体一达到最高速度就开始减速

    离散时间模拟将如何进行

    first tick
      old speed = 0
      new speed = 5
      distance  = 5
    
    second tick
      old speed = 5
      new speed = 10
      distance  = 15
    
    third tick
      old speed = 10
      new speed = 13
      distance  = 28  <-- total distance while accelerating
    
    fourth tick
      old speed = 13
      distance  = 41
      new speed = 10  <-- not 8!!!
    
    fifth tick
      old speed = 10
      distance  = 51
      new speed =  5
    
    sixth tick
      old speed =  5
      distance  = 56  <-- Yay, twice the distance, we have symmetry
      new speed =  0
    

    这里有两个重点

    • 加速时首先更新速度,然后更新距离。减速时顺序相反,先更新距离,再更新速度。
    • 减速时,将调整后的速度保持为加速度的倍数很重要

    在C编程语言中,以下代码可用于在减速过程中更新速度

    if ( old_speed % acceleration != 0 )                   // if speed is not a multiple of acceleration
       new_speed = old_speed - old_speed % acceleration;   //   reduce speed to a multiple of acceleration
    else                                                   // otherwise
       new_speed = old_speed - acceleration;               //   reduce speed by acceleration
    

    如果加减速对称,则计算减速距离与计算加速距离相同。

    distance = acceleration * (1+2+3+ ... +N) + fudge_factor
    

    在哪里

    • Ntop_speed / acceleration 截断为整数,例如13/5 ==&gt; 2
    • fudge_factor0 如果最高速度是加速度的倍数,或者 top_speed 否则

    计算可以通过注意来简化

    1+2+3+ ... +N = N * (N+1) / 2
    

    在 C 中,减速时行进的总距离可以计算如下

    int top_speed = 13;
    int acceleration = 5;
    
    int N = top_speed / acceleration;     // Note: in C, integer division truncates
    
    int fudge = 0;
    if ( top_speed % acceleration != 0 )
        fudge = top_speed;
    
    int distance = acceleration * (N * (N+1)) / 2 + fudge;
    

    【讨论】:

    • 这似乎对我不起作用。我使用top_speed=10.0acceleration=0.5,使用这些值,您的最​​后一行acceleration * (N * (N+1)) / 2 + fudge 给了我distance=105.0,而通过反复试验,我知道它应该小于1.0
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-30
    • 1970-01-01
    相关资源
    最近更新 更多