lab_geometry/geometry/point.py

74 lines
2.6 KiB
Python

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))