-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathhelper.py
106 lines (79 loc) · 2.89 KB
/
helper.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
import math
def sign(x):
return math.copysign(1, x)
class Point(object):
def __init__(self, x=None, y=None, coordinates=None):
if coordinates is not None:
self.coordinates = coordinates
else:
self.coordinates = (x, y)
@property
def x(self):
return self.coordinates[0]
@property
def y(self):
return self.coordinates[1]
@property
def distance_to_origin(self):
return math.sqrt(self.x ** 2 + self.y ** 2)
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return Point(self.x - other.x, self.y - other.y)
def __truediv__(self, other):
if isinstance(other, int) or isinstance(other, float):
return Point(self.x / other, self.y / other)
else:
raise TypeError(f'unsupported operand type(s) for /: {type(self).__name__} and {type(other).__name__}')
def __floordiv__(self, other):
if isinstance(other, int):
return Point(self.x // other, self.y // other)
else:
raise TypeError(f'unsupported operand type(s) for /: {type(self).__name__} and {type(other).__name__}')
def __mul__(self, other):
if isinstance(other, int) or isinstance(other, float):
return Point(self.x * other, self.y * other)
else:
raise TypeError(f'unsupported operand type(s) for /: {type(self).__name__} and {type(other).__name__}')
def __round__(self, n=None):
return Point(round(self.x), round(self.y))
def __repr__(self):
return f'{type(self).__name__}(x={self.x}, y={self.y})'
@classmethod
def euclidean_distance(cls, point1, point2):
return (point1 - point2).distance_to_origin
class Size(Point):
@property
def width(self):
return self.x
@property
def height(self):
return self.y
@property
def shape(self):
return self.coordinates
class Line(object):
def __init__(self, point1, point2):
self.point1 = point1
self.point2 = point2
self.theta = self.get_theta()
def get_theta(self):
point = self.point2 - self.point1
return math.atan2(point.y, point.x)
@property
def rotation(self):
rotation = self.theta
if math.fabs(rotation) > math.pi / 2:
rotation = rotation - sign(rotation) * math.pi
return math.degrees(rotation)
@property
def slope(self):
m = (self.point2.y - self.point1.y) / (self.point2.x - self.point1.x)
return m
@property
def distance(self):
return Point.euclidean_distance(self.point1, self.point2)
def get_equidistant_points(self, percent=0.15):
point1 = self.point1 * (1 - percent) + self.point2 * percent
point2 = self.point1 * percent + self.point2 * (1 - percent)
return round(point1), round(point2)