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