# vispy/vispy

Fetching contributors…
Cannot retrieve contributors at this time
203 lines (164 sloc) 5.32 KB
 import numpy as np class Rect(object): """ Representation of a rectangular area in a 2D coordinate system. Parameters ---------- *args : arguments Can be in the form `Rect(x, y, w, h)`, `Rect(pos, size)`, or `Rect(Rect)`. """ def __init__(self, *args, **kwargs): self._pos = (0, 0) self._size = (0, 0) if len(args) == 1 and isinstance(args[0], Rect): self._pos = args[0]._pos[:] self._size = args[0]._size[:] elif (len(args) == 1 and isinstance(args[0], (list, tuple)) and len(args[0]) == 4): self._pos = args[0][:2] self._size = args[0][2:] elif len(args) == 2: self._pos = tuple(args[0]) self._size = tuple(args[1]) elif len(args) == 4: self._pos = tuple(args[:2]) self._size = tuple(args[2:]) elif len(args) != 0: raise TypeError("Rect must be instantiated with 0, 1, 2, or 4 " "non-keyword arguments.") self._pos = kwargs.get('pos', self._pos) self._size = kwargs.get('size', self._size) if len(self._pos) != 2 or len(self._size) != 2: raise ValueError("Rect pos and size arguments must have 2 " "elements.") @property def pos(self): return tuple(self._pos) @pos.setter def pos(self, p): assert len(p) == 2 self._pos = p @property def size(self): return tuple(self._size) @size.setter def size(self, s): assert len(s) == 2 self._size = s @property def width(self): return self.size[0] @width.setter def width(self, w): self.size[0] = w @property def height(self): return self.size[1] @height.setter def height(self, h): self.size[1] = h @property def left(self): return self.pos[0] @left.setter def left(self, x): self.size = (self.size[0] + (self.pos[0] - x), self.size[1]) self.pos = (x, self.pos[1]) @property def right(self): return self.pos[0] + self.size[0] @right.setter def right(self, x): self.size = (x - self.pos[0], self.size[1]) @property def bottom(self): return self.pos[1] @bottom.setter def bottom(self, y): self.size = (self.size[0], self.size[1] + (self.pos[1] - y)) self.pos = (self.pos[0], y) @property def top(self): return self.pos[1] + self.size[1] @top.setter def top(self, y): self.size = (self.size[0], y - self.pos[1]) @property def center(self): return (self.pos[0] + self.size[0] * 0.5, self.pos[1] + self.size[1] * 0.5) def padded(self, padding): """Return a new Rect padded (smaller) by padding on all sides Parameters ---------- padding : float The padding. Returns ------- rect : instance of Rect The padded rectangle. """ return Rect(pos=(self.pos[0]+padding, self.pos[1]+padding), size=(self.size[0]-2*padding, self.size[1]-2*padding)) def normalized(self): """Return a Rect covering the same area, but with height and width guaranteed to be positive.""" return Rect(pos=(min(self.left, self.right), min(self.top, self.bottom)), size=(abs(self.width), abs(self.height))) def flipped(self, x=False, y=True): """Return a Rect with the same bounds but with axes inverted Parameters ---------- x : bool Flip the X axis. y : bool Flip the Y axis. Returns ------- rect : instance of Rect The flipped rectangle. """ pos = list(self.pos) size = list(self.size) for i, flip in enumerate((x, y)): if flip: pos[i] += size[i] size[i] *= -1 return Rect(pos, size) def __eq__(self, r): if not isinstance(r, Rect): return False return (np.all(np.equal(r.pos, self.pos)) and np.all(np.equal(r.size, self.size))) def __add__(self, a): """ Return this Rect translated by *a*. """ return self._transform_out(self._transform_in()[:, :2] + a[:2]) def contains(self, x, y): """Query if the rectangle contains points Parameters ---------- x : float X coordinate. y : float Y coordinate. Returns ------- contains : bool True if the point is within the rectangle. """ return (x >= self.left and x <= self.right and y >= self.bottom and y <= self.top) def __repr__(self): return "" % (self.pos + self.size) def _transform_in(self): """Return array of coordinates that can be mapped by Transform classes.""" return np.array([ [self.left, self.bottom, 0, 1], [self.right, self.top, 0, 1]]) def _transform_out(self, coords): """Return a new Rect from coordinates mapped after _transform_in().""" return Rect(pos=coords[0, :2], size=coords[1, :2]-coords[0, :2])