Leap Motion API 仅支持四种标准手势:画圈、滑动、按键和屏幕点击。在我的应用程序中,我需要其他手势,但我不知道如何添加它们,或者是否可以添加更多手势。我阅读了 API,但没有任何帮助。
在我的应用程序中,我想允许用户握住一个对象并拖动它。使用 Leap Motion API 可以做到吗?如果是这样,我该怎么做?
Leap Motion API 仅支持四种标准手势:画圈、滑动、按键和屏幕点击。在我的应用程序中,我需要其他手势,但我不知道如何添加它们,或者是否可以添加更多手势。我阅读了 API,但没有任何帮助。
在我的应用程序中,我想允许用户握住一个对象并拖动它。使用 Leap Motion API 可以做到吗?如果是这样,我该怎么做?
您将需要创建自己的方法来识别手势的起点、过程和终点。
起点:您的程序将如何识别您正在尝试持有某物?我能想到的一个简单手势是 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
}
在某个时间点我想知道是否需要派生一些 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");
}
}