当前位置:  开发笔记 > 编程语言 > 正文

简单的基于物理的运动

如何解决《简单的基于物理的运动》经验,为你挑选了1个好方法。

我正在研究2D游戏,我正在尝试使用一些基本的物理代码将对象加速到最高速度.

这是它的伪代码:

const float acceleration = 0.02f;
const float friction     = 0.8f;  // value is always 0.0..1.0
      float velocity     = 0;
      float position     = 0;

move()
{
   velocity += acceleration;
   velocity *= friction;
   position += velocity;
}

这是一种非常简化的方法,不依赖于质量或实际摩擦(代码内摩擦只是一种阻止运动的通用力).它的效果很好,因为"速度*=摩擦力"; 部分保持速度不超过某一点.然而,正是这种最高速度及其与加速和摩擦的关系,我有点迷失.

我想要做的是设置一个最高速度,以及达到它所需的时间,然后使用它们来获得加速度和摩擦值.

const float max_velocity = 2.0; 
const int   ticks;       = 120; // If my game runs at 60 FPS, I'd like a 
                                // moving object to reach max_velocity in 
                                // exactly 2 seconds.
const float acceleration = ?
const float friction     = ?

gnovice.. 37

我发现这个问题非常有趣,因为我最近做了一些关于使用阻力建模弹丸运动的工作.

第1点:您实际上是使用显式/前向欧拉迭代更新位置和速度,其中状态的每个新值应该是旧值的函数.在这种情况下,你应该更新所述位置第一,然后更新速度.

要点2:有更真实的物理模型来解决阻力摩擦的影响.一个模型(由Adam Liss建议)涉及与速度成比例的阻力(称为斯托克斯阻力,通常适用于低速情况).我之前提出的那个涉及一个与速度的平方成比例的阻力(称为二次阻力,通常适用于高速情况).关于如何推导出有效达到最大速度所需的最大速度和时间的公式,我将解决每一个问题.我会放弃完整的推导,因为他们相互参与.


斯托克斯的拖累:

更新速度的等式将是:

velocity += acceleration - friction*velocity

它代表以下微分方程:

dv/dt = a - f*v

使用此积分表中的第一个条目,我们可以找到解决方案(假设t = 0时v = 0):

v = (a/f) - (a/f)*exp(-f*t)

当t >> 0时出现最大(即终端)速度,因此等式中的第二项非常接近零并且:

v_max = a/f

关于达到最大速度所需的时间,请注意方程式永远不会真正达到它,而是渐近方向.然而,当指数的参数等于-5时,速度大约是最大速度的98%,可能足够接近以认为它是相等的.然后,您可以将时间近似为最大速度:

t_max = 5/f

然后,您可以使用这两个公式来求解˚F一个给定期望的VMAX最高温度.


二次拖动:

更新速度的等式将是:

velocity += acceleration - friction*velocity*velocity

它代表以下微分方程:

dv/dt = a - f*v^2

使用此积分表中的第一个条目,我们可以找到解决方案(假设t = 0时v = 0):

v = sqrt(a/f)*(exp(2*sqrt(a*f)*t) - 1)/(exp(2*sqrt(a*f)*t) + 1)

当t >> 0时出现最大(即终端)速度,因此指数项远大于1且方程接近:

v_max = sqrt(a/f)

关于达到最大速度所需的时间,请注意方程式永远不会真正达到它,而是渐近方向.然而,当指数的参数等于5时,速度大约是最大速度的99%,可能足够接近以认为它是相等的.然后,您可以将时间近似为最大速度:

t_max = 2.5/sqrt(a*f)

这相当于:

t_max = 2.5/(f*v_max)

对于所需的VMAX最高温度,对于第二个方程最高温度会告诉你什么˚F应该是,然后你就可以插在公式为VMAX获得了价值.


这看起来有点矫枉过正,但这些实际上是一些模拟拖拽的最简单方法!任何真正想要查看集成步骤的人都可以给我发电子邮件,我会将它们发送给您.在这里输入它们有点过于牵扯.

另一点:我没有立即意识到这一点,但如果您改为使用我为v(t)推导出的公式,则不再需要更新速度.如果您只是简单地从静止建模加速,并且您正在跟踪自加速开始以来的时间,则代码将类似于:

position += velocity_function(timeSinceStart)

