1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez# Copyright 2015 The Chromium Authors. All rights reserved. 2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez# Use of this source code is governed by a BSD-style license that can be 3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez# found in the LICENSE file. 4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez"""Objects for convenient manipulation of points and other surface areas.""" 6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezimport collections 8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass Point(collections.namedtuple('Point', ['x', 'y'])): 11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Object to represent an (x, y) point on a surface. 12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez Args: 14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez x, y: Two numeric coordinates that define the point. 15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """ 16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez __slots__ = () 17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def __str__(self): 19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Get a useful string representation of the object.""" 20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return '(%s, %s)' % (self.x, self.y) 21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def __add__(self, other): 23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Sum of two points, e.g. p + q.""" 24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if isinstance(other, Point): 25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return Point(self.x + other.x, self.y + other.y) 26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez else: 27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return NotImplemented 28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def __mul__(self, factor): 30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Multiplication on the right is not implemented.""" 31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez # This overrides the default behaviour of a tuple multiplied by a constant 32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez # on the right, which does not make sense for a Point. 33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return NotImplemented 34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def __rmul__(self, factor): 36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Multiply a point by a scalar factor on the left, e.g. 2 * p.""" 37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return Point(factor * self.x, factor * self.y) 38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass Rectangle( 41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez collections.namedtuple('Rectangle', ['top_left', 'bottom_right'])): 42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Object to represent a rectangle on a surface. 43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez Args: 45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez top_left: A pair of (left, top) coordinates. Might be given as a Point 46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez or as a two-element sequence (list, tuple, etc.). 47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bottom_right: A pair (right, bottom) coordinates. 48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """ 49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez __slots__ = () 50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def __new__(cls, top_left, bottom_right): 52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if not isinstance(top_left, Point): 53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez top_left = Point(*top_left) 54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if not isinstance(bottom_right, Point): 55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bottom_right = Point(*bottom_right) 56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return super(Rectangle, cls).__new__(cls, top_left, bottom_right) 57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def __str__(self): 59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Get a useful string representation of the object.""" 60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return '[%s, %s]' % (self.top_left, self.bottom_right) 61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @property 63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def center(self): 64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Get the point at the center of the rectangle.""" 65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return 0.5 * (self.top_left + self.bottom_right) 66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez @classmethod 68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def FromDict(cls, d): 69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Create a rectangle object from a dictionary. 70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez Args: 72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez d: A dictionary (or mapping) of the form, e.g., {'top': 0, 'left': 0, 73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'bottom': 1, 'right': 1}. 74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """ 75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return cls(Point(d['left'], d['top']), Point(d['right'], d['bottom'])) 76