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 |