| OLD | NEW |
| (Empty) |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 """Objects for convenient manipulation of points and other surface areas.""" | |
| 6 | |
| 7 import collections | |
| 8 | |
| 9 | |
| 10 class Point(collections.namedtuple('Point', ['x', 'y'])): | |
| 11 """Object to represent an (x, y) point on a surface. | |
| 12 | |
| 13 Args: | |
| 14 x, y: Two numeric coordinates that define the point. | |
| 15 """ | |
| 16 __slots__ = () | |
| 17 | |
| 18 def __str__(self): | |
| 19 """Get a useful string representation of the object.""" | |
| 20 return '(%s, %s)' % (self.x, self.y) | |
| 21 | |
| 22 def __add__(self, other): | |
| 23 """Sum of two points, e.g. p + q.""" | |
| 24 if isinstance(other, Point): | |
| 25 return Point(self.x + other.x, self.y + other.y) | |
| 26 else: | |
| 27 return NotImplemented | |
| 28 | |
| 29 def __mul__(self, factor): | |
| 30 """Multiplication on the right is not implemented.""" | |
| 31 # This overrides the default behaviour of a tuple multiplied by a constant | |
| 32 # on the right, which does not make sense for a Point. | |
| 33 return NotImplemented | |
| 34 | |
| 35 def __rmul__(self, factor): | |
| 36 """Multiply a point by a scalar factor on the left, e.g. 2 * p.""" | |
| 37 return Point(factor * self.x, factor * self.y) | |
| 38 | |
| 39 | |
| 40 class Rectangle( | |
| 41 collections.namedtuple('Rectangle', ['top_left', 'bottom_right'])): | |
| 42 """Object to represent a rectangle on a surface. | |
| 43 | |
| 44 Args: | |
| 45 top_left: A pair of (left, top) coordinates. Might be given as a Point | |
| 46 or as a two-element sequence (list, tuple, etc.). | |
| 47 bottom_right: A pair (right, bottom) coordinates. | |
| 48 """ | |
| 49 __slots__ = () | |
| 50 | |
| 51 def __new__(cls, top_left, bottom_right): | |
| 52 if not isinstance(top_left, Point): | |
| 53 top_left = Point(*top_left) | |
| 54 if not isinstance(bottom_right, Point): | |
| 55 bottom_right = Point(*bottom_right) | |
| 56 return super(Rectangle, cls).__new__(cls, top_left, bottom_right) | |
| 57 | |
| 58 def __str__(self): | |
| 59 """Get a useful string representation of the object.""" | |
| 60 return '[%s, %s]' % (self.top_left, self.bottom_right) | |
| 61 | |
| 62 @property | |
| 63 def center(self): | |
| 64 """Get the point at the center of the rectangle.""" | |
| 65 return 0.5 * (self.top_left + self.bottom_right) | |
| 66 | |
| 67 @classmethod | |
| 68 def FromDict(cls, d): | |
| 69 """Create a rectangle object from a dictionary. | |
| 70 | |
| 71 Args: | |
| 72 d: A dictionary (or mapping) of the form, e.g., {'top': 0, 'left': 0, | |
| 73 'bottom': 1, 'right': 1}. | |
| 74 """ | |
| 75 return cls(Point(d['left'], d['top']), Point(d['right'], d['bottom'])) | |
| OLD | NEW |