Leap Motion Win7开发环境配置
先说下环境 Win7 64位 ,不过在配置的时候推荐选择32位
Leap Motion SDK 下载需要到官网去下载
下载到SDK之后,解压缩就好啦,我直接解压到了F盘,路径会后面需要
1、开始配置系统环境变量
(1)新建一个名字为LeapMotionSDK的用户变量,变量值就是SDK的地址
(2)对用户变量的Path进行修改(如果没有Path变量就同样新建一个),将SDK下的dll所在路径添加进去。
这里选择的是32位即x86的路径地址(推荐)
(3)保存,关闭所有程序,注销计算机当前用户(你也可以重启),再重新登陆。这样做为了让刚才设置的环境变量生效。
2、VS2010开启环境配置
(1)打开Visual Studio 2010或者Visual Studio 2012或者其它VS。新建一个Win32应用程序,我们起一个名字LeapSample
(2)新建的项目后,对项目属性进行修改
(3)添加可执行目录地址(可以不加,加了为保险)
$(LeapMotionSDK)lib\x86
(4)添加“包含目录”
$(LeapMotionSDK)include
(5)添加库目录
$(VCInstallDir)lib
$(VCInstallDir)atlmfc\lib
$(WindowsSDK_LibraryPath_x86)
$(LeapMotionSDK)lib\x86
(6)添加附加依赖性(链接器-->输入-->附加依赖项)
Leapd.lib
kernel32.lib
user32.lib
gdi32.lib
winspool.lib
comdlg32.lib
advapi32.lib
shell32.lib
ole32.lib
oleaut32.lib
uuid.lib
odbc32.lib
odbccp32.lib
3、至此,开发环境已经配置好
将一下代码复制到LeapSample.cpp文件中,F7编译,Ctrl+F5执行。看到如图所示输出,这表明程序配置正确(LeapMotion自然得接上)
注(代码来自:http://52coding.com/understanding-the-cpp-sample-application)
1 /******************************************************************************\ 2 * Copyright (C) 2012-2013 Leap Motion, Inc. All rights reserved. * 3 * Leap Motion proprietary and confidential. Not for distribution. * 4 * Use subject to the terms of the Leap Motion SDK Agreement available at * 5 * https://developer.leapmotion.com/sdk_agreement, or another agreement * 6 * between Leap Motion and you, your company or other organization. * 7 \******************************************************************************/ 8 //#include <windows.h>//如果嫌刷屏太快打开这个定义1(一共2处) 9 #include <iostream> 10 #include "Leap.h" 11 using namespace Leap; 12 13 class SampleListener : public Listener { 14 public: 15 virtual void onInit(const Controller&); 16 virtual void onConnect(const Controller&); 17 virtual void onDisconnect(const Controller&); 18 virtual void onExit(const Controller&); 19 virtual void onFrame(const Controller&); 20 virtual void onFocusGained(const Controller&); 21 virtual void onFocusLost(const Controller&); 22 }; 23 24 void SampleListener::onInit(const Controller& controller) { 25 std::cout << "Initialized" << std::endl; 26 } 27 28 //打开对所有手势的识别 29 void SampleListener::onConnect(const Controller& controller) { 30 std::cout << "Connected" << std::endl; 31 controller.enableGesture(Gesture::TYPE_CIRCLE); 32 controller.enableGesture(Gesture::TYPE_KEY_TAP); 33 controller.enableGesture(Gesture::TYPE_SCREEN_TAP); 34 controller.enableGesture(Gesture::TYPE_SWIPE); 35 } 36 37 void SampleListener::onDisconnect(const Controller& controller) { 38 //Note: not dispatched when running in a debugger. 39 std::cout << "Disconnected" << std::endl; 40 } 41 42 void SampleListener::onExit(const Controller& controller) { 43 std::cout << "Exited" << std::endl; 44 } 45 46 //核心函数,当获取一帧数据时要做点什么事 47 void SampleListener::onFrame(const Controller& controller) { 48 // 获取最新的一帧,并且返回一些基本信息 49 const Frame frame = controller.frame(); 50 std::cout << "Frame id: " << frame.id() 51 << ", timestamp: " << frame.timestamp() 52 << ", hands: " << frame.hands().count() 53 << ", fingers: " << frame.fingers().count() 54 << ", tools: " << frame.tools().count() 55 << ", gestures: " << frame.gestures().count() << std::endl; 56 57 //非空,检测到手 58 if (!frame.hands().isEmpty()) { 59 // 得到第一只手[hands()返回HandList结构,可以向操作容器一样操作] 60 const Hand hand = frame.hands()[0]; 61 62 // 检查下手是否有手指[握拳的话,是找不到手指的] 63 const FingerList fingers = hand.fingers(); 64 if (!fingers.isEmpty()) { 65 // 计算指尖尖端平均位置坐标 66 Vector avgPos; 67 for (int i = 0; i < fingers.count(); ++i) { 68 avgPos += fingers[i].tipPosition(); 69 } 70 avgPos /= (float)fingers.count(); 71 std::cout << "Hand has " << fingers.count() 72 << " fingers, average finger tip position" << avgPos << std::endl; 73 } 74 75 // 获取手的球心半径和手掌的坐标 76 std::cout << "Hand sphere radius: " << hand.sphereRadius() 77 << " mm, palm position: " << hand.palmPosition() << std::endl; 78 79 // 获取手的垂直向量(垂直手心向里)和方向(以手心开始,沿着手指指尖方向) 80 const Vector normal = hand.palmNormal(); 81 const Vector direction = hand.direction(); 82 83 // 计算手的俯仰Pitch角度、平面Roll旋转角度和左右Yaw旋转角度 84 std::cout << "Hand pitch: " << direction.pitch() * RAD_TO_DEG << " degrees, " 85 << "roll: " << normal.roll() * RAD_TO_DEG << " degrees, " 86 << "yaw: " << direction.yaw() * RAD_TO_DEG << " degrees" << std::endl; 87 } 88 /*他并没有使用一些函数rightmost和leftmost之类*/ 89 90 // 获取手势 91 const GestureList gestures = frame.gestures(); 92 for (int g = 0; g < gestures.count(); ++g) { 93 Gesture gesture = gestures[g];//这里最好去看下Gesture的定义,里面详细描述各种手势触发的阈值 94 //编程技术比较厉害啊,都看不到Gesture的成员变量在哪里,完全被封装起来了,不是com就是dll封装的吧 95 //我也很想学习这种完全把变量封装到看不见的方法,这样程序员会很省心(眼不见心为净) 96 97 //注意下来使用了switch语句先判断它是否是这种类型手势,再进行类的重新构造 98 switch (gesture.type()) { 99 case Gesture::TYPE_CIRCLE: 100 { 101 CircleGesture circle = gesture; 102 std::string clockwiseness; 103 104 if (circle.pointable().direction().angleTo(circle.normal()) <= PI/4) { 105 clockwiseness = "clockwise";//顺时针旋转的话,circle.normal()指向外侧[右手坐标系,学过物理磁力线神马的一下子就会明白] 106 } else { 107 clockwiseness = "counterclockwise";//逆时针,同上理解 108 } 109 110 // 计算和上一帧经过的角度 111 float sweptAngle = 0; 112 if (circle.state() != Gesture::STATE_START) { 113 //如果不是第一帧[第一帧肯定不能作为判断,只能作为初始化] 114 //frame(0)表示当前最新一帧,而frame(1)表示前一帧,以此类推 115 //对于id的使用十分简单明了,但很重要。这样表示只针对这个人的这个手指。 116 CircleGesture previousUpdate = CircleGesture(controller.frame(1).gesture(circle.id())); 117 //progress()表示手指旋转了几圈,如果是0.5表示旋转了半圈,如果是3表示已经旋转了3圈[计数功能很赞啊] 118 sweptAngle = (circle.progress() - previousUpdate.progress()) * 2 * PI;//一共旋转多少弧度[显示时他再次转换成角度] 119 } 120 std::cout << "Circle id: " << gesture.id() 121 << ", state: " << gesture.state() 122 << ", progress: " << circle.progress() 123 << ", radius: " << circle.radius() 124 << ", angle " << sweptAngle * RAD_TO_DEG 125 << ", " << clockwiseness << std::endl; 126 break; 127 } 128 case Gesture::TYPE_SWIPE: 129 {//相对旋转手势来说,这个以及下面几个简单很多 130 SwipeGesture swipe = gesture; 131 std::cout << "Swipe id: " << gesture.id() 132 << ", state: " << gesture.state() 133 << ", direction: " << swipe.direction()//这个可是能判断所有方向的,强大!我玩Kinect时只能识别几个特定的方向。 134 << ", speed: " << swipe.speed() << std::endl; 135 break; 136 } 137 case Gesture::TYPE_KEY_TAP: 138 { 139 KeyTapGesture tap = gesture; 140 std::cout << "Key Tap id: " << gesture.id() 141 << ", state: " << gesture.state() 142 << ", position: " << tap.position() 143 << ", direction: " << tap.direction()<< std::endl; 144 break; 145 } 146 case Gesture::TYPE_SCREEN_TAP: 147 { 148 ScreenTapGesture screentap = gesture; 149 std::cout << "Screen Tap id: " << gesture.id() 150 << ", state: " << gesture.state() 151 << ", position: " << screentap.position() 152 << ", direction: " << screentap.direction()<< std::endl; 153 break; 154 } 155 default: 156 std::cout << "Unknown gesture type." << std::endl; 157 break; 158 } 159 } 160 161 if (!frame.hands().isEmpty() || !gestures.isEmpty()) { 162 std::cout << std::endl; 163 } 164 // Sleep(1000);//如果嫌刷屏太快打开这个定义2(一共2处) 165 } 166 167 void SampleListener::onFocusGained(const Controller& controller) { 168 std::cout << "Focus Gained" << std::endl; 169 } 170 171 void SampleListener::onFocusLost(const Controller& controller) { 172 std::cout << "Focus Lost" << std::endl; 173 } 174 175 int main() { 176 // 创建例子监听者和控制器 177 SampleListener listener; 178 Controller controller; 179 180 // 让监听者获取控制器的数据并进行分析 181 controller.addListener(listener); 182 183 // 让程序一直运行,直到输入回车键才结束 184 std::cout << "Press Enter to quit..." << std::endl; 185 std::cin.get(); 186 187 // 移除监听者 188 controller.removeListener(listener); 189 190 return 0; 191 }