Part 3 of C++ tutorial – a 3D vector & transform library
Multiplying/dividing vectors by a scalar is probably the next overloaded operator to implement.
Thus we have the respective helper functions:
Vector multiplication(double m) const { return Vector(x*m,y*m,z*m); }
Vector division(double d) const { if (d) return Vector(x/d,y/d,z/d);
else throw runtime_error("Divide by Zero"); }
Note that it is here, in the division function, that we can throw an exception in the event that it is attempted to divide a vector by zero. If you know of a superior way of handling this, post it in a comment.
The corresponding modifying methods are:
void multiply_by(double m) { assign(multiplication(m)); }
void divide_by(double d) { assign(division(d)); }
The respective overloaded operators can be seen in the complete code here:
#include <iostream> // For console output functionality
using namespace std; // Avoids having to use std:: scoping prefix
class Vector // A vector class with addition and subtraction functionality
{
public:
double x,y,z; // Representation
protected:
// Non-modifying functions
Vector addition(const Vector& v) const { return Vector(x+v.x,y+v.y,z+v.z); }
Vector subtraction(const Vector& v) const { return Vector(x-v.x,y-v.y,z-v.z); }
Vector multiplication(double m) const { return Vector(x*m,y*m,z*m); }
Vector division(double d) const { if (d) return Vector(x/d,y/d,z/d); else throw std::runtime_error("Divide by Zero"); }
// Modifying methods
void assign(const Vector& v) { x=v.x; y=v.y; z=v.z; }
void add(const Vector& v) { assign(addition(v)); }
void subtract(const Vector& v) { assign(subtraction(v)); }
void multiply_by(double m) { assign(multiplication(m)); }
void divide_by(double d) { assign(division(d)); }
public:
Vector(double a,double b,double c):x(a),y(b),z(c) { }
Vector& operator+=(const Vector& v) { add(v); return *this; }
Vector& operator-=(const Vector& v) { subtract(v); return *this; }
friend Vector operator+(const Vector& u,const Vector& v) { return Vector(u.addition(v)); }
friend Vector operator-(const Vector& u,const Vector& v) { return Vector(u.subtraction(v)); }
Vector& operator*=(double m) { multiply_by(m); return *this; }
Vector& operator/=(double d) { divide_by(d); return *this; } // Throws div0
friend Vector operator*(const Vector& v,double m) { return Vector(v.multiplication(m)); }
friend Vector operator*(double m,const Vector& v) { return Vector(v.multiplication(m)); }
friend Vector operator/(const Vector& v,double d) { return Vector(v.division(d)); }
friend ostream& operator<<(ostream& os,const Vector& v)
{ return os<<'('<<v.x<<','<<v.y<<','<<v.z<<')'; } // Output, e.g. (1,2,3)
};
int main() // The program
{ Vector v(1,2,3); // A test vector
cout<<"v="<<v<<"\n";
cout<<"3*v="<<3*v<<"\n";
cout<<"v*3="<<v*3<<"\n";
cout<<"v/2="<<v/2<<"\n";
}
Note that because multiplication of a vector by a scalar should be commutative, both operator overloads are provided. However, division of a scalar by a vector is a different kettle of fish to a vector divided by a scalar – the latter being equivalent to multiplication by the reciprocal of the scalar divisor, thus: v/s == v*(1/s).
This program outputs the following:
v=(1,2,3)
3*v=(3,6,9)
v*3=(3,6,9)
v/2=(0.5,1,1.5)
Comments
There are currently no comments on this article.
Comment