from geometry.validation import is_coordinates, expect_type from geometry.drawing import centered_circle, write_label from superturtle.movement import fly from turtle import begin_fill, end_fill, fillcolor class Point: """A Point is a location in 2D space, identified by its x and y coordinates. A Point can be initialized in multiple ways: - With no value: The Point will be the origin (0, 0). - With an ordered pair of numbers: The Point will have those coordinates. - With a Vector: The Point will have the Vector's x and y coordinates. """ def __init__(self, value=None): from geometry.vector import Vector if value is None: self.x, self.y = (0, 0) elif is_coordinates(value): self.x, self.y = value elif isinstance(value, Vector): self.x, self.y = value.x, value.y else: raise TypeError(f"Can't create a Point from {value}.") def draw(self, label=None): fly(self.x, self.y) fillcolor("black") begin_fill() centered_circle(2) end_fill() if label: write_label(self, label) def __str__(self): return f"({self.x}, {self.y})" def __repr__(self): return f"Point(({self.x}, {self.y}))" def __eq__(self, other): """Implements equality checking with a == b. Two Points are equal if their coordinates are the same. A Point can only be equal to another Point. """ try: expect_type(other, Point) return (self.x, self.y) == (other.x, other.y) except TypeError: return False def __add__(self, other): """Implements addition with a + b. Other can be: - a Vector: interpreted as moving the point in the direction of the Vector, returning a new Point. """ from geometry.vector import Vector expect_type(other, Vector) return Point((self.x + other.x, self.y + other.y)) def __sub__(self, other): """Implements subtraction with a - b. Other can be: - a Point: interpreted as "what's needed to get from here to there, returning a Vector. - a Vector:interpreted as moving the point in the (negative) direction of the vector and returns a Point. """ from geometry.vector import Vector expect_type(other, (Point, Vector)) if isinstance(other, Point): return Vector((self.x - other.x, self.y - other.y)) elif isinstance(other, Vector): return Point((self.x - other.x, self.y - other.y))