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

1import operator 

2import math 

3 

4 

5def vop(op, a, b): 

6 return list(map(op, a, b)) 

7 

8 

9class NVector(): 

10 def __init__(self, *components): 

11 self.components = list(components) 

12 

13 def __str__(self): 

14 return str(self.components) 

15 

16 def __repr__(self): 

17 return "NVector(%s)" % ", ".join(map(str, self)) 

18 

19 def __len__(self): 

20 return len(self.components) 

21 

22 def to_list(self): 

23 return list(self.components) 

24 

25 def __add__(self, other): 

26 return type(self)(*vop(operator.add, self.components, other.components)) 

27 

28 def __sub__(self, other): 

29 return type(self)(*vop(operator.sub, self.components, other.components)) 

30 

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

35 

36 def __truediv__(self, scalar): 

37 return type(self)(*(c / scalar for c in self.components)) 

38 

39 def __iadd__(self, other): 

40 self.components = vop(operator.add, self.components, other.components) 

41 return self 

42 

43 def __isub__(self, other): 

44 self.components = vop(operator.sub, self.components, other.components) 

45 return self 

46 

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 

53 

54 def __itruediv__(self, scalar): 

55 self.components = [c / scalar for c in self.components] 

56 return self 

57 

58 def __neg__(self): 

59 return type(self)(*(-c for c in self.components)) 

60 

61 def __getitem__(self, key): 

62 if isinstance(key, slice): 

63 return NVector(*self.components[key]) 

64 return self.components[key] 

65 

66 def __setitem__(self, key, value): 

67 self.components[key] = value 

68 

69 def __eq__(self, other): 

70 return self.components == other.components 

71 

72 def __abs__(self): 

73 return type(self)(*(abs(c) for c in self.components)) 

74 

75 @property 

76 def length(self) -> float: 

77 return math.sqrt(sum(map(lambda x: x**2, self.components))) 

78 

79 def dot(self, other): 

80 return sum(map(operator.mul, self.components, other.components)) 

81 

82 def clone(self): 

83 return NVector(*self.components) 

84 

85 def lerp(self, other, t): 

86 return self * (1-t) + other * t 

87 

88 @property 

89 def x(self): 

90 return self.components[0] 

91 

92 @x.setter 

93 def x(self, v): 

94 self.components[0] = v 

95 

96 @property 

97 def y(self): 

98 return self.components[1] 

99 

100 @y.setter 

101 def y(self, v): 

102 self.components[1] = v 

103 

104 @property 

105 def z(self): 

106 return self.components[2] 

107 

108 @z.setter 

109 def z(self, v): 

110 self.components[2] = v 

111 

112 def element_scaled(self, other): 

113 return type(self)(*vop(operator.mul, self.components, other.components)) 

114 

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 ) 

126 

127 @property 

128 def polar_angle(self): 

129 """ 

130 @pre len(self) == 2 

131 """ 

132 return math.atan2(self.y, self.x) 

133 

134 

135def Point(x, y): 

136 return NVector(x, y) 

137 

138 

139def Size(x, y): 

140 return NVector(x, y) 

141 

142 

143def Point3D(x, y, z): 

144 return NVector(x, y, z) 

145 

146 

147def PolarVector(length, theta): 

148 return NVector(length * math.cos(theta), length * math.sin(theta))