其中"velocity_function"是v(t)的两个公式之一,你不再需要速度变量.一般来说,这里有一个权衡:计算v(t)可能比简单地用迭代方案更新速度(由于指数项)更加计算成本,但是它保证保持稳定和有界.在某些条件下(比如试图获得非常短的tmax),迭代会变得不稳定和爆炸,这是前向欧拉方法的常见问题.但是,保持对变量的限制(如0 < f <1)应该可以防止这些不稳定性.

另外,如果你感觉有点自虐,你可以将v(t)的公式整合到p(t)的闭合形式解,因此完全需要牛顿迭代.我会把这个留给别人去尝试.=)



1> gnovice..:

我发现这个问题非常有趣,因为我最近做了一些关于使用阻力建模弹丸运动的工作.

第1点:您实际上是使用显式/前向欧拉迭代更新位置和速度,其中状态的每个新值应该是旧值的函数.在这种情况下,你应该更新所述位置第一,然后更新速度.

要点2:有更真实的物理模型来解决阻力摩擦的影响.一个模型(由Adam Liss建议)涉及与速度成比例的阻力(称为斯托克斯阻力,通常适用于低速情况).我之前提出的那个涉及一个与速度的平方成比例的阻力(称为二次阻力,通常适用于高速情况).关于如何推导出有效达到最大速度所需的最大速度和时间的公式,我将解决每一个问题.我会放弃完整的推导,因为他们相互参与.


斯托克斯的拖累:

更新速度的等式将是:

velocity += acceleration - friction*velocity

它代表以下微分方程:

dv/dt = a - f*v

使用此积分表中的第一个条目,我们可以找到解决方案(假设t = 0时v = 0):

v = (a/f) - (a/f)*exp(-f*t)

当t >> 0时出现最大(即终端)速度,因此等式中的第二项非常接近零并且:

v_max = a/f

关于达到最大速度所需的时间,请注意方程式永远不会真正达到它,而是渐近方向.然而,当指数的参数等于-5时,速度大约是最大速度的98%,可能足够接近以认为它是相等的.然后,您可以将时间近似为最大速度:

t_max = 5/f

然后,您可以使用这两个公式来求解˚F一个给定期望的VMAX最高温度.


二次拖动:

更新速度的等式将是:

velocity += acceleration - friction*velocity*velocity

它代表以下微分方程:

dv/dt = a - f*v^2

使用此积分表中的第一个条目,我们可以找到解决方案(假设t = 0时v = 0):

v = sqrt(a/f)*(exp(2*sqrt(a*f)*t) - 1)/(exp(2*sqrt(a*f)*t) + 1)

当t >> 0时出现最大(即终端)速度,因此指数项远大于1且方程接近:

v_max = sqrt(a/f)

关于达到最大速度所需的时间,请注意方程式永远不会真正达到它,而是渐近方向.然而,当指数的参数等于5时,速度大约是最大速度的99%,可能足够接近以认为它是相等的.然后,您可以将时间近似为最大速度:

t_max = 2.5/sqrt(a*f)

这相当于:

t_max = 2.5/(f*v_max)

对于所需的VMAX最高温度,对于第二个方程最高温度会告诉你什么˚F应该是,然后你就可以插在公式为VMAX获得了价值.


这看起来有点矫枉过正,但这些实际上是一些模拟拖拽的最简单方法!任何真正想要查看集成步骤的人都可以给我发电子邮件,我会将它们发送给您.在这里输入它们有点过于牵扯.

另一点:我没有立即意识到这一点,但如果您改为使用我为v(t)推导出的公式,则不再需要更新速度.如果您只是简单地从静止建模加速,并且您正在跟踪自加速开始以来的时间,则代码将类似于:

position += velocity_function(timeSinceStart)

其中"velocity_function"是v(t)的两个公式之一,你不再需要速度变量.一般来说,这里有一个权衡:计算v(t)可能比简单地用迭代方案更新速度(由于指数项)更加计算成本,但是它保证保持稳定和有界.在某些条件下(比如试图获得非常短的tmax),迭代会变得不稳定和爆炸,这是前向欧拉方法的常见问题.但是,保持对变量的限制(如0 < f <1)应该可以防止这些不稳定性.

另外,如果你感觉有点自虐,你可以将v(t)的公式整合到p(t)的闭合形式解,因此完全需要牛顿迭代.我会把这个留给别人去尝试.=)


谢谢!我可能已经避免了一个离散数学rathole,但我直接陷入了整合裂缝!=)
推荐阅读
pan2502851807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有