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

时间:2013-12-09 15:12:03

标签: leap-motion

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

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

2 个答案:

答案 0 :(得分:8)

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

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

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

起点:     Boolean 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
       }

答案 1 :(得分: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");
    }
}