Browse Source

Rewritten test file draw.py using trackers.

Taddeus Kroes 13 years ago
parent
commit
2632de4524
3 changed files with 174 additions and 25 deletions
  1. 6 0
      src/trackers/transform.py
  2. 167 0
      tests/draw.py
  3. 1 25
      tests/transform.py

+ 6 - 0
src/trackers/transform.py

@@ -84,6 +84,9 @@ class RotationGesture(Positionable, Gesture):
         return '<RotationGesture at (%s, %s) angle=%s>' \
         return '<RotationGesture at (%s, %s) angle=%s>' \
                % (self.x, self.y, self.angle)
                % (self.x, self.y, self.angle)
 
 
+    def get_angle(self):
+        return self.angle
+
 
 
 class PinchGesture(Positionable, Gesture):
 class PinchGesture(Positionable, Gesture):
     """
     """
@@ -100,6 +103,9 @@ class PinchGesture(Positionable, Gesture):
         return '<PinchGesture at (%s, %s) scale=%s>' \
         return '<PinchGesture at (%s, %s) scale=%s>' \
                % (self.x, self.y, self.scale)
                % (self.x, self.y, self.scale)
 
 
+    def get_scale(self):
+        return self.scale
+
 
 
 class MovementGesture(Positionable, Gesture):
 class MovementGesture(Positionable, Gesture):
     """
     """

+ 167 - 0
tests/draw.py

