2010-03-06 50 views
12

我正在尋找一種簡單的,編程方式來檢測用戶是否繪製了圓形。我在C工作,但很高興從僞代碼工作。一些谷歌搜索帶來了一些(希望)過於複雜的方法。簡單的圓形手勢檢測

我正在跟蹤鼠標座標作爲浮點數,並創建了一個矢量數組來跟蹤鼠標隨着時間的移動。基本上,我正在尋找檢測何時繪製了一個圓,然後忽略與該圓不相關的所有移動數據。

我有多麼這可能是完成了基本思路:

跟蹤使用輪詢功能,所有的動作。每次輪詢該功能時,都會存儲當前的鼠標位置。在這裏,我們通過歷史位置數據循環並做一個粗略的「定位」來比較兩個位置。如果新位置距舊位置足夠近,我們會刪除舊位置之前的所有歷史數據。

雖然這在理論上是有效的,但實際上卻是一團糟。有沒有人有什麼建議?如果建議的方法可以檢測到它是順時針還是逆時針抽取,則爲獎勵分數。

回答

6

根據您的跟蹤/輪詢功能,將堆棧中的浮點對推入。這必須在正常的時間間隔內完成。

  1. 對列表中的兩個相等條目執行基於閾值的搜索。現在你的堆棧中有兩個索引;第一個和第二個相等的條目。考慮這一行。
  2. 獲得指數的絕對差異。然後除以二得到這個點的座標。 (線的中心)
  3. 你有兩點:因此你可以通過得到兩點之間的距離來得到圓的半徑。
  4. 將第2步的數字除以2,現在你已經得到宿舍。

    如果步驟1中的線條是垂直的並且線條的第一個點位於頂部:如果第一個四分之一位於中心點的左側,則該圓圈將按逆時針方向繪製。如果第一個季度在中心點右側,則該圓圈順時針繪製。如果該線的第一個點在底部,則反向(即ccw => cw和cw => ccw)

    如果第1步中的行是水平的,並且列表的第一個點位於左側:If第一節在中心點之上,圓圈是逆時針繪製的。如果第一個四分之一在中心點以下,則圓形會順時針繪製。如果該線的第一個點在右側,則反向。

  5. 檢查它是否是一個圓:迭代所有座標對並計算到中心點的距離。調整距計算距離的允許距離的閾值和到中心點的實際距離。

在步驟2和4中,如果定時間隔非常短(快速輪詢),則可以通過取多個索引的平均值來進一步調整此算法。例如:陣列中有30對,然後在0,1和28,29處平均配對以獲得高點。對所有其他要點也一樣。

我希望這很容易。

+0

如果手勢檢測是這裏的主要話題,我會實際上去與某種觸發計時器的事件。我目前正在使用Qt進行自定義手勢的工作,並使用鼠標按鈕作爲採集樣本的起點。一旦發生其他特定事件(例如釋放鼠標按鈕),此計時器就會停止。在開始和結束時間點,可以檢測鼠標是否正在移動並收集光標的位置。通過這種方式,您將獲得較少的數據以及明確定義的一組點,每個點描述從開始到結束的移動。 – rbaleksandar

0

沒有試過,但這個想法浮現在腦海閱讀您的問題,那麼不妨與大家分享:

我假設圓,必須在合理的時間量內畫,給定一個穩定的「採樣率」的鼠標,會留下一個已知尺寸的2D矢量陣列(點)。將它們全部添加併除以2D向量的數量以得到陣列中「中心」點的估計值。然後從這個中心點到陣列中的點形成矢量,並做點積(按照矢量長度進行歸一化),確保點積的符號對於一定範圍的點保持相同意味着這些點都移動到相同點方向,正號表示逆時針移動,負號正好相反。如果累積的角度超過2 PI,圓形運動被吸引..

好運。

+0

使用時間來限制動作是一個不錯的主意。我也在使用它。如果用戶想畫一個圓圈,他的直覺會告訴他儘可能地做到這一點,因此邊界循環或一些奇怪的非圓形運動的可能性會降低很多。問題在於,對於一​​個用戶來說,時間安排可能會感覺不錯,但是對於另一個用戶而言,這個解決方案可能會完全失敗。 – rbaleksandar

4

你肯定是在正確的軌道恕我直言。基本上你需要比較每個鼠標點與以前的鼠標點並計算它們之間的角度(如第一個點在原點的單位圓上所設想的那樣)。爲此,您可以用公式:

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是真實的,比方說, 10次​​),你可以假定一個順時針圓正在繪製;如果趨勢爲負(isPositive爲假10次),則爲逆時針圓。 :)

+0

不錯,但這實際上可以應用於任何形狀的邊界點在時鐘/逆時針方向。你可以用相同的邏輯畫出一個正方形,一個三角形等等,也許還有一個圓圈。這是由於手和鼠標的運動。用戶不太可能畫出完美的線條(例如作爲正方形的一側),因此曲線是可能導致誤報的結果。這當然不是一個很大的問題,如果只有圈子被檢測到,並且沒有其他東西遵循相同的邏輯路徑。 – rbaleksandar