Vector3D:一个三维向量类
今天我心血来潮,写了一个三维向量类,叫Vector3D
上代码
import math
class Vector3D:
"""
a three-dimensional class
"""
def __init__(self, n1, n2, n3):
if n1 <= 0 or n2 <= 0 or n3 <= 0:
raise TypeError('can not be 0 or lower')
self.n1 = n1
self.n2 = n2
self.n3 = n3
def __repr__(self):
return f'Vector3D({self.n1}, {self.n2}, {self.n3})'
def __add__(self, other):
if isinstance(other, Vector3D):
return Vector3D(self.n1 + other.n1, self.n2 + other.n2, self.n3 + other.n3)
else:
raise TypeError('The argument must be a Vector3D instance')
def __mul__(self, other):
if isinstance(other, Vector3D):
return Vector3D(self.n1 * other.n1, self.n2 * other.n2, self.n3 * other.n3)
else:
raise TypeError('The argument must be a Vector3D instance')
def __sub__(self, other):
if isinstance(other, Vector3D):
return Vector3D(self.n1 - other.n1, self.n2 - other.n2, self.n3 - other.n3)
else:
raise TypeError('The argument must be a Vector3D instance')
def __truediv__(self, other):
if isinstance(other, Vector3D):
return Vector3D(self.n1 / other.n1, self.n2 / other.n2, self.n3 / other.n3)
else:
raise TypeError('The argument must be a Vector3D instance')
def __abs__(self):
return Vector3D(abs(self.n1), abs(self.n2), abs(self.n3))
def __eq__(self, other):
if isinstance(other, Vector3D):
if self.n1 == other.n1 and self.n2 == other.n2 and self.n3 == other.n3:
return True
else:
return False
else:
raise TypeError('The argument must be a Vector3D instance')
def norm(self):
return math.sqrt(self.n1 ** 2 + self.n2 ** 2 + self.n3 ** 2)
def __iadd__(self, other):
if isinstance(other, Vector3D):
self.n1 += other.n1
self.n2 += other.n2
self.n3 += other.n3
return self
else:
raise TypeError('The argument must be a Vector3D instance')
def __imul__(self, other):
if isinstance(other, Vector3D):
self.n1 *= other.n1
self.n2 *= other.n2
self.n3 *= other.n3
return self
else:
raise TypeError('The argument must be a Vector3D instance')
def __isub__(self, other):
if isinstance(other, Vector3D):
self.n1 -= other.n1
self.n2 -= other.n2
self.n3 -= other.n3
return self
else:
raise TypeError('The argument must be a Vector3D instance')
def __itruediv__(self, other):
if isinstance(other, Vector3D):
self.n1 /= other.n1
self.n2 /= other.n2
self.n3 /= other.n3
return self
else:
raise TypeError('The argument must be a Vector3D instance')
def dot(self, other):
if isinstance(other, Vector3D):
return self.n1 * other.n1 + self.n2 * other.n2 + self.n3 * other.n3
else:
raise TypeError('The argument must be a Vector3D instance')
def cross(self, other):
if isinstance(other, Vector3D):
x = self.n2 * other.n3 - self.n3 * other.n2
y = self.n3 * other.n1 - self.n1 * other.n3
z = self.n1 * other.n2 - self.n2 * other.n1
return Vector3D(x, y, z)
else:
raise TypeError('The argument must be a Vector3D instance')
def normalize(self):
norm = self.norm()
if norm == 0:
raise ValueError('Cannot normalize the zero vector.')
else:
return Vector3D(self.n1 / norm, self.n2 / norm, self.n3 / norm)
def negate(self):
return Vector3D(-self.n1, -self.n2, -self.n3)
def angle_with(self, other):
if not isinstance(other, Vector3D):
raise TypeError('The argument must be a Vector3D instance')
dot_product = self.dot(other)
norms_product = self.norm() * other.norm()
cos_angle = max(min(dot_product / norms_product, 1), -1)
angle = math.acos(cos_angle)
return angle
def projection_on(self, other):
if not isinstance(other, Vector3D):
raise TypeError('The argument must be a Vector3D instance')
dot_product = self.dot(other)
other_norm_square = other.dot(other)
if other_norm_square == 0:
raise ValueError('Cannot project onto the zero vector')
scalar_projection = dot_product / other_norm_square
return Vector3D(scalar_projection * other.n1, scalar_projection * other.n2, scalar_projection * other.n3)
整个代码有一百多行,可以复制
又:之前有点事,好久没发,对不起!