def _scale(self, point, rel, reverse, ratio): width = float(self.shape.bounds.width) height = float(self.shape.bounds.height) if ratio: old_r = self.grabbed_stamp.scale[1] / self.grabbed_stamp.scale[0] if old_r != ratio: self.grabbed_stamp.scale = (self.grabbed_stamp.scale[0], ratio * self.grabbed_stamp.scale[0]) print 'ratio:', self.grabbed_stamp.scale[1] / self.grabbed_stamp.scale[0] if reverse: anchor = Point(width/2 * self.grabbed_stamp.scale[0], height/2 * self.grabbed_stamp.scale[1]) else: anchor = Point(-width/2 * self.grabbed_stamp.scale[0], -height/2 * self.grabbed_stamp.scale[1]) anchor = Point.rotate(anchor, self.grabbed_stamp.angle) anchor.x += self.grabbed_stamp.pos.x anchor.y += self.grabbed_stamp.pos.y rel = Point(point.x - anchor.x, point.y - anchor.y) rel = Point.rotate(rel, -self.grabbed_stamp.angle) if ratio != None: a = self.grabbed_stamp.scale[0] > 0 b = rel.x < rel.y c = reverse # No, this is not pretty. But I didn't like the alternative much # either. This reassigns either the x or y value such that # rel.y / rel.x = ratio, while also indirectly keeding the anchor # 'within' rel. This creates the expeceted behavior while resizing # and keeping the ratio, even when mirrored and flipped. if ((a and b and c) or (a and not b and not c) or (not a and b and not c) or (not a and not b and c)): rel.y = ratio * rel.x elif ((a and b and not c) or (a and not b and c) or (not a and b and c) or (not a and not b and not c)): rel.x = 1 / ratio * rel.y dx = rel.x dy = rel.y if reverse: dx = -dx dy = -dy old_scale_x = self.grabbed_stamp.scale[0] old_scale_y = self.grabbed_stamp.scale[1] old_dx = width - old_scale_x * width old_dy = height - old_scale_y * height new_dx = old_dx + dx new_dy = old_dy + dy new_scale_x = (width - new_dx) / width new_scale_y = (height - new_dy) / height if abs(new_scale_x) > 0.1 and abs(new_scale_y) > 0.1: self.grabbed_stamp.scale = (new_scale_x, new_scale_y) if reverse: dx = -dx dy = -dy p = Point.rotate(Point(dx, dy), self.grabbed_stamp.angle) self.grabbed_stamp.pos.x += p.x / 2.0 self.grabbed_stamp.pos.y += p.y / 2.0
def snapToGrid(self, point): snap_point = Point(point.x, point.y) width = self.surface.get_width() center = width / 2 half = self.grid_size / 2 offset = map(lambda x: x - center, range(center % self.grid_size, width, self.grid_size)) possible_x = range(point.x - half, point.x + half) possible_y = range(point.y - half, point.y + half) for x in possible_x: if x in offset: snap_point.x = x break for y in possible_y: if y in offset: snap_point.y = y break return snap_point
def localPoint(self, global_point): local_point = Point() local_point.x = global_point.x - self.rect.left - self.rect.width / 2 local_point.y = global_point.y - self.rect.top - self.rect.height / 2 return local_point