Iphone 平滑消息

Iphone 平滑消息,iphone,objective-c,cocoa-touch,Iphone,Objective C,Cocoa Touch,我正在研究类似于测斜仪的东西。我使用传入的UIAcceleration变量,根据在didAccelerate(来自UIAccelerometerDelegate)中计算的角度旋转图像。图像抖动或抖动。甚至当手机仰卧不动时。应用商店里有一些非常平滑的测斜仪。我已经试着通过检查最后的读数来平滑它,如果它在一个范围内,就什么也不要做。这会停止一些抽搐,但随后你会进入一种类似于停止动画的状态。如何获得更平滑的效果?我建议使用“临界阻尼弹簧”进行平滑 基本上你要做的是计算你的目标旋转(这就是你现在所拥有的

我正在研究类似于测斜仪的东西。我使用传入的UIAcceleration变量,根据在didAccelerate(来自UIAccelerometerDelegate)中计算的角度旋转图像。图像抖动或抖动。甚至当手机仰卧不动时。应用商店里有一些非常平滑的测斜仪。我已经试着通过检查最后的读数来平滑它,如果它在一个范围内,就什么也不要做。这会停止一些抽搐,但随后你会进入一种类似于停止动画的状态。如何获得更平滑的效果?

我建议使用“临界阻尼弹簧”进行平滑

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

你需要一个常数来调节系统的反应速度,我们称之为SpringConstant

基本上我们对旋转施加两个力,然后随时间积分。 第一个力是弹簧施加的力,Fs=弹簧常数*距离目标。 第二个是阻尼力,Fd=-CurrentVelocity*2*sqrt(弹簧常数)

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

在每个步骤中,将这两个力的总和乘以时间步长。 这将提供CurrentVelocity值的变化

再乘以时间步长,它会给出位移

我们将其添加到图像的实际旋转中

C++代码中的P>:

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对于弹簧常数来说是一个很好的值,但是你必须针对你的情况进行实验。设置得太高并不能消除急动,设置得太低反应太慢

此外,您最好创建一个保持velocity状态的类,而不必反复将其传递到函数中


我希望这有帮助:)

我建议使用“临界阻尼弹簧”进行平滑处理

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

你需要一个常数来调节系统的反应速度,我们称之为SpringConstant

基本上我们对旋转施加两个力,然后随时间积分。 第一个力是弹簧施加的力,Fs=弹簧常数*距离目标。 第二个是阻尼力,Fd=-CurrentVelocity*2*sqrt(弹簧常数)

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

在每个步骤中,将这两个力的总和乘以时间步长。 这将提供CurrentVelocity值的变化

再乘以时间步长,它会给出位移

我们将其添加到图像的实际旋转中

C++代码中的P>:

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对于弹簧常数来说是一个很好的值,但是你必须针对你的情况进行实验。设置得太高并不能消除急动,设置得太低反应太慢

此外,您最好创建一个保持velocity状态的类,而不必反复将其传递到函数中


我希望这有帮助:)

谢谢。你的意思是说“浮动&a_速度”还是“浮动a_速度”。第一个没有编译,我是说&。当值更改时,需要通过引用传递它。(正如我所说,将其封装在类中可能会更好——但我认为该函数足以说明我的意思)一旦我可以让它工作,我将尝试该类。它不断抛出错误:“错误:在“&”标记之前应为“;”、“、”或“)”。你知道那是什么意思吗?啊。。。也许引用类型是C++的东西,而你使用的是Objy-C。您可以将其更改为指针,或者使用ObjultC++(RealEmto to .mm)Objtovi-C实际使用和引用引用的含义。但是,我认为这不适用于原语(即float)。这就是编译器不断抱怨的原因。出于某种原因,我还不得不用sqrt(5.0)替换sqrt(SPRING_常量)。谢谢。你的意思是说“浮动&a_速度”还是“浮动a_速度”。第一个没有编译,我是说&。当值更改时,需要通过引用传递它。(正如我所说,将其封装在类中可能会更好——但我认为该函数足以说明我的意思)一旦我可以让它工作,我将尝试该类。它不断抛出错误:“错误:在“&”标记之前应为“;”、“、”或“)”。你知道那是什么意思吗?啊。。。也许引用类型是C++的东西,而你使用的是Objy-C。您可以将其更改为指针,或者使用ObjultC++(RealEmto to .mm)Objtovi-C实际使用和引用引用的含义。但是,我认为这不适用于原语(即float)。这就是编译器不断抱怨的原因。出于某种原因,我还不得不用sqrt(5.0)替换sqrt(SPRING_常量)。