-
Notifications
You must be signed in to change notification settings - Fork 0
/
algebra.py
121 lines (91 loc) · 2.94 KB
/
algebra.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
'''
implements 3D vector and epsilon algebra for floating point values
'''
from __future__ import annotations # PEP 563: postponed evaluation of annotations
EPSILON = 1e-10
class EFloat(float):
'''
implementation of floating point numbers using ε algebra
- a > 0 if a > ε
- a < 0 if a < ε
- a == 0 if a in [-ε, ε]
'''
def __new__(cls, *args, **kwargs):
float.__new__(cls, *args, **kwargs)
def __init__(self, value):
float.__init__(value)
self.x = value
def __gt__(self, y):
return (self.x - y) > EPSILON
def __lt__(self, y):
return (self.x - y) < -EPSILON
def __ge__(self, y):
return (self.x - y) >= -EPSILON
def __le__(self, y):
return (self.x - y) <= EPSILON
def __eq__(self, y):
return abs(self.x - y) <= EPSILON
def __ne__(self, y):
return abs(self.x - y) > EPSILON
class Vector3d:
def __init__(self, x : float, y : float, z : float):
self.x = x
self.y = y
self.z = z
def dot(self, v : Vector3d) -> float:
return self.x * v.x + self.y * v.y + self.z * v.z
def __add__(self, v):
return Vector3d(self.x + v.x, self.y + v.y, self.z + v.z)
def __sub__(self, v):
return Vector3d(self.x - v.x, self.y - v.y, self.z - v.z)
def __mul__(self, s):
return Vector3d(self.x * s, self.y * s, self.z * s)
def __truediv__(self, s):
return Vector3d(self.x / s, self.y / s, self.z / s)
def __floordiv__(self, s):
return Vector3d(self.x // s, self.y // s, self.z // s)
def __gt__(self, v):
# implement 'all' logic
return all(self.x > v.x, self.y > v.y, self.z > v.z)
def __lt__(self, v):
# implement 'all' logic
return all(self.x < v.x, self.y < v.y, self.z < v.z)
def __ge__(self, v):
# implement 'all' logic
return all(self.x >= v.x, self.y >= v.y, self.z >= v.z)
def __le__(self, v):
# implement 'all' logic
return all(self.x <= v.x, self.y <= v.y, self.z <= v.z)
def __eq__(self, v):
return all(self.x == v.x, self.y == v.y, self.z == v.z)
def __ne__(self, v):
return any(self.x != v.x, self.y != v.y, self.z != v.z)
def __iadd__(self, v):
self.x += v.x
self.y += v.y
self.z += v.z
def __isub__(self, v):
self.x -= v.x
self.y -= v.y
self.z -= v.z
def __imul__(self, s):
self.x *= s
self.y *= s
self.z *= s
def __idiv__(self, s):
self.x /= s
self.y /= s
self.z /= s
def __ifloordiv__(self, s):
self.x //= s
self.y //= s
self.z //= s
def __getitem__(self, i):
if i == 0:
return self.x
elif i == 1:
return self.y
elif i == 2:
return self.z
else:
raise Exception("Vector3d index out of bounds.")