8

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

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

4

2 回答 2

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
       }
于 2013-12-16T14:18:29.850 回答
0

在某个时间点我想知道是否需要派生一些 Leap Motion 类以便像使用其他 API 一样定义自定义类,事实证明你不必这样做。下面是 C++(Leap Motion 原生语言)中自定义手势定义的简短示例,Lift 手势可将您世界中的所有运动对象提升到空中。

手势定义需要 2 只可见的手,手掌向上张开且向上移动的速度比预定义的(目前已弃用)Leap Motion Swipe 手势慢,因此在启用 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");
    }
}
于 2017-05-15T04:29:17.923 回答