from __future__ import division from time import sleep from threading import Thread from numpy import array, diag, dot, cos, sin from src import RectangularArea class BoundingBoxArea(RectangularArea): def __init__(self, x, y, points): super(BoundingBoxArea, self).__init__(x, y, 0, 0) self.points = array(points).T self.update_bounds() def translate_points(self, tx, ty): self.points += [[tx], [ty]] def scale_points(self, scale, cx, cy): self.translate_points(-cx, -cy) self.points = dot(diag([scale, scale]), self.points) self.translate_points(cx, cy) def rotate_points(self, angle, cx, cy): cosa = cos(angle) sina = sin(angle) mat = array([[cosa, -sina], [sina, cosa]]) self.translate_points(-cx, -cy) self.points = dot(mat, self.points) self.translate_points(cx, cy) def update_bounds(self): min_x, min_y = self.points.min(1) max_x, max_y = self.points.max(1) self.set_size(max_x - min_x, max_y - min_y) if min_x or min_y: self.translate(min_x, min_y) self.translate_points(-min_x, -min_y) FLICK_UPDATE_RATE = 30 class Flick(object): def __init__(self, callback, seconds, start_amount=1.0): self.callback = callback self.amount = start_amount self.iterations = int(seconds * FLICK_UPDATE_RATE) self.reduce_rate = start_amount / self.iterations def iteration(self): self.callback(self.amount) self.amount -= self.reduce_rate self.iterations -= 1 return self.is_not_done() def is_not_done(self): return self.iterations > 0 def is_done(self): return self.iterations <= 0 class FlickThread(Thread): def __init__(self): super(FlickThread, self).__init__() self.flicks = [] def run(self): while True: self.flicks = filter(Flick.iteration, self.flicks) sleep(1 / FLICK_UPDATE_RATE) def add(self, flick): self.flicks.append(flick)