@@ -0,0 +1,167 @@
+#!/usr/bin/env python
+from __future__ import division
+import pygame
+import sys
+import time
+from threading import Thread
+from math import degrees, cos, sin
+
+from src.server import GestureServer
+from src.window import FullscreenWindow
+from src.trackers.transform import TransformationTracker
+from src.trackers.tap import TapTracker
+from src.screen import screen_size
+
+import tests.parse_arguments
+
+
+pygame.init()
+
+FULLSCREEN = '-f' in sys.argv[1:]
+
+# Config
+FINGER_RADIUS = 20
+CENTROID_RADIUS = 15
+W, H = screen_size if FULLSCREEN else (640, 480)
+
+BG_COLOR = 0, 0, 0
+LINE_COLOR = 128, 128, 128
+CIRCLE_COLOR = 255, 255, 255
+RECT_COLOR = 0, 200, 0
+RECT_POS = W / 2, H / 2
+RECT_SIZE = W / 6., H / 6.
+
+TAP_RADIUS = 65
+TAP_INCREMENT = .3
+
+BEAM_COLOR = 255, 50, 50
+BEAM_LENGTH = 50
+BEAM_WIDTH = 3
+BEAM_INCREMENT = .8
+
+MAX_SCALE = 10
+
+# Create canvas GUI
+flags = pygame.FULLSCREEN if FULLSCREEN else 0
+screen = pygame.display.set_mode((W, H), flags)
+
+
+def coord(x, y):
+    w, h = screen_size
+    return int(round(W / w * x)), int(round(H / h * y))
+
+
+# Global state
+angle = 0
+scale = 1
+taps = []
+dtaps = []
+
+
+def update():
+    global taps, dtaps
+
+    # Clear previous frame
+    screen.fill(BG_COLOR)
+
+    # Apply scale and rotation to a fixed-size rectangle canvas
+    canvas = pygame.Surface(RECT_SIZE)
+    canvas.fill(RECT_COLOR)
+    transformed = pygame.transform.rotozoom(canvas, degrees(angle), scale)
+    rect = transformed.get_rect()
+    rect.center = W / 2, H / 2
+    screen.blit(transformed, rect)
+
+    # Draw touch points
+    if transform.centroid:
+        c = coord(*transform.centroid.xy)
+
+    for p in server.points.itervalues():
+        xy = coord(p.x, p.y)
+
+        # Draw line to centroid
+        if transform.centroid:
+            pygame.draw.line(screen, LINE_COLOR, xy, c, 1)
+
+        # Draw outlined circle around touch point
+        pygame.draw.circle(screen, CIRCLE_COLOR, xy, FINGER_RADIUS, 1)
+
+        # Fill filled circle with background color within the outline
+        pygame.draw.circle(screen, BG_COLOR, xy, FINGER_RADIUS - 1, 0)
+
+    # Draw filled circle around centroid
+    if transform.centroid:
+        pygame.draw.circle(screen, CIRCLE_COLOR, c, CENTROID_RADIUS)
+
+    # Draw an expanding circle around each tap event
+    taps = filter(lambda (xy, r): r <= TAP_RADIUS, taps)
+
+    for tap in taps:
+        xy, radius = tap
+        pygame.draw.circle(screen, CIRCLE_COLOR, xy, int(radius), 2)
+
+        # Increment radius
+        tap[1] += TAP_INCREMENT
+
+    # Shoot a beam from each double tap event to the left
+    dtaps = filter(lambda (x, y, s): 0 <= x <= W, dtaps)
+
+    for dtap in dtaps:
+        x, y, single = dtap
+
+        if single:
+            start_x = x
+            end_x = x + BEAM_LENGTH
+            dtap[0] += BEAM_INCREMENT
+        else:
+            start_x = x - BEAM_LENGTH
+            end_x = x
+            dtap[0] -= BEAM_INCREMENT
+
+        pygame.draw.line(screen, BEAM_COLOR, (start_x, y), (end_x, y), BEAM_WIDTH)
+
+    # Update canvas
+    pygame.display.flip()
+
+
+# Create server and fullscreen window
+server = GestureServer()
+win = FullscreenWindow(server=server)
+
+
+# Bind trackers
+def rotate(gesture):
+    global angle
+    angle += gesture.get_angle()
+
+def pinch(gesture):
+    global scale
+    scale = min(scale * gesture.get_scale(), MAX_SCALE)
+
+transform = TransformationTracker(win)
+transform.bind('rotate', rotate)
+transform.bind('pinch', pinch)
+
+tap = TapTracker(win)
+tap.bind('tap', lambda g: taps.append([coord(*g.xy), FINGER_RADIUS]))
+tap.bind('single_tap', lambda g: dtaps.append(list(coord(*g.xy)) + [1]))
+tap.bind('double_tap', lambda g: dtaps.append(list(coord(*g.xy)) + [0]))
+
+
+try:
+    # Start touch gesture server in separate thread
+    thread = Thread(target=server.start)
+    thread.daemon = True
+    thread.start()
+
+    # Start GUI event loop
+    def is_quit_event(e):
+        return e.type == pygame.QUIT \
+            or (e.type == pygame.KEYDOWN and e.key == ord('q'))
+
+    while not any(filter(is_quit_event, pygame.event.get())):
+        update()
+except KeyboardInterrupt:
+    pass
+finally:
+    server.stop()

+ 1 - 25
tests/transform.py

@@ -1,32 +1,8 @@
-import argparse
-import logging
-
 from src.server import GestureServer
 from src.server import GestureServer
 from src.window import FullscreenWindow
 from src.window import FullscreenWindow
 from src.trackers.transform import TransformationTracker
 from src.trackers.transform import TransformationTracker
-from src.logger import Logger
-
-
-# Parse arguments
-parser = argparse.ArgumentParser(description='Basic test program for usage '
-                                             'of multi-touch API.')
-parser.add_argument('--log', metavar='LOG_LEVEL', default='INFO',
-                    choices=['DEBUG', 'INFO', 'WARNING'],
-                    help='set log level (defaults to INFO)')
-parser.add_argument('--logfile', metavar='FILENAME',
-                    help='filename for the log file (the log is printed to '
-                         'stdout by default)')
-args = parser.parse_args()
-
-
-# Configure logger
-log_config = {'level': getattr(logging, args.log)}
-
-if args.logfile:
-    log_config['filename'] = args.logfile
-
-Logger.configure(**log_config)
 
 
+import tests.parse_arguments
 
 
 # Create server
 # Create server
 server = GestureServer()
 server = GestureServer()