Implement 3D vector using dunder methods
In this tutorial, we will learn how to implement a 3D vector using Dunder methods in Python.
First, we will look at what dunder methods are.
Next, we look at the basic properties of a 3D vector.
Finally, we will implement a 3D vector class with dunder methods in Python.
Dunder methods in Python
The word ‘dunder’ comes from joining the words ‘double’ and ‘underscore’. Dunder methods are those methods of a class which have names beginning and ending with a double underscore (__). They help us implement certain functionalities to objects of a class that are similar to existing datatypes.
Consider this simple example. Although the ‘+’ (binary addition) operator generally refers to the addition of numeric types, Python allows it to be used for the concatenation of strings. This is done with the help of a dunder method called ‘__add__’.
Click here for a more comprehensive understanding of these methods.
Properties of 3D vectors
We wish to implement the following simple properties of vectors.
- Firstly, we wish to be able to initialise an object with 3 components. We use the ‘__init__’ dunder method to do so.
- Next, we wish to represent the vector as some ‘ai + bj + ck‘. We use the ‘__repr__’ dunder method to do this. This helps us to format the way the vector is printed.
- We define a function to display the magnitude of the vector. This is not a dunder method.
- We implement a method to work with the negative of a vector. We use the ‘__neg__’ dunder method to do so.
- For addition and subtraction of vectors, we use the help of the ‘__add__’ and ‘__sub__’ dunder methods.
- Multiplication in vectors is a little more complex. We overload the ‘*’ operator to have two meanings. We can use it for scalar multiplication as well as the dot product of two vectors. The dunder methods we use in this regard are ‘__mul__’ and ‘__rmul__’.
- Since a vector can also be divided by a scalar, we implement this with the ‘__truediv__’ dunder method. (This is to work with the ‘/’ operator).
- Finally, we implement the cross product of 2 vectors. I decided to use the ‘**’ operator as the symbol to denote cross product. The dunder method for this is ‘__pow__’.
We require a good understanding of operator overloading in Python to implement this program.
Implementation in Python: 3d vector
We implement the concepts so far in the following Python code.
# We define a class vector to handle vector objects class vector: # For initialising the vector def __init__(self, x_comp = None, y_comp = None, z_comp = None): self.x_comp = x_comp self.y_comp = y_comp self.z_comp = z_comp # Representing the vector # Used to print a valid string def __repr__ (self): return '{}i {} {}j {} {}k'.format(self.x_comp, '+' if self.y_comp >= 0 else '-', abs(self.y_comp), '+' if self.z_comp >= 0 else '-', abs(self.z_comp)) # Magnitude of the vector def mag(self): return ((self.x_comp ** 2 + self.y_comp ** 2 + self.z_comp ** 2) ** 0.5) # Negative of a vector def __neg__(self): return (vector(-self.x_comp, -self.y_comp, -self.z_comp)) # Addition of 2 vectors def __add__(first, second): return (vector(first.x_comp + second.x_comp, first.y_comp + second.y_comp, first.z_comp + second.z_comp)) # Subtraction of 2 vectors def __sub__(first, second): return (vector(first.x_comp - second.x_comp, first.y_comp - second.y_comp, first.z_comp - second.z_comp)) # We use '*' for both scalar multiplication # as well as dot product def __mul__(first, second): if (isinstance(second, (int, float))): return (vector(second * first.x_comp, second * first.y_comp, second * first.z_comp)) else: return (first.x_comp * second.x_comp + first.y_comp * second.y_comp + first.z_comp * second.z_comp) def __rmul__(second, first): return (vector(first * second.x_comp, first * second.y_comp, first * second.z_comp)) # Scalar division def __truediv__(first, second): return vector(first.x_comp / second, first.y_comp / second, first.z_comp / second) # We use '**' for cross product def __pow__(first, second): return vector(first.y_comp * second.z_comp - first.z_comp * second.y_comp, first.z_comp * second.x_comp - first.x_comp * second.z_comp, first.x_comp * second.y_comp - first.y_comp * second.x_comp) if __name__ == "__main__": # Creating a vector and printing it v = vector(-2, 3, -7) print(v) # Print magnitude print(v.mag()) # Negative of the vector print(-v) # Scaling the vector print(v * 4) print(v / 2) # The following line if uncommented, produces an error # print(2 / v) # Addition of two vectors print(v + vector(1, 23, 2)) # Subtraction of two vectors print(v - vector(7, 3, 11)) # Dot product of two vectors print(v * vector(1, 23, 2)) # Cross Product aka Vector Product of two vectors print(v ** vector(5, 2, 4))
Output
Leave a Reply