首页 文章

如何实现非标准的Leap Motion手势?

提问于
浏览
8

Leap Motion API仅支持四种标准手势:圆形,滑动,按键点击和屏幕点按 . 在我的应用程序中,我需要其他手势,但我不知道如何添加它们或者甚至可以添加更多手势 . 我读了API,没有任何帮助 .

在我的应用程序中,我想允许用户持有一个对象并拖动它 . 可以使用Leap Motion API吗?如果是这样,我该怎么做?

2 回答

  • 8

    您需要创建自己的方法来识别手势的起点,过程和结束点 .

    起点:您的计划将如何识别您正试图 grab 某些东西?我能想到的一个简单的手势是2个手指与1个手掌相连 . 因此,在框架中,如果您看到2个手指与1个手掌相连并且手指可能相距10-20毫米,您可以将其识别为握住某物的手势 . 满足这些条件后,程序将识别手势,您可以在这些条件下编写一些代码 .

    对于C#中一个非常难看的例子:

    起点:布尔值gesture_detected = false;

    Frame frame = controller.Frame();
    HandList hands = controller.Hands;
    
    if (hands.Count == 1)
    {
       foreach (Hand hand in hands)
       {
           if (hand.fingers.Count == 2)
           {
               int fingerA_x,fingerB_x;
               foreach (Finger finger in hand.fingers)
               {
                   if(fingerA_x == 0)
                   {
                       fingerA_x = finger.x;
                   } else
                   {
                       fingerB_x = finger.x;
                   }
               }
           }
       }
    
       if((fingerA_x - fingerB_x) < 20)
       {
             //Gesture is detected. Do something...
             gesture_detected = true;
       }
    }
    

    过程:你的手势试图做什么?如果要移动,则必须调用鼠标方法进行拖动 . 使用事件MOUSEEVENTF_LEFTDOWN在PInvoke下的C中搜索方法mouse_event() .

    结束点:完成拖动后,需要调用鼠标方法事件(如MOUSEEVENTF_LEFTUP)来模拟已完成的鼠标拖动 . 但是你的程序如何检测何时应该停止阻力?最合乎逻辑的方式是如果在帧中不再检测到手势 . 所以写一个else条件来处理备用场景 .

    if (!gesture_detected)
           {
                // Do something
           }
    
  • 0

    在某个时间点,我是否想知道是否需要派生一些Leap Motion classe来定义自定义类,就像使用其他API一样,事实证明你不必这样做 . 下面是C语言中的简短示例,即Leap Motion本地语言,自定义手势定义,Lift手势,可以在空中提升您世界中所有运动物体 .

    手势定义需要2个可见的手,两个都是手掌向上打开,向上移动的速度比预定义的(当前已弃用的)Leap Motion Swipe手势慢,因此如果已启用滑动手势,则两个手势之间不会混淆在Leap Motion回调功能启动期间 void GestureListener::onConnect(const Leap::Controller& controller) .

    从示例中可以看出,手势定义对双手法线和速度施加了约束,因此不会随机检测到但不会太多,因此仍然可以通过一些合理的努力来执行 .

    // lift gesture: 2 hands open flat, both palms up and moving up slowly
    void LeapMotion::liftGesture(int numberHands, std::vector<glm::vec3> palmNormals, std::vector<glm::vec3> palmVelocities) {
    
        if ((numberHands == 2) &&
            (palmNormals[0].x < 0.4f) && (palmNormals[1].x < 0.4f) &&
            (palmNormals[0].y > 0.9f) && (palmNormals[1].y > 0.9f) &&
            (palmNormals[0].z < 0.4f) && (palmNormals[1].z < 0.4f) &&
            (palmVelocities[0].z > 50.0f) && (palmVelocities[1].z > 50.0f) &&
            (palmVelocities[0].z < 300.0f) && (palmVelocities[1].z < 300.0f)) {
    
            m_gesture = LIFT;
            logFileStderr(VERBOSE, "\nLift gesture...\n");
        }
    }
    

相关问题