Coverage for lib/lottie/nvector.py: 77%
88 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-20 16:17 +0100
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-20 16:17 +0100
1import operator
2import math
5def vop(op, a, b):
6 return list(map(op, a, b))
9class NVector():
10 def __init__(self, *components):
11 self.components = list(components)
13 def __str__(self):
14 return str(self.components)
16 def __repr__(self):
17 return "NVector(%s)" % ", ".join(map(str, self))
19 def __len__(self):
20 return len(self.components)
22 def to_list(self):
23 return list(self.components)
25 def __add__(self, other):
26 return type(self)(*vop(operator.add, self.components, other.components))
28 def __sub__(self, other):
29 return type(self)(*vop(operator.sub, self.components, other.components))
31 def __mul__(self, scalar):
32 if isinstance(scalar, NVector): 32 ↛ 33line 32 didn't jump to line 33, because the condition on line 32 was never true
33 return type(self)(*vop(operator.mul, self.components, scalar.components))
34 return type(self)(*(c * scalar for c in self.components))
36 def __truediv__(self, scalar):
37 return type(self)(*(c / scalar for c in self.components))
39 def __iadd__(self, other):
40 self.components = vop(operator.add, self.components, other.components)
41 return self
43 def __isub__(self, other):
44 self.components = vop(operator.sub, self.components, other.components)
45 return self
47 def __imul__(self, scalar):
48 if isinstance(scalar, NVector):
49 self.components = vop(operator.mul, self.components, scalar.components)
50 else:
51 self.components = [c * scalar for c in self.components]
52 return self
54 def __itruediv__(self, scalar):
55 self.components = [c / scalar for c in self.components]
56 return self
58 def __neg__(self):
59 return type(self)(*(-c for c in self.components))
61 def __getitem__(self, key):
62 if isinstance(key, slice):
63 return NVector(*self.components[key])
64 return self.components[key]
66 def __setitem__(self, key, value):
67 self.components[key] = value
69 def __eq__(self, other):
70 return self.components == other.components
72 def __abs__(self):
73 return type(self)(*(abs(c) for c in self.components))
75 @property
76 def length(self) -> float:
77 return math.sqrt(sum(map(lambda x: x**2, self.components)))
79 def dot(self, other):
80 return sum(map(operator.mul, self.components, other.components))
82 def clone(self):
83 return NVector(*self.components)
85 def lerp(self, other, t):
86 return self * (1-t) + other * t
88 @property
89 def x(self):
90 return self.components[0]
92 @x.setter
93 def x(self, v):
94 self.components[0] = v
96 @property
97 def y(self):
98 return self.components[1]
100 @y.setter
101 def y(self, v):
102 self.components[1] = v
104 @property
105 def z(self):
106 return self.components[2]
108 @z.setter
109 def z(self, v):
110 self.components[2] = v
112 def element_scaled(self, other):
113 return type(self)(*vop(operator.mul, self.components, other.components))
115 def cross(self, other):
116 """
117 @pre len(self) == len(other) == 3
118 """
119 a = self
120 b = other
121 return type(self)(
122 a[1] * b[2] - a[2] * b[1],
123 a[2] * b[0] - a[0] * b[2],
124 a[0] * b[1] - a[1] * b[0],
125 )
127 @property
128 def polar_angle(self):
129 """
130 @pre len(self) == 2
131 """
132 return math.atan2(self.y, self.x)
135def Point(x, y):
136 return NVector(x, y)
139def Size(x, y):
140 return NVector(x, y)
143def Point3D(x, y, z):
144 return NVector(x, y, z)
147def PolarVector(length, theta):
148 return NVector(length * math.cos(theta), length * math.sin(theta))