16

ユーザーが円形を描いたかどうかを検出する簡単なプログラム方法を検討しています。私は C で作業していますが、疑似コードから作業できることをうれしく思います。少しググると、(できれば) 非常に複雑なメソッドが多数表示されます。

マウスの座標をフロートとして追跡しており、時間の経過に伴うマウスの動きを追跡するためのベクトルの配列を作成しました。基本的に、円が描画されたことを検出し、その円に関連付けられていないすべての動きデータを破棄しようとしています。

これがどのように達成されるかについての基本的な考えがあります:

ポーリング機能を使用してすべての動きを追跡します。関数がポーリングされるたびに、現在のマウス位置が保存されます。ここでは、過去の位置データをループし、大まかな「位置へのスナップ」を実行して 2 つの位置を比較します。新しい場所が古い場所から十分に近い距離にある場合は、古い場所より前のすべての履歴データを削除します。

これは理論的には機能しますが、実際には混乱します。誰か提案はありますか?提案された方法が時計回りまたは反時計回りに描かれたかどうかを検出できる場合のボーナスポイント.

4

5 に答える 5

6

float ペアをスタックにプッシュする追跡/ポーリング関数に基づいています。これは、一定の時間間隔で行う必要があります。

  1. リスト内の 2 つの等しいエントリをしきい値ベースで検索します。これで、スタックに 2 つのインデックスができました。最初と 2 番目の等しいエントリ。これを直線と考えてください。
  2. インデックスの絶対差を取得します。次に、2 で割り、この点の座標を取得します。(行の中央。)
  3. 2 つの点があります。したがって、2 点間の距離を 2 で割ることによって、円の半径を取得できます。
  4. ステップ 2 の数を 2 で割ると、4 分の 1 になります。

    ステップ 1 の線が垂直で、線の最初の点が上にある場合: 最初の 4 分の 1 が中心点の左側にある場合、円は反時計回りに描かれています。最初の 4 分の 1 が中心点の右側にある場合、円は時計回りに描かれています。線の最初の点が下にある場合は、反転します (つまり、ccw => cw および cw => ccw)。

    ステップ 1 の線が水平で、リストの最初の点が左側にある場合: 最初の 4 分の 1 が中心点の上にある場合、円は反時計回りに描かれています。最初の 4 分の 1 が中心点より下にある場合、円は時計回りに描かれています。線の最初の点が右にある場合は、反転します。

  5. 円であるかどうかを確認します。座標のすべてのペアを反復処理し、中心点までの距離を計算します。計算された距離と中心点までの実際の距離から、許容される距離のしきい値を微調整します。

ステップ 2 と 4 で、タイミング間隔が非常に短い (高速ポーリング) 場合は、複数のインデックスの平均を取ることで、このアルゴリズムをさらに微調整できます。例: 配列に 30 個のペアがあり、0、1、および 28、29 でペアを平均して上限を取得します。他のすべてのポイントについても同じことを行います。

これで十分簡単だと思います。

于 2010-03-06T18:37:12.817 に答える
5

あなたは間違いなく正しい方向に進んでいます。基本的に、各マウスポイントを前のマウスポイントと比較し、それらの間の角度を計算する必要があります(最初のポイントが原点にある単位円で想定されているように)。これには、次の式を使用できます。

double angle = atan2(y2 - y1, x2 - x1) * 180 / PI;

if (angle < 0)
    angle += 360;

最終的には、時計回りの動きの場合、角度は正の方向に循環しますが、反時計回りの動きの場合、角度は負の方向に循環します。次のロジックを使用して、現在の角度が前の角度よりも大きいか小さいかを判断できます。

if (angle2 > 270 && angle1 < 90)
{
    angle1 += 360
}
else if (angle1 > 270 && angle2 < 90)
{
    angle2 += 360
}

bool isPositive = (angle2-angle1 > 0);

角度が増加している(isPositiveがtrue、たとえば10倍)特定の数のベクトルを取得した場合、時計回りの円が描画されていると見なすことができます。傾向が負の場合(isPositiveが10回falseの場合)、反時計回りの円になります。:)

于 2011-09-01T19:50:11.407 に答える
0

これを試したことはありませんが、あなたの質問を読んでアイデアが頭に浮かんだので、あなたと共有することもできます:

2D ベクトル (ポイント) の既知のサイズの配列を残すマウスの安定した「サンプルレート」を考えると、円は妥当な時間内に描画する必要があると想定しています。それらをすべて加算し、2D ベクトルの数で割って、配列内の「中心」点の推定値を取得します。次に、この中心点から配列内の点までのベクトルを形成し、内積 (ベクトルの長さで正規化) を実行します。内積の符号が一定範囲の点で同一であることを確認すると、それらの点はすべて同じ方向に移動します。正の符号は反時計回りの動きを示し、負の符号は正反対です。累積角度が 2 PI を超えると、円運動が描かれました。

幸運を。

于 2010-03-06T19:29:17.060 に答える