from math import sqrt, acos, degrees

class Vector:
    '''Klasse zum Rechnen mit 3D-Vektoren'''
    
    def __init__(self, x, y, z):
        '''Gibt die Adresse eines 3D-Vektors zurück'''
        self.x = x
        self.y = y
        self.z = z

    def __str__(self):
        '''Gibt Textdarstellung des Vektors zurück'''
        return f'({self.x},{self.y},{self.z})^T'

    def __add__(self, other):
        '''Gibt Summe der Vektoren als Vektor zurück'''
        return Vector(self.x+other.x, self.y+other.y, self.z+other.z)

    def __sub__(self, other):
        '''Gibt Differenz der Vektoren als Vektor zurück'''
        return Vector(self.x-other.x, self.y-other.y, self.z-other.z)

    def __rmul__(self, k):
        '''Gibt k-faches des Vektors als Vektor zurück'''
        return Vector(k*self.x, k*self.y, k*self.z)

    def __abs__(self):
        '''Gibt den Betrag des Vektors zurück'''
        return sqrt(self.x**2 + self.y**2 + self.z**2) 

    def dot(self, other):
        '''Gibt das Skalarprodukt der Vektoren zurück'''
        return self.x*other.x + self.y*other.y + self.z*other.z

    def angle(self, other):
        '''Gibt den Zwischenwinkel der Vektoren in Grad zurück.'''
        return degrees(acos(self.dot(other)/abs(self)/abs(other)))
    

    def cross(self, other):
        '''Gibt das Vektorprodunkt der Vektoren zurück'''
        x = self.y*other.z - self.z*other.y
        y = self.z*other.x - self.x*other.z
        z = self.x*other.y + self.y*other.x
        return Vector(x, y, z)

# Testcode
# Wird nur ausgeführt, wenn diese Modul zuerst gestartet wird.
if __name__ == '__main__':
    
    a = Vector(2,2,1)
    b = Vector(3,6,-5)
    e1 = Vector(1,0,0)
    e2 = Vector(0,1,0)
    e3 = Vector(0,0,1)
    
    print(a)
    print(a + b)
    print(a - b)
    print(10*b)
    print(a.dot(b))
    print(abs(a))

    w1 = e1.angle(e2)
    w2 = a.angle(a)

    print(f'{w1}°')
    print(f'{w2}°')

    print(e1.cross(e1))
    print(e1.cross(e2))
    print(e1.cross(e3))
