再來一篇執行個體講解(PS:該篇執行個體改編自Flash AS當中的一個滑鼠手勢庫,具體出處我忘記了,這代碼寫的有點久了,好像2008年左右寫的)。
滑鼠手勢是一個種比較好玩的東西,其應用并不算很廣泛,但是研究起來相當好玩。在遨遊浏覽器當中,你可以看到滑鼠手勢的應用,例如你按住滑鼠右鍵,然後畫一個L,可以關閉目前的标簽,從右向左畫一橫,可以後退,FireFox當中也支援滑鼠手勢。還有一些遊戲中也用到了該技術,例如《三位一體》,還有NDS上的《惡魔城》等等。當然,手寫輸入發也算是一種滑鼠手勢,不過其實作方式不知道與我下面将的是否相同,這個沒有研究過。
其實滑鼠手勢玩的就是算法,建立弧度向量表,根據滑鼠軌迹的點計算方向,然後與預定義的滑鼠手勢進行對比,取出最相似的一組。這幾個步驟當中都要用到不同的算法。
首先是弧度向量表,以八個方向的向量劃分弧度,并按一定的精度建立一個弧度向量表,用0-7表示8個方向,-1表示“.”。如下圖所示:

此時,我們就可以根據這個方向建立手勢資料了,例如:
A可以表示為71
B可以表示為260123401234
I可以表示為2(與1沒有區分開,程式帶中的代碼也是如此,如果需要區分開,可以用6表示1,即從下往上畫一豎,不過這樣不符合人們的輸入習慣了)
看到這裡,相信基本原理也大概明白了,就是預先建立手勢資料,然後通過捕獲滑鼠軌迹的點來建立方向數組,然後與手勢資料的數組進行對比。
接下來從流程上開始說(執行個體當中的流程):
1.捕獲滑鼠輸入,當滑鼠左鍵按下,開始進行滑鼠軌迹記錄。
2.以一定時間間隔記錄滑鼠移動過的點,并通過前後兩點的向量計算出向量所對應的方向編号,并添加到數組當中。
3.滑鼠左鍵擡起時結束輸入捕獲(這裡就必須是連筆輸入,如果你不希望連筆輸入,可以在設定一個時間間隔,在這個時間間隔内如果滑鼠按下,則繼續捕獲),開始對輸入的手勢資料與所有預先建立的手勢資料進行對比,這裡采用了Levenshtein算法計算數組相似度,這個算法稍微有點複雜,這裡就不解釋了,有興趣的可以去這個網站看看。同時,在對比過程當中,對一些容易混淆的手勢進行了精度修正(源代碼中的MouseGesture的GestureMatchEvent就是對手勢進行精度修正)。
4.列印符合條件的字元。
源代碼可以在這裡下載下傳。其中有兩個工程,MouseGestureLib是滑鼠手勢的庫,MouseGesture是一個利用該庫實作的識别26個字母+0-9個數字的Demo,有使用說明。
代碼當中可以優化的地方很多,這篇代碼是剛學了C#不久後寫的,注釋不是太全,見諒。(每次回過頭去看自己以前寫的代碼都覺得有點好笑,心想:“嘿,那個時候我怎麼會那樣想呢,怎麼能那樣做呢?”,呵呵,相當的搞笑)