我正在研究类似于测斜仪的东西。我使用传入的UIAcceleration变量,根据didAccelerate(来自UIAccelerometerDelegate)计算的角度旋转图像。图像是紧张或颤抖。即使手机背面没有移动也没有移动。应用程序商店中有一些倾斜仪非常流畅。我试图通过检查最后一次读数来平滑它,如果它在一个范围内,不要做任何事情。这会停止一些抽搐,但是你会进入看起来像停止动画的东西。我怎样才能获得更顺畅的效果呢?
答案 0 :(得分:3)
我建议使用'临界阻尼弹簧'来平滑。
基本上你所做的就是计算你的目标轮换(这就是你现在所拥有的)。 您可以使用弹簧或弹性片将图像旋转附加到目标旋转,而不是将其直接应用于图像旋转。弹簧受到阻尼,不会产生振动。
你需要一个常量来调整系统反应的速度,我们称之为SpringConstant。
基本上我们对旋转施加两个力,然后随着时间的推移将其整合。 第一个力是弹簧施加的力,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的系统中,弹簧常数很有价值,但你必须根据自己的情况进行实验。设置得太高不会摆脱急动,设置得太低会反应太慢。
另外,你可能最好创建一个保持速度状态的类,而不是一遍又一遍地将它传递给函数。
我希望这有用:)