人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

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

●質問者: Kassan
●カテゴリ:コンピュータ
✍キーワード:C++Builder アドバイス ソフト プログラム マウス
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● enc
●20ポイント

http://www.asahi-net.or.jp/~yf8k-kbys/newcpp0.html

C++入門

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

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

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


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

◎質問者からの返答

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

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

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

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

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


2 ● harg
●20ポイント

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になります。

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


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

◎質問者からの返答

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

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


3 ● harg
●20ポイント

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++でどうなのかは知らないのでエラー処理は割愛します。

◎質問者からの返答

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

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

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

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