Vector Scaling

Posted
Comments 0

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)

Author

Comments

There are currently no comments on this article.

Comment

Enter your comment below. Fields marked * are required. You must preview your comment before submitting it.