class Vector3(object):

This is my implementation of a vector class for Python. The class was developed while I was working with Maya’s cmds module which returns objects as strings and thus needed a way to handle the data. It uses Tuple as its core data because of its fast initialization which saves time when working with millions of vertices that needs to be handled.  As Tuple’s are immutable  you can’t set  the x,y,z values after the object is created which renders the function decorators useless.

# initialize a new vector
vectorOne = vector3(1, 2, 3)

vectorOne.x() # .x() will return the value of x
vectorOne.x(5) # but you cant set individual values.

# List based vector class
vectorTwo = vector3(3, 2, 1)

vectorTwo.x() # retrieve the x value
vectorTwo.x(7) # since lists are mutable you can use the assignment decorator.

The next step for the vector class is to create it to inherit the Tuple class and work with it from there. I will post the list version of the class shortly with some data gathered from using the classes. Here it is:

import math

class vector3(object):
    
    
    def __init__(self, *args):

        """
        The vector object can be initialized by:
        
        list/tuple with 3 indices
        3 separate values
        
        if no values are entered a object with 
        the values of 0,0,0 is created. 
        """
        if len(args) == 1:
            try: 
                self._v = (args[0][0], args[0][1],args[0][2])
            except:
                return "typeError"

        elif len(args) == 3:
            try:
                self._v = (args[0], args[1], args[2])
            except:
                return "typeError"

        elif not args:
            self._v = (0.0, 0.0, 0.0)
        else:
            raise TypeError()


    def __repr__(self):
        return ("Vector3({x}, {y}, {z})").format(x = self._v[0], y = self._v[1], z = self._v[2]) 
    
    def __str__(self):
        return ("({x}, {y}, {z})").format(x = self._v[0], y = self._v[1], z = self._v[2])
    
    # add
    def __add__(self, other):
        """ addition
        checks what object the vector is added with 
        and runs the correct operation.
        """
        if isinstance(other, vector3):
            # adds corresponding indices.
            return tuple(i + j for i, j in zip(self._v, other._v))
            
        elif isinstance(other, int) or isinstance(other, float):
            # adds all original indices with the inputed scalar.
            return tuple(i + other for i in self._v)
        
        elif isinstance(other, list) or isinstance(other, tuple) and len(other) == 3:
            # adds corresponding indices.
            return tuple(i + j for i, j in zip(self._v, other))
        
        else:
            raise TypeError("Vector3 can only be added with vector3, float/int value or list/tuple with 3 values.")
        
    # subtract
    def __sub__(self, other):
        """ Subtraction
        checks what object the vector is added with 
        and runs the correct operation.
        """
        if isinstance(other, vector3):
            # subtracts corresponding indices.
            return tuple(i - j for i, j in zip(self._v, other._v))
            
        elif isinstance(other, int) or isinstance(other, float):
            # subtracts all original indices with the inputed scalar.
            return tuple(i + other for i in self._v)

        elif isinstance(other, list) or isinstance(other, tuple) and len(other) == 3:
            # subtracts corresponding indices.
            return tuple(i + j for i, j in zip(self._v, other))
        
        else:
            raise TypeError("Vector3 can only be subtracted with vector3, float/int value or list/tuple with 3 values.")
        
    #multiply
    def __mul__(self, other):
        """Multiply
        Multiplies a scalar with the indices of the vector.
        """
        if isinstance(other, int) or isinstance(other, float):
            return tuple(i * other for i in self._v)
        else:
            raise ValueError()       
    
    def get(self):
        """return the values of the vector."""
        return self._v[0], self._v[1], self._v[2]
    
    def getString(self):
        """ TEST FUNCTION
        returns a string of the vector
        """
        return "{x:4f} {y:4f} {z:4f} ".format(x = self._v[0], y = self._v[1], z = self._v[2])
    
    ############ X
    @property
    def x(self):        # get x
        """return the x value of the vector"""
        return self._v[0]
    
    """
    @x.setter
    def x(self, value): # set x
        #set the x value of the vector
        self._x = value
    """
    ############ Y
    @property
    def y(self):        # get y
        """return the z value of the vector"""
        return self._v[1]
    """
    @y.setter
    def y(self, value): # set y
        #set the z value of the vector
        self._y = value
    """
    ############ Z
    @property
    def z(self):        # get z
        """return the z value of the vector"""
        return self._v[2]
    """
    @z.setter
    def z(self, value): # set z
        #set the z value of the vector
        self._z = value
    """
    # magnitude
    def mag(self):
        """return the magnitude(length) of a vector."""
        return math.sqrt(sum(tuple(i * i for i in self._v)))
    
    def unit(self):
        """return the unit vector of self"""
        magConst = self.mag()
        return tuple(i / magConst for i in self._v)
    
    # dot product 
    def dotp(self, other):
        """return the dot product of two vectors."""
        return sum(tuple(a * b for a, b in zip(self._v, other._v)))
    
    # dot angle 
    def dota(self, other):
        """return the angle between two vectors."""
        return math.acos(self.dotp(other) / (self.mag() * other.mag()))
    
    # cross product 
    def crossp(self, other):
        """return the cross product of two vectors."""
        v = self._v
        V2 = other._v
        return [v[1] * V2[2] - v[2] * V2[1], v[2] * V2[0] - v[0] * V2[2], v[0] * V2[1] - v[1] * V2[0]]
    
    # cross magnitude
    def crossm(self, other):
        """return the magnitude(lenght) of the cross product of two vectors."""
        return (self.mag() * other.mag()) * math.sin(self.dota(other))

    # area of a triangle defined by two vectors
    def tria(self, other):
        """returns half the area(=triangle) of the parallelogram fromed by two vectors."""
        return self.crossm(other) / 2

Leave a Reply

Your email address will not be published.