天天看點

Leap Motion 探究 【第三篇】

Leap Motion 探究 【第三篇】

        剛嘗試手勢的時候我差點選擇放棄,現在想想還是自己不好好看SDK,小心使得萬年船啊。

        五一不想斷更的,實在是沒辦法,出去的急忘了帶筆記本,隻好斷更。下午才回來,畢竟這種萬年沒休的也習慣這種生活方式了,反而出去溜達感到閑的蛋疼。

        廢話不多說,直接貼代碼,這段代碼實作的是在畫圈停止後輸出一個Gesture通知,代碼很順利,結果很粗糙。由于手部肌肉連帶,食指動的時候必然中指也動,加上Leap“超凡的精确度”,導緻動了右手食指,出來四胞胎結果——拇指,食指,中指,無名指。

public override void OnFrame(Controller arg0)
        {
            Frame frame = arg0.Frame();
            GestureList gestures = frame.Gestures();
            for (int i = 0; i < gestures.Count; i++)
            {
                Gesture gesture = gestures[i];

                switch (gesture.Type)
                {
                    case Gesture.GestureType.TYPE_CIRCLE:
                        CircleGesture circle = new CircleGesture(gesture);

                        // Calculate clock direction using the angle between circle normal and pointable
                        String clockwiseness;
                        if (circle.Pointable.Direction.AngleTo(circle.Normal) <= Math.PI / 2)
                        {
                            //Clockwise if angle is less than 90 degrees
                            clockwiseness = "clockwise";
                        }
                        else
                        {
                            clockwiseness = "counterclockwise";
                        }

                        float sweptAngle = 0;

                        // Calculate angle swept since last frame
                        if (circle.State != Gesture.GestureState.STATE_START)
                        {
                            CircleGesture previousUpdate = new CircleGesture(arg0.Frame(1).Gesture(circle.Id));
                            sweptAngle = (circle.Progress - previousUpdate.Progress) * 360;
                        }

                        if(circle.State==Gesture.GestureState.STATE_STOP)
                            Console.WriteLine("  Circle id: " + circle.Id
                                            + ", " + circle.State
                                            + ", progress: " + circle.Progress
                                            + ", radius: " + circle.Radius
                                            + ", angle: " + sweptAngle
                                            + ", " + clockwiseness);
                        break;
                }
                    
            }
        }
           
Leap Motion 探究 【第三篇】

        修改過一個小東西後,手勢明顯變得好用了,就是門檻值。圖上是檢測Key_Tap時候的回報資料,由于設定了min_distance,即最小移動檢測門檻值,回報良好,基本不會出現誤操作的問題。由此可見好好看SDK是多麼重要啊!門檻值參數表如下:

畫圈手勢

Gesture.Circle.MinRadius float5mm

Gesture.Circle.MinArc float1.5 * piradians

按鍵手勢

Gesture.KeyTap.MinDownVelocity float50mm/s

Gesture.KeyTap.HistorySeconds float0.1s

Gesture.KeyTap.MinDistance float3mm

橫掃手勢

Gesture.Swipe.MinLength float150mm

Gesture.Swipe.MinVelocity float1000mm/s

觸摸手勢

Gesture.ScreenTap.MinForwardVelocity float50mm/s

Gesture.ScreenTap.HistorySeconds float0.1s

Gesture.ScreenTap.MinDistance float5mm

       第一項為名稱,第二項是資料類型(都是float),第三項是預設門檻值大小,第四項是機關,csdn的表格有點不友善,然而對于一個寫程式剛入門的,還去用dreamwaver編個表格粘到源碼裡,太麻煩,大家就這麼一看,我就這麼一畫吧。修改門檻值的方式也很簡單:這裡用Circle手勢作為參考,修改了最小半徑和最小角速度,然後記得儲存。

controller.Config.SetFloat ("Gesture.Circle.MinRadius", 10.0f);
controller.Config.SetFloat ("Gesture.Circle.MinArc", .5f);
controller.Config.Save ();
           

       那麼問題又來了,手勢是對了,怎麼知道是哪根指頭操作的呢,不能玩第二根半價(權值選擇不讀)的遊戲啊,肯定得想辦法把所有指頭都用上。想了兩個辦法,第一個操作一個Hand循環,采樣手指名稱,比如finger.type等于“TYPE_INDEX”是食指,是需要的的指頭操作,測試發現問題了,因為是foreach fingers,是以隻要手指頭被檢測到,就會被刷出來,第一種方案胎死腹中。第二個方案比較原始,即判斷激發點和手指的位置是不是重合,但是由于Finger中并沒有postion參數,隻好想其他辦法,不過下期一定貼代碼!

      另外,細心的朋友發現程式失焦後會不工作,這是Leap的一種保護機制,然而這種保護機制我給零分,明明應該是預設讀取資料,我可以選擇關閉,現在是預設關閉我可以選擇打開,好吧,我服,其實就是加了一句話:

Controller.SetPolicy(Controller.PolicyFlag.POLICY_BACKGROUND_FRAMES);
           

       這樣子程式就可以背景繼續資料了,回來路上我還納悶這個問題呢,心想不應該,實在不行建立個新程序單獨走,然而SDK再一次告訴我想多了,好好看SDK,東西全在裡面,寫不出都是自己的問題。現在節奏快,巴不得什麼東西都不學,一口吃成個大胖子,唉,急不得啊。

       如果有朋友有finger和gesture比對的解決方案,記得留言!

繼續閱讀