考虑以下语句来更新游戏中集成过程中物理对象的速度:
velocity = velocity * 0.999f + acceleration;
将速度乘以略小于1的值称为"速度";阻尼";并且CCD_ 1是"0";阻尼因子";。有人说,阻尼是必要的,以消除多余的能量造成的数值不稳定。
我不明白。我也可以使用CCD_;阻尼系数";并声称这是为了增加由数值不稳定性引起的缺失能量(而不是超过能量(:
velocity = velocity * 1.001f + acceleration;
对吧?我错过了什么?
我不是在说阻力,是吗?毕竟,0.999f
阻力因子是去除与速度成比例的部分。阻尼只是阻力吗?
如果使用*1.001f
方法,对象将倾向于人为加速。事实上,他们很快就会离开你的游戏世界,可能是因为他们以极快的速度移动。
另一方面,*0.999f
方法不能导致如此明显/怪异的行为,因为玩家的大脑可以很容易地将其解释为";阻力";(如果他们注意到的话(。
阻尼系数0.999f或DAMPING
是数字低通滤波器中的α
,用于平滑计算速度。
OP具有
考虑以下语句来更新游戏中集成过程中物理对象的速度:
velocity = velocity * 0.999f + acceleration;
我缺少什么?
缺少的是隐含的时间缩减1/1000。
// old velocity new velocity
// v------v v------------v
velocity = velocity * 0.999f + acceleration*t*0.001;
// factor1 factor2, their sum is 1.0
t*0.001
是1.0
,并且肯定已经在用于表示0.999f
0和velocity
的更新周期和单位中被考虑在内。
另一种选择是使用实单位,让编译器看到* (mm_to_m * UPDATE_PERIOD * DAMPING)
按1缩放,并发出信任有效代码。
double acceleration; // mm/s/s
double velocity; // m/s
#define UPDATE_PERIOD (1.0 /* seconds */)
#define DAMPING 0.001
#define mm_to_m 1000.0
velocity = velocity * (1.0 - DAMPING) + acceleration * (mm_to_m * UPDATE_PERIOD * DAMPING);
改变知识来源,sine显然作者在物理模拟领域知识不足。
看起来有些人使用了正向欧拉方法,这并没有节省系统的总能量。作者不理解这个问题,并使用了"duping";作为邪恶的黑客。
适当的解决方案是使用不同的算法。最简单的是Verlets算法(简单如Euler方法(。另一种选择叫跳蛙,也很容易理解。
还有其他更复杂的算法来模拟物理。
Forward Euler方法有什么问题?在这种近似中,每一步都会引入一个系统性的误差。在每一步中,系统都会获得一点能量。误差不是计算精度有限的结果,而是算法如何工作的问题。更改时间步长可以减少此问题,但速度不够快。经典的例子是模拟行星轨道,在这个算法中,它不是椭圆形的(应该是椭圆形的(,而是螺旋形的,每个轨道都会使行星远离太阳。
如果补救措施描述为It is said that damping is necessary to remove excess energy caused by numerical instability.
对我来说,这清楚地表明作者不知道还有其他算法的数值复杂度是相同的,但没有这个弱点。在这里添加阻力是一种欺骗。
现在,如果你正在用物理学实现一个游戏;欺骗;是无害的。如果你正在模拟一些物理过程,那么这是最糟糕的方法,会产生错误的结果。
在替代算法中,误差不是系统性的,并且系统节省总能量。
Ian Millington解释说,在他的物理引擎Cyclone中添加阻尼因子是阻力的粗略近似,为了解决处理器数值不准确的问题,他解释说,当涉及到广泛的计算(如游戏所需的计算(时,计算机处理器会有一定程度的数值不准确。
这样,物体似乎不会被人为加速,它也可以作为一个较小的阻力。
这本书讲述了他的物理引擎的发展历程。他在第三章第一运动定律中解释了阻尼因子游戏物理引擎开发