File indexing completed on 2025-01-19 03:59:55

0001 import operator
0002 import math
0003 
0004 
0005 def vop(op, a, b):
0006     return list(map(op, a, b))
0007 
0008 
0009 class NVector():
0010     def __init__(self, *components):
0011         self.components = list(components)
0012 
0013     def __str__(self):
0014         return str(self.components)
0015 
0016     def __repr__(self):
0017         return "<NVector %s>" % self
0018 
0019     def __len__(self):
0020         return len(self.components)
0021 
0022     def to_list(self):
0023         return list(self.components)
0024 
0025     def __add__(self, other):
0026         return type(self)(*vop(operator.add, self.components, other.components))
0027 
0028     def __sub__(self, other):
0029         return type(self)(*vop(operator.sub, self.components, other.components))
0030 
0031     def __mul__(self, scalar):
0032         if isinstance(scalar, NVector):
0033             return type(self)(*vop(operator.mul, self.components, scalar.components))
0034         return type(self)(*(c * scalar for c in self.components))
0035 
0036     def __truediv__(self, scalar):
0037         return type(self)(*(c / scalar for c in self.components))
0038 
0039     def __iadd__(self, other):
0040         self.components = vop(operator.add, self.components, other.components)
0041         return self
0042 
0043     def __isub__(self, other):
0044         self.components = vop(operator.sub, self.components, other.components)
0045         return self
0046 
0047     def __imul__(self, scalar):
0048         if isinstance(scalar, NVector):
0049             self.components = vop(operator.mul, self.components, scalar.components)
0050         else:
0051             self.components = [c * scalar for c in self.components]
0052         return self
0053 
0054     def __itruediv__(self, scalar):
0055         self.components = [c / scalar for c in self.components]
0056         return self
0057 
0058     def __neg__(self):
0059         return type(self)(*(-c for c in self.components))
0060 
0061     def __getitem__(self, key):
0062         if isinstance(key, slice):
0063             return NVector(*self.components[key])
0064         return self.components[key]
0065 
0066     def __setitem__(self, key, value):
0067         self.components[key] = value
0068 
0069     def __eq__(self, other):
0070         return self.components == other.components
0071 
0072     def __abs__(self):
0073         return type(self)(*(abs(c) for c in self.components))
0074 
0075     @property
0076     def length(self):
0077         return math.sqrt(sum(map(lambda x: x**2, self.components)))
0078 
0079     def dot(self, other):
0080         return sum(map(operator.mul, self.components, other.components))
0081 
0082     def clone(self):
0083         return NVector(*self.components)
0084 
0085     def lerp(self, other, t):
0086         return self * (1-t) + other * t
0087 
0088     @property
0089     def x(self):
0090         return self.components[0]
0091 
0092     @x.setter
0093     def x(self, v):
0094         self.components[0] = v
0095 
0096     @property
0097     def y(self):
0098         return self.components[1]
0099 
0100     @y.setter
0101     def y(self, v):
0102         self.components[1] = v
0103 
0104     @property
0105     def z(self):
0106         return self.components[2]
0107 
0108     @z.setter
0109     def z(self, v):
0110         self.components[2] = v
0111 
0112     def element_scaled(self, other):
0113         return type(self)(*vop(operator.mul, self.components, other.components))
0114 
0115     def cross(self, other):
0116         """
0117         @pre len(self) == len(other) == 3
0118         """
0119         a = self
0120         b = other
0121         return type(self)(
0122             a[1] * b[2] - a[2] * b[1],
0123             a[2] * b[0] - a[0] * b[2],
0124             a[0] * b[1] - a[1] * b[0],
0125         )
0126 
0127     @property
0128     def polar_angle(self):
0129         """
0130         @pre len(self) == 2
0131         """
0132         return math.atan2(self.y, self.x)
0133 
0134 
0135 def Point(x, y):
0136     return NVector(x, y)
0137 
0138 
0139 def Size(x, y):
0140     return NVector(x, y)
0141 
0142 
0143 def Point3D(x, y, z):
0144     return NVector(x, y, z)
0145 
0146 
0147 def PolarVector(length, theta):
0148     return NVector(length * math.cos(theta), length * math.sin(theta))