-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
utilities.py
142 lines (101 loc) · 4.62 KB
/
utilities.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
from __future__ import annotations
from math import sqrt, sin, cos
import json
class Vector:
"""A Python implementation of a vector class and some of its operations."""
values = None
def __init__(self, *args):
self.values = list(args)
def __str__(self):
"""String representation of a vector is its components surrounded by < and >."""
return f"<{str(self.values)[1:-1]}>"
__repr__ = __str__
def __len__(self):
"""Defines the length of the vector as the number of its components."""
return len(self.values)
def __hash__(self):
"""Defines the hash of the vector as a hash of a tuple with its components."""
return hash(tuple(self))
def __eq__(self, other):
"""Defines vector equality as the equality of all of its components."""
return self.values == other.values
def __setitem__(self, i, value):
"""Sets the i-th vector component to the specified value."""
self.values[i] = value
def __getitem__(self, i):
"""Either returns a new vector when sliced, or the i-th vector component."""
if type(i) == slice:
return Vector(*self.values[i])
else:
return self.values[i]
def __delitem__(self, i):
"""Deletes the i-th component of the vector."""
del self.values[i]
def __neg__(self):
"""Defines vector negation as the negation of all of its components."""
return Vector(*iter(-component for component in self))
def __add__(self, other):
"""Defines vector addition as the addition of each of their components."""
return Vector(*iter(u + v for u, v in zip(self, other)))
__iadd__ = __add__
def __sub__(self, other):
"""Defines vector subtraction as the subtraction of each of its components."""
return Vector(*iter(u - v for u, v in zip(self, other)))
__isub__ = __sub__
def __mul__(self, other):
"""Defines scalar and dot multiplication of a vector."""
if type(other) == int or type(other) == float:
# scalar multiplication
return Vector(*iter(component * other for component in self))
else:
# dot multiplication
return sum(u * v for u, v in zip(self, other))
__rmul__ = __imul__ = __mul__
def __truediv__(self, other):
"""Defines vector division by a scalar."""
return Vector(*iter(component / other for component in self))
def __floordiv__(self, other):
"""Defines floor vector division by a scalar."""
return Vector(*iter(component // other for component in self))
def __matmul__(self, other):
"""Defines cross multiplication of a vector."""
return Vector(
self[1] * other[2] - self[2] * other[1],
self[2] * other[0] - self[0] * other[2],
self[0] * other[1] - self[1] * other[0],
)
__imatmul__ = __matmul__
def __mod__(self, other):
"""Defines vector mod as the mod of its components."""
return Vector(*iter(component % other for component in self))
def magnitude(self):
"""Returns the magnitude of the vector."""
return sqrt(sum(component ** 2 for component in self))
def rotated(self, angle: float, point: Vector = None):
"""Returns this vector rotated by an angle (in radians) around a certain point."""
if point is None:
point = Vector(0, 0)
return self.__rotated(self - point, angle) + point
def rotated_new(self, angle: float, point: Vector = None):
"""Returns this vector rotated by an angle (in radians) around a certain point."""
if point is None:
point = Vector(0, 0)
return self.__rotated(self - point, angle) + point
def __rotated(self, vector: Vector, angle: float):
"""Returns a vector rotated by an angle (in radians)."""
return Vector(
vector[0] * cos(angle) - vector[1] * sin(angle),
vector[0] * sin(angle) + vector[1] * cos(angle),
)
def unit(self):
"""Returns a unit vector with the same direction as this vector."""
return self / self.magnitude()
def abs(self):
"""Returns a vector with absolute values of the components of this vector."""
return Vector(*iter(abs(component) for component in self))
def repeat(self, n):
"""Performs sequence repetition on the vector (n times)."""
return Vector(*self.values * n)
def distance(p1: Vector, p2: Vector):
"""Returns the distance of two points in space (represented as Vectors)."""
return sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)