デバイスが水平に保持されているときに、アプリがデバイスの回転を検出できるようにしたいと考えています。コンパスからの読み取り値を使用することもできますが、ジャイロスコープからのヨー値の方が正確だと思います。ヨーの読み取り値が与えられた場合、360° の回転 (時計回りまたは反時計回り) を決定するための最適なアルゴリズムは何でしょうか。また、電話を一方向に 180° 回転させ、反対方向に 180° 戻すだけでなく、完全に 360° である必要があります。
2 に答える
CoreMotion を使用して、垂直軸を中心とした回転を取得します。回転イベントのデルタを追加する必要があります。最小値を超えるたびに、以前とは異なる方向に出発点をリセットします。次に、この開始点からプラスまたはマイナス 360 度に到達すると、回転します。
ここでは、読み取り値を短い間隔で取得でき、特定の開始点でヨーをゼロにできると仮定したアイデアを示します。これは、継続的に適応された開始点から完全な円を検出する他の回答とは異なります。
このアプローチでは、現在のヨーを以前のヨーと比較し続け、180 度のチェックポイントをPI
通過したかどうかを尋ねます。最初は、チェックポイント フラグcp_pi
はNO
であり、それをどちらの方向にも渡すと、その状態が切り替わります。yaw は 2 つの場所で符号を変更することに注意してください。ゼロ点と で再びPI
です-PI
。
tick
オブジェクトに検出器の と の間でBOOL cp_pi;
持続する 2 つのプロパティがあると仮定すると、これは0 を横切る場合よりも小さく、円の反対側で交差する場合よりも大きいfloat prev_yaw;
と見なされます。反対側の端を横切るときは、トグルします。が0 を横切っているときに、完全な円を通過したことが保証されます。d_yaw
PI
PI
cp_pi
cp_pi
YES
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
、 がチェックポイントの 1 つにある場合は、検出機能を完全にスキップすることに注意してください。