【翻译】Leapmotion-python开发官方文档(7)

触摸仿真

LeapMotion的通用接口提供了一些功能使你能够在你的应用中实现触摸仿真。触摸仿真相关功能可以在Pointable类中找到。

概览

LeapMotion定义了一个自适应触摸面使你能够用来与你程序中的2D部件进行交互。这个平面大概是与x-y平面平行(译者注:应该是z-y吧?),但是与用户手及手指位置相适应。当用户向前触动手指或工具,LeapMotion会回馈pointable(即移动的手指或工具)是在接近还是触摸此虚拟界面。LeapMotion反馈两个值代表触摸:触摸区域和与触摸平面的距离。

虚拟触摸平面
触摸区域用于识别是否有一个Pointable对象悬停在触摸屏面附近、穿透触摸平面还是与平面距离过远(或者运动方向与触摸平面所在的方向相反)。这些区域包括“悬停(区)”、“触摸(区)”、“无触摸(区)”。触摸区之间的转换总滞后于触摸距离的变化。这个滞后适用于避免误识别和频繁转换。如果你在程序中使用触摸交互,你可能不需要经常考虑触摸区域。
触摸距离只有当一个Pointable对象处在悬停区或者触摸区时才是有效的。这个距离已经被归一化了,属于[+1,-1]。当一个Pointable对象第一次进入悬停区域,其触摸距离是+1.0同时离触摸界面越近,距离越小(向零减小)。当Pointable对象接触到触摸平面,距离为0.当Pointable再在触摸区间中深入,距离会无限接近-1.
你可以基于悬停区间和触摸区间值来决定何时更新UI部件。你可以基于与触摸平面的接近程度利用触摸距离进一步的修饰UI部件。比如,当有手指处于控制时,你可以将对应的UI部件标亮表明其处于受控状态,同时基于触摸距离改变光标,来向用户提供反馈——其离触摸控制界面的距离。
除了标准位置,作为触摸仿真的一部分,LeapMotion接口还为Pointable对象提供了稳定位置。LeapMotion软件使用一个能够平滑和减慢运动的自适应滤波器使位置变得稳定以便使用户更容易与屏幕的小区域进行互动(比如按钮和链接)。当运动变得很慢时,平滑会更剧烈,使得用户更容易能集中在一个点上进行触摸操作。

获得触摸区间

触摸空间由Pointable类的touchZone属性反馈。这些触摸区间用枚举类型进行识别,其定义如下:
NONE——pointable对象离触摸平面过远或者运动方向为用户的后方。
HOVERING——pointable对象的尖端进入悬停区间,但是不被识别为触摸。
TOUCHING——pointbale对象穿过触摸平面。
接下来的代码段展示了如何访问最前端的手指的触摸区间
zone = pointable.touch_zone

获取触摸距离

触摸距离可以通过Pointable类的touchDistance属性访问。这个距离介于+1与-1之间。这个距离并不代表物理量,只反应此Pointable对象与触摸平面的接近程度。

接下来的代码段展示了如何获得最前端手指的触摸距离:

distance = pointable.touch_distance

获得一个Pointable对象的稳定位置

稳定位置可以通过访问Pointable类的stabilizedTipPosition来获得。这个位置是以LeapMotion坐标系统为参考系的。
接下来的代码段展示了如何获得最前端手指的稳定距离:
frame = controller.frame()
pointable = frame.pointables.frontmost
stabilizedPosition = pointable.stabilized_tip_position

从LeapMotion坐标系统向应用程序的坐标系统转换

当使用触摸仿真时,你必须了解如何从LeapMotion的坐标空间转换到你程序的显示窗口空间。为了使转换更容易,LeapMotion接口提供了InteractionBox类。这个InteractionBox代表了一个处于LeapMotion视野中的线性空间。这个类提供了归一化位置坐标的函数,你可以归一化位置坐标然后根据你程序中窗口的尺寸进行缩放,从而将坐标点变换到程序坐标空间中。
比如,如果你有一个窗口,windowWidth和windowHeight分别代表窗口的宽和高,你可以使用下列代码得到一个触摸点的2D坐标:
frame = controller.frame()
finger = frame.fingers.frontmost
stabilizedPosition = finger.stabilized_tip_position

interactionBox = controller.frame().interaction_box
normalizedPosition = interactionBox.normalize_point(stabilizedPosition)
x = normalizedPosition.x * windowWidth
y = windowHeight - normalizedPosition.y * windowHeight

触摸点的例子

接下来的例子使用触摸仿真接口,在程序窗口中显示所有检测到的Pointable对象的位置。这个例子使用触摸区间改变每个点的颜色,使用触摸距离改变每个点的透明度。稳定的尖端位置通过使用Interactionbox类将其转换到程序窗口空间。
from Tkinter import Frame, Canvas, YES, BOTH
import Leap

class TouchPointListener(Leap.Listener):
    def on_init(self, controller):
        print "Initialized"

    def on_connect(self, controller):
        print "Connected"

    def on_frame(self, controller):
        self.paintCanvas.delete("all")
        frame = controller.frame()

        interactionBox = frame.interaction_box
        
        for pointable in frame.pointables:
            normalizedPosition = interactionBox.normalize_point(pointable.tip_position)
            if(pointable.touch_distance > 0 and pointable.touch_zone != Leap.Pointable.ZONE_NONE):
                color = self.rgb_to_hex((0, 255 - 255 * pointable.touch_distance, 0))
                
            elif(pointable.touch_distance <= 0):
                color = self.rgb_to_hex((-255 * pointable.touch_distance, 0, 0))
                #color = self.rgb_to_hex((255,0,0))
                
            else:
                color = self.rgb_to_hex((0,0,200))
                
            self.draw(normalizedPosition.x * 800, 600 - normalizedPosition.y * 600, 40, 40, color)

    def draw(self, x, y, width, height, color):
        self.paintCanvas.create_oval( x, y, x + width, y + height, fill = color, outline = "")

    def set_canvas(self, canvas):
        self.paintCanvas = canvas
        
    def rgb_to_hex(self, rgb):
        return '#%02x%02x%02x' % rgb

class PaintBox(Frame):

    def __init__( self ):
        Frame.__init__( self )
        self.leap = Leap.Controller()
        self.painter = TouchPointListener()
        self.leap.add_listener(self.painter)
        self.pack( expand = YES, fill = BOTH )
        self.master.title( "Touch Points" )
        self.master.geometry( "800x600" )
      
        # create Canvas component
        self.paintCanvas = Canvas( self, width = "800", height = "600" )
        self.paintCanvas.pack()
        self.painter.set_canvas(self.paintCanvas)

def main():
    PaintBox().mainloop()

if __name__ == "__main__":
    main()
这个例子使用了Tkinter模块,但是与LeapMotion相关的代码可以用于所有的Python项目。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值