from src.tracker import GestureTracker, Gesture class HandGesture(Gesture): def __init__(self, hand, finger): self.hand = hand self.finger = finger def get_hand(self): return self.hand def get_finger(self): return self.finger def is_first(self): return len(self.hand) == 1 def is_last(self): return not len(self.hand) class FingerDownGesture(HandGesture): _type = 'finger_down' class FingerMoveGesture(HandGesture): _type = 'finger_move' class FingerUpGesture(HandGesture): _type = 'finger_up' class Hand(object): def __init__(self): self.fingers = [] def __len__(self): return len(self.fingers) def __iter__(self): return iter(self.fingers) def __str__(self): return '' \ % (self.fingers, self.get_centroid()) def __repr__(self): return str(self) def contains(self, finger, max_distance): for other_finger in self.fingers: if other_finger.distance_to(finger) <= max_distance: return True return False def add_finger(self, finger): self.fingers.append(finger) def remove_finger(self, finger): self.fingers.remove(finger) def get_centroid(self): l = len(self.fingers) coords = [f.get_position() for f in self.fingers] all_x, all_y = zip(*coords) return sum(all_x) / l, sum(all_y) / l class HandTracker(GestureTracker): supported_gestures = [FingerDownGesture, FingerMoveGesture, FingerUpGesture] configurable = ['max_finger_distance'] def __init__(self, area): super(HandTracker, self).__init__(area) # Map of finger id's to corresponding hand objects self.finger_hands = {} # All hands being tracked self.hands = [] # Maximum distance between two fingers to be assigned to the same hand self.max_finger_distance = 300 def find_hand(self, finger): for hand in self.hands: if hand.contains(finger, self.max_finger_distance): return hand self.hands.append(Hand()) return self.hands[-1] def on_point_down(self, event): finger = event.get_touch_object() hand = self.find_hand(finger) hand.add_finger(finger) self.finger_hands[finger.get_id()] = hand self.trigger(FingerDownGesture(hand, finger)) def on_point_move(self, event): finger = event.get_touch_object() if finger.get_id() not in self.finger_hands: return hand = self.finger_hands[finger.get_id()] self.trigger(FingerMoveGesture(hand, finger)) def on_point_up(self, event): finger = event.get_touch_object() finger_id = finger.get_id() if finger_id not in self.finger_hands: return hand = self.finger_hands[finger_id] del self.finger_hands[finger_id] hand.remove_finger(finger) if not len(hand): self.hands.remove(hand) self.trigger(FingerUpGesture(hand, finger))