我希望我的应用程序能够在设备水平持握时检测设备旋转。我可以使用罗盘的读数,但我认为陀螺仪的偏航值更准确。给定偏航读数,确定360°旋转(顺时针或逆时针)的最佳算法是什么?而且它必须是完整的360°旋转,不能只是将手机向一个方向旋转180°,再向相反方向旋转180°。
我希望我的应用程序能够在设备水平持握时检测设备旋转。我可以使用罗盘的读数,但我认为陀螺仪的偏航值更准确。给定偏航读数,确定360°旋转(顺时针或逆时针)的最佳算法是什么?而且它必须是完整的360°旋转,不能只是将手机向一个方向旋转180°,再向相反方向旋转180°。
您可以使用CoreMotion获取垂直轴的旋转。您需要添加旋转事件的增量。每当超过最小值,与先前不同的方向时,您就会重置起始点。然后当您从此起始点到达加或减360度时,您就有了旋转。
PI
的检查点。最初,检查点标志cp_pi
为NO
,并且在任何方向上通过它都会切换其状态。请注意,偏航角在两个位置改变其符号,在零点处再次改变符号,并到达PI
至-PI
。tick
之间保持不变,BOOL cp_pi;
和 float prev_yaw;
,我们认为对于穿过0的情况,d_yaw
小于PI
,而对于穿过圆形相反端点的情况,d_yaw
大于PI
。当穿过相反的端点时,我们切换cp_pi
。当cp_pi
为YES
并穿过0时,我们保证已经通过了一个完整的圆 - 否则,cp_pi
将被切换回NO
。-(void)tick
{
float yaw = [self zeroedYaw];
if ((fabs(yaw) == PI) || (yaw == 0.0f)) return;
if (yaw * prev_yaw < 0)
{
float d_yaw = fabs(yaw - prev_yaw);
if (d_yaw > PI)
{
cp_pi = ! cp_pi;
}
else if (cp_pi)
{
// fire detection event
}
}
prev_yaw = yaw;
}
yaw
恰好位于其中一个检查点上,则会完全跳过检测函数。cp_pi = ! cp_pi
在第二次交叉时会翻转回 NO
,所以它不会被检测为旋转。 - s.bandaracp_pi
就会在 +/- PI
时再次翻转到 YES
,并且事件最终将在 0 处触发。因此,只有完整的圆圈才会计数。 - s.bandarazeroedYaw
是什么作用? - Ahmed Z.zeroedYaw
必须返回一个在 -PI
和 PI
之间的偏航角,并且围绕初始偏航角为零。 - s.bandara