素人ですが,C++Builderでマウスジェスチャのソフトをプログラムの練習で作ってみたいです。マウスの座標を取得して線を引くとこまでは分かったのですが,それを色んな機能と結びつける方法が分かりません。。。何か参考になるようなページやアドバイスを教えてほしいです。どうかよろしくお願いします。

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:
  • 終了:--
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答3件)

id:enc No.1

回答回数71ベストアンサー獲得回数2

ポイント20pt

まずは線の向きを判定します。

x座標とy座標より、上下左右の判定ができると思います。

次に、それらを配列に代入します。そして、事前に登録されたアクションの配列と比較すれば判定が可能です。たとえばこれらをswitchで記述して、あとはそれぞれのアクションをcaseに記述すれば良いでしょう。


URIはC++の基礎講座サイトです。ご参考までに。

id:Kassan

どうもありがとうございます。

大体の形が見えてきてとても参考になります。

あとの疑問として,事前にアクションを登録するのはどうすればいいのでしょうか?

それと,上下左右に加えて文字判定(「C」を書いたらウインドウを閉じる,「W」を書いたらブラウザ起動など)の処理を行うのにはどうすればよいのでしょうか?

どうぞよろしくお願いします。

2006/01/21 01:18:08
id:harg No.2

回答回数35ベストアンサー獲得回数0

ポイント20pt

http://www.hatena.ne.jp/1137764391#

人力検索はてな - 素人ですが,C++Builderでマウスジェスチャのソフトをプログラムの練習で作ってみたいです。マウスの座標を取得して線を引くとこまでは分かったのですが,それを色んな機能..

URLはダミーです。

マウスジェスチャに必要なのは、ずばりパターンの検出ですね。

パターンの検出のためには、前述されている座標を配列として保存することがまず必要です。

では、その後どのように登録したパターンと比較するのか、またそもそもパターンの登録をどうするか、という問題は、簡単ではありませんし、解決法は一つではないと思います。


とりあえず、自分が今思いついた方法を書きます。

形状は、座標の変化量によって決まるので、ここでは変化量にのみ注目します。

マウスの座標が配列x,yに入っているとします。ここで、配列のインデックスiとしたとき、横軸をi,縦軸をx[i+1]-x[i](xの変化量)とするグラフと、横軸をi,縦軸をy[i+1]-y[i](yの変化量)とするグラフを描くことを考えます。

そして、そのグラフ上に、登録するパターンのxとyの変化量の理想的なグラフを描くことを考えます。

たとえば、Lの字を描くようなジェスチャであれば、途中までxの変化量は0で、yは変化します。Lのコーナーを過ぎたら、xは変化するが、yは変化量0になります。

この理想的なグラフと、実際の変化量のずれが小さいほど、正確なジェスチャをしていると判断をすることができます。あとは、どの程度までのずれを許容するかがプログラマの判断にゆだねられます。


数学的なセンス、特に微分を理解していればかなり考えやすいと思います。

id:Kassan

どうもありがとうございます。

文字判定もそれで出来そうですね。かなり参考になります。

2006/01/21 15:48:16
id:harg No.3

回答回数35ベストアンサー獲得回数0

ポイント20pt

http://www.hatena.ne.jp/1137764391##

人力検索はてな - 素人ですが,C++Builderでマウスジェスチャのソフトをプログラムの練習で作ってみたいです。マウスの座標を取得して線を引くとこまでは分かったのですが,それを色んな機能..

URLはダミーです。

複雑な形のジェスチャーは認識が難しいのと、現在主流なの方法が上下左右の組み合わせなので、それの簡単なサンプルをJavaで作って、実際に動かしてみました。以下メインの部分を抜粋します。


int dx = e.getX() - px;

int dy = e.getY() - py;

int state = 0;

double di = 0.0;


di = (double)dy / (double)dx;


if (dx > 0){

if (di < -1) state = 1;

if (-1 <= di & di <= 1) state = 3;

if (1 < di) state = 2;

}else if (dx < 0){

if (di < -1) state = 2;

if (-1 <= di & di <= 1) state = 4;

if (1 < di) state = 1;

}else if (dx == 0){

if (dy > 0){

state = 2;

}else if(dy < 0){

state = 1;

}

}


if (state == gesture_state){

state_count++;

}else{

state_count = 0;

}


gesture_state = state;


String[] arr = new String[5];

arr[1] = ”↑”; arr[2] = ”↓”; arr[3] = ”→”; arr[4] = ”←”;


if (state_count > 5 & state_count < 7){

// ジェスチャー発生!

}


px = e.getX();

py = e.getY();


簡単に解説します。

上記の部分が、マウスが動くときのイベントで実行されます。

px, pyには、前回のmousemoveのときのマウスの座標が入っています。

そこから、移動量dx, dyを求めます。

また、移動量の比di = dy / dxを求めます。

水平から45度の方向に動くと、diは1か-1になるので、それを使って動いた方向を上下左右のいずれかに判別します。水平から45度以内の移動は左右に動いたと判断しています。

gesture_stateでは、前回のジェスチャーが何であったかを記憶します。とりあえず、0-nothing, 1-north, 2-south, 3-east, 4-westとしてあります。なぜ前回のジェスチャーを記憶するかというと、mousemoveは非常に短い間隔で起こるので、同じジェスチャーが何度か続いて初めてジェスチャー発生とみなしているからです。そのカウント用にstate_countを使っています。

Javaではdouble同士の演算で0で割ってもエラーが発生しませんが、C++でどうなのかは知らないのでエラー処理は割愛します。

id:Kassan

再びありがとうございます。

サンプルまでいただいて非常に感謝してます。おかげ様でかなり理解が深まってきました!

がんばって作ってみます!

2006/01/26 09:39:54

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません