Will Perone

2D Vector C++ Class

My template handles most cases with generic 2d vectors; specific behavior is defined for the floating point and integer types of vectors. You can see the latest version of the entire math package at GitHub or visit my downloadable code page.
/****************************************
 * By Will Perone
 * Original: 9-16-2002  
 * Revised: 19-11-2003
 *          18-12-2003
 *          06-06-2004
 ****************************************/

#pragma once 

#include <math.h> 


template <typename T>
struct vector2
{
	T x, y;
	
	//! trivial ctor
	vector2<T>() {}

	//! setting ctor
	vector2<T>(const T x0, const T y0): x(x0), y(y0) {}

	//! array indexing
	T &operator [](unsigned int i) 
	{   return *(&x+i);   }

	//! array indexing
	const T &operator [](unsigned int i) const 
	{	return *(&x+i);   }  

	//! function call operator
	void operator ()(const T x0, const T y0) 
	{	x= x0; y= y0;	}

	//! test for equality
	bool operator==(const vector2<T> &v)
	{	return (x==v.x && y==v.y);	}

	//! test for inequality
	bool operator!=(const vector2<T> &v)
	{	return (x!=v.x || y!=v.y);	}
	
	//! set to value
	const vector2<T> &operator =(const vector2<T> &v)
	{	
		x= v.x; y= v.y;			
		return *this;
	}
	
	//! negation
	const vector2<T> operator -(void) const
	{	return vector2<T>(-x, -y);	}

	//! addition
	const vector2<T> operator +(const vector2<T> &v) const
	{	return vector2<T>(x+v.x, y+v.y);	}
	
	//! subtraction
	const vector2<T> operator -(const vector2<T> &v) const
	{   return vector2<T>(x-v.x, y-v.y);	}
		
	//! uniform scaling
	const vector2<T> operator *(const T num) const
	{
		vector2<T> temp(*this);			
		return temp*=num;
	}

	//! uniform scaling
	const vector2<T> operator /(const T num) const
	{
		vector2<T> temp(*this);			
		return temp/=num;
	}		

	//! addition
	const vector2<T> &operator +=(const vector2<T> &v)
	{
		x+=v.x;	y+=v.y;						
		return *this;
	}

	//! subtraction
	const vector2<T> &operator -=(const vector2<T> &v) 
	{ 
		x-=v.x;	y-=v.y;						
		return *this;	
	}

	//! uniform scaling
	const vector2<T> &operator *=(const T num)
	{
		x*=num;	y*=num;										
		return *this;
	}
	
	//! uniform scaling
	const vector2<T> &operator /=(const T num)
	{
		x/=num;	y/=num;										
		return *this;
	}

	//! dot product
	T operator *(const vector2<T> &v) const
	{	return x*v.x + y*v.y;	}	
};


// macro to make creating the ctors for derived vectors easier
#define VECTOR2_CTORS(name, type)   \ 
	/* trivial ctor */				\
	name() {}						\
	/* down casting ctor */			\
	name(const vector2<type> &v): vector2<type>(v.x, v.y) {}	\
	/* make x,y combination into a vector */					\
	name(type x0, type y0): vector2<type>(x0, y0) {}
	    


struct vector2i: public vector2<int>
{
	VECTOR2_CTORS(vector2i, int)
};


struct vector2ui: public vector2<unsigned int>
{
	VECTOR2_CTORS(vector2ui, unsigned int)
};


struct vector2f: public vector2<float>
{
	VECTOR2_CTORS(vector2f, float)

	//! gets the length of this vector squared
	float length_squared() const
	{	return (float)(*this * *this);   }

	//! gets the length of this vector
	float length() const
	{	return (float)sqrt(*this * *this);   }

	//! normalizes this vector
	void normalize()
	{	*this/=length();	}

	//! returns the normalized vector
	vector2f normalized() const
	{   return  *this/length();  }

	//! reflects this vector about n
	void reflect(const vector2f &n)
	{
		vector2f orig(*this);
		project(n);
		*this= *this*2 - orig;
	}

	//! projects this vector onto v
	void project(const vector2f &v)
	{	*this= v * (*this * v)/(v*v);	}

	//! returns this vector projected onto v
	vector2f projected(const vector2f &v)
	{   return v * (*this * v)/(v*v);	}

	//! computes the angle between 2 arbitrary vectors
	static inline float angle(const vector2f &v1, const vector2f &v2)
	{   return acosf((v1*v2) / (v1.length()*v2.length()));  }

	//! computes the angle between 2 normalized arbitrary vectors
	static inline float angle_normalized(const vector2f &v1, const vector2f &v2)
	{   return acosf(v1*v2);  }
};
11 Comments
si 10 2
Thanks
Rain 1 0
Thanks, :)
Brett 0 0
Thank you very much, sir! :)
Ryan 0 0
Thanks, this is very useful !
GergN 0 0
Can I use this without license in a comercial product?
Will 0 0
sure, this code is public domain
Idalee 2011/11/21 Contact Me0 0
That's 2 celver by half and 2x2 clever 4 me. Thanks!
prospective user 2012/02/030 0
This part is throwing a bunch of errors, every time name or type is used before a colon there are errors for them.
#define VECTOR2_CTORS(name, type) \
/* trivial ctor */ \
name() {} \
/* down casting ctor */ \
name(const vector2<type> &v): vector2<type>(v.x, v.y) {} \
/* make x,y combination into a vector */ \
name(type x0, type y0): vector2<type>(x0, y0) {}
prospective user 2012/02/030 19
^^ any thoughts on how to fix that would be helpful ...
Will 2012/02/05 Contact Me1 1
Make sure your compiler can do multiple parameter macros and that there is no whitespace after any of the \ in the macro. If you just paste that CTOR code into the class does it work or does that also fail?
Timbly 2014/05/23 Contact Me0 0
I'm getting a lot of 'returning reference to temporary [-Wreturn-local-addr]' warnings. Can anyone explain this?

<- for private contact