2009-11-12 56 views
0

我正在研究类似于测斜仪的东西。我使用传入的UIAcceleration变量基于didAccelerate(来自UIAccelerometerDelegate)计算出的角度旋转图像。图像是紧张或抽搐。即使手机躺在背后不移动。应用商店中有一些倾斜仪非常流畅。我试图通过检查最后的阅读来理顺它,如果它在一个范围内,不要做任何事情。这阻止了一些抽搐,但是然后你进入了一些看起来像停止动画的东西。我如何获得更平滑的影响?平滑加速消息

回答

3

我会建议使用'临界阻尼弹簧'进行平滑。

基本上你要做的就是计算你的目标轮换(这就是你现在拥有的)。 而不是将其直接应用于图像旋转,而是使用弹簧或弹性片将图像旋转附加到目标旋转。春天被阻尼,这样你就没有振动。

您需要一个常量来调整系统反应的速度,我们称之为SpringConstant。

基本上我们会对旋转施加两个力,然后随着时间的推移整合这个力。 第一个力是由Spring应用的,Fs = SpringConstant * DistanceToTarget。 第二个是阻尼力,Fd = -CurrentVelocity * 2 * sqrt(SpringConstant)

CurrentVelocity构成系统状态的一部分,可以初始化为零。

在每一步中,将这两个力的总和乘以时间步长。 这使您可以更改CurrentVelocity的值。

再次乘以这个时间步,它会给你的位移。

我们将此添加到图片的实际旋转。

在C++代码:

float CriticallyDampedSpring(float a_Target, 
           float a_Current, 
           float & a_Velocity, 
           float a_TimeStep) 
{ 
    float currentToTarget = a_Target - a_Current; 
    float springForce = currentToTarget * SPRING_CONSTANT; 
    float dampingForce = -a_Velocity * 2 * sqrt(SPRING_CONSTANT); 
    float force = springForce + dampingForce; 
    a_Velocity += force * a_TimeStep; 
    float displacement = a_Velocity * a_TimeStep; 
    return a_Current + displacement; 
} 

我想象你有旋转的两个维度。您只需为每个维度使用一次,并分别跟踪每个维度的速度。

在我和5一起工作的系统中,对于弹簧常数来说是一个很好的值,但是你必须针对你的情况进行实验。将它设置得太高不会消除晃动,设置得太低会反应太慢。另外,你可能最好做一个保持速度状态的类,而不是一次又一次地将它传递给函数。

我希望这有帮助:)

+0

谢谢。你的意思是说“float&a_Velocity”或“float a_Velocity”。第一个不编译。 – 4thSpace 2009-11-12 16:31:43

+0

我的意思是&。随着值的变化,它需要通过引用传递。 (正如我所说,这可能会更好地封装在一个班 - 但我觉得这个功能足以显示我的意思) – 2009-11-12 16:45:43

+0

我会尝试这个类,一旦我能得到它的工作。它在'&'标记之前不断抛出错误:“错误:预计';',','或')'。你知道那是什么意思吗? – 4thSpace 2009-11-12 17:04:54