Leap Motion API仅支持四种标准手势:圆形,滑动,按键点按和屏幕点按。在我的应用程序中,我需要其他手势,但我不知道如何添加它们或者甚至可以添加更多手势。我阅读了API并没有帮助。
在我的应用程序中,我想允许用户持有一个对象并拖动它。可以使用Leap Motion API吗?如果是这样,我该怎么做?
答案 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");
}
}