-
Notifications
You must be signed in to change notification settings - Fork 0
Using Operator Overloading for Math
When programming, there are many occasions where one wants to define addition/multiplication and different kinds of operations for a mathematical object. For example, one might define a vector or matrix and some addition/subtraction/multiplication functions to go with it.
One can define a Vec3 in the following way:
Vec3 :: struct {
x: float;
y: float;
z: float;
}
Given the above definition, one can overload the addition operator as follows:
operator + :: (a: Vec3, b: Vec3) -> Vec3 {
c: Vec3;
c.x = a.x + b.x;
c.y = a.y + b.y;
c.z = a.z + b.z;
return c;
}
This is a short example demonstrating vector addition:
a := Vec3.{1, 2, 3};
b := Vec3.{3, 4, 5};
c := a + b;
print("c = %\n", c);
Here is how one can overload the subtraction operator for Vec3.
operator - :: (a: Vec3, b: Vec3) -> Vec3 {
c: Vec3;
c.x = a.x - b.x;
c.y = a.y - b.y;
c.z = a.z - b.z;
return c;
}
This is a short example demonstrating vector subtraction:
a := Vec3.{1, 2, 3};
b := Vec3.{3, 4, 5};
c := a - b;
print("c = %\n", c);
Here is how one can overload the negation operator for Vec3.
operator - :: (a: Vec3) -> Vec3 {
b: Vec3;
b.x = -a.x;
b.y = -a.y;
b.z = -a.z;
return b;
}
This is a short example demonstrating vector negation:
a := Vec3.{1, 2, 3};
b := -a;
print("b = %\n", b);
One can overload the multiplication operator so that Vec3 can support scalar multiplication. We can attach the #symmetric keyword to the function so that the scalar float value is swappable with the Vec3; in this way, we do not need to define two different functions to represent scalar multiplication.
operator * :: (a: Vec3, b: float) -> Vec3 #symmetric {
c: Vec3 = a;
c.x *= b;
c.y *= b;
c.z *= b;
return c;
}
When we compile the example below, the ordering of the Vec3 and scalar float value does not need matter.
a: Vec3 = Vec3.{1, 2, 3};
b: float = 3.0;
c := a * b;
d := b * a; // <- perform commutative scalar multiplication
print("c = %\n", c);
print("d = %\n", d);
Dot Product for Vec3 can be written as follows:
dot :: (a: Vec3, b: Vec3) -> float {
c := (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
return c;
}
This is a short example demonstrating dot product:
a := Vec3.{1, 2, 3};
b := Vec3.{2, 4, 6};
c := dot(a, b);
print("c = %\n", c); // <- answer should be 'c = 28.0'