This class should have been posted long ago.  So, seeing how popular my C++ Vector2 class page has been, I've decided to finally post this for your needs.  This version is similar to the "improvements" on the Vector2 class, supposedly helping encapsulation; frankly, that's up for you to decide.

 

Remember, you can hover over the source area and click the "<>" looking image (top right) to pop the source code into a new window to more easily view and copy the code.

Vector3.h

/*  __      __   ___     _____    ____
 *  \ \    / /  / _ \   |  __ \  |    |
 *   \ \/\/ /  / / \ \  | | / /  |  __|
 *    \_/\_/  /_/   \_\ |_| \_\  |_|
 *      Take it to the next Level
 *
 *  Copyright (c) 2009 Brian Ernst.
 */

#ifndef w_Vector3
#define w_Vector3

#include <cmath>

namespace _Warp
{
	typedef float	Scalar;
	typedef int		Bool;

	class Vector3
	{
	public:
		Scalar X;
		Scalar Y;
		Scalar Z;

		Vector3();
		Vector3(Scalar x, Scalar y, Scalar z);

		Vector3		operator+(const Vector3&amp; vector) const;
		Vector3		operator-(const Vector3&amp; vector) const;
		Vector3		operator-() const;
		Vector3		operator*(Scalar num) const;
		Vector3		operator/(Scalar num) const;

		Vector3&amp;	operator+=(const Vector3&amp; vector);
		Vector3&amp;	operator-=(const Vector3&amp; vector);
		Vector3&amp;	operator*=(Scalar num);
		Vector3&amp;	operator/=(Scalar num);

		Bool		operator==(const Vector3&amp; vector) const;
		Bool		operator!=(const Vector3&amp; vector) const;

		static const Vector3 Zero;
		static const Scalar	Epsilon;
	};

	inline Bool Vector3::operator==(const Vector3&amp; vector) const
	{
		return X == vector.X &amp;&amp; Y == vector.Y &amp;&amp; Z == vector.Z;
	}

	inline Bool Vector3::operator!=(const Vector3&amp; vector) const
	{
		return X != vector.X || Y != vector.Y || Z != vector.Z;
	}

	inline Vector3 Vector3::operator+(const Vector3&amp; vector) const
	{
		return Vector3(X + vector.X, Y + vector.Y, Z + vector.Z);
	}

	inline Vector3 Vector3::operator-(const Vector3&amp; vector) const
	{
		return Vector3(X - vector.X, Y - vector.Y, Z - vector.Z);
	}

	inline Vector3 Vector3::operator-() const
	{
		return Vector3(-X,-Y,-Z);
	}

	inline Vector3 Vector3::operator*(Scalar num) const
	{
		return Vector3(X * num, Y * num, Z * num);
	}

	inline Vector3 Vector3::operator/(Scalar num) const
	{
		return Vector3(X / num, Y / num, Z / num);
	}
}
#endif

Vector3.cpp:

#include "Vector3.h"

#include <limits>

namespace _Warp
{
	const Vector3 Vector3::Zero = Vector3(0,0,0);
	const Scalar Vector3::Epsilon = std::numeric_limits::epsilon();

	Vector3::Vector3()
	{
	}

	Vector3::Vector3(Scalar x, Scalar y, Scalar z)
		: X( x )
		, Y( y )
		, Z( z )
	{
	}

	Vector3& Vector3::operator+=(const Vector3& vector)
	{
		X += vector.X;
		Y += vector.Y;
		Z += vector.Z;
		return *this;
	}

	Vector3& Vector3::operator-=(const Vector3& vector)
	{
		X -= vector.X;
		Y -= vector.Y;
		Z -= vector.Z;
		return *this;
	}

	Vector3& Vector3::operator*=(Scalar num)
	{
		X *= num;
		Y *= num;
		Z *= num;
		return *this;
	}

	Vector3& Vector3::operator/=(Scalar num)
	{
		this-&gt;X /= num;
		this-&gt;Y /= num;
		this-&gt;Z /= num;
		return *this;
	}
}

Vector3Util.h

/*  __      __   ___     _____    ____
 *  \ \    / /  / _ \   |  __ \  |    |
 *   \ \/\/ /  / / \ \  | | / /  |  __|
 *    \_/\_/  /_/   \_\ |_| \_\  |_|
 *      Take it to the next Level
 *
 *  Copyright (c) 2009 Brian Ernst.
 */

#ifndef w_Vector3Util
#define w_Vector3Util

#include "Vector3.h"

// These two files are not detailed out in this blog post.
#include "Quaternion.h"
#include "TMatrixUtil.h"

namespace _Warp
{
	Scalar len(const Vector3& vect);
	Scalar len2(const Vector3& vect);

	void Clamp(Vector3& vect,Scalar length);
	void Normalize(Vector3& vect);
	void Normalize_s(Vector3& vect);
	void SetLength(Vector3& vect, Scalar length);
	void SetLength_s(Vector3& vect, Scalar length);

	Scalar	Dot(const Vector3& vec1, const Vector3& vec2);
	Scalar	GetAngle(Vector3 vec1, Vector3 vec2);

	Vector3	ToNormalized(const Vector3& vect);
	Vector3	ToNormalized_s(const Vector3& vect);
	Vector3	ToPolar(Scalar x, Scalar y, Scalar z);
	Vector3	ToCartesian(Scalar radius, Scalar angle, Scalar z);
	Vector3	Cross(const Vector3& vec1, const Vector3& vec2);
	Vector3	Rotate(const Vector3& vec1, Scalar angle, const Vector3& axis);

	Vector3 ToEuler(Vector3 axis, Scalar angle);

	inline Scalar len(const Vector3& vect)
	{
		return sqrt(vect.X * vect.X + vect.Y * vect.Y + vect.Z * vect.Z);
	}

	inline Scalar len2(const Vector3& vect)
	{
		return vect.X * vect.X + vect.Y * vect.Y + vect.Z * vect.Z;
	}

	inline void Normalize(Vector3& vect)
	{
		vect /= len(vect);
	}

	inline void SetLength(Vector3& vect, Scalar length)
	{
		vect *= length / len(vect);
	}

	inline Scalar	Dot(const Vector3& vec1, const Vector3& vec2)
	{
		return vec1.X * vec2.X + vec1.Y * vec2.Y + vec1.Z * vec2.Z;
	}

	inline Vector3 ToNormalized(const Vector3& vect)
	{
		return vect / len(vect);
	}

	// This uses a Quaternion combined with the Matrix Utility, neither of which are detailed out in this post.
	inline Vector3	Rotate(const Vector3& vec1, Scalar angle, const Vector3&amp; axis)
	{
		return TransformCoord(Quaternion::FromAxis(axis.X,axis.Y,axis.Z,angle).Get_RotationMatrix(),vec1);
	}

	inline Vector3	ToPolar(Scalar x, Scalar y, Scalar z)
	{
		return Vector3(
			atan2(y,x),
			sqrt(x * x + y * y),
			z);
	}

	inline Vector3	ToCartesian(Scalar radius, Scalar angle, Scalar z)
	{
		return Vector3(
			radius * cos(angle),
			radius * sin(angle),
			z);
	}

	inline Vector3	Cross(const Vector3& vec1, const Vector3& vec2)
	{
		return Vector3(
			vec1.Y * vec2.Z - vec1.Z * vec2.Y,
			vec1.Z * vec2.X - vec1.X * vec2.Z,
			vec1.X * vec2.Y - vec1.Y * vec2.X);
	}
}

#endif

Vector3Util.cpp

#include "Vector3Util.h"

#include "../Constants.h"

namespace _Warp
{
	void Clamp(Vector3& vect,Scalar length)
	{
		Scalar vecLength = len2(vect);

		if(vecLength &lt;= length * length)
		{
			return;
		}

		vect *= length / sqrt(vecLength);
	}

	void Normalize_s(Vector3& vect)
	{
		Scalar vecLength = len2(vect);

		if(vecLength == 0)
		{
			return;
		}

		vect /= sqrt(vecLength);
	}

	void SetLength_s(Vector3& vect, Scalar length)
	{
		Scalar vecLength = len2(vect);

		if(vecLength == 0)
		{
			return;
		}

		vect *= length / sqrt(vecLength);
	}

	inline Scalar	GetAngle(Vector3 vec1, Vector3 vec2)
	{
		if(vec1 == vec2)
		{
			return 0.0f;
		}

		Normalize_s(vec1);
		Normalize_s(vec2);

		Scalar dot = Dot(vec1, vec2) / (len(vec1) * len(vec2));

		dot = dot > 1.0f ? 1.0f : ( dot < -1.0f ? -1.0f : dot );

		return std::acos(dot);
	}

	Vector3 ToNormalized_s(const Vector3& vect)
	{
		Scalar vecLength = len2(vect);

		if(vecLength == 0)
		{
			return vect;
		}

		vecLength = sqrt(vecLength);

		return Vector3(vect.X / vecLength, vect.Y / vecLength, vect.Z / vecLength);
	}

	// Thanks to Martin Baker for this solution
	// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToEuler/index.htm
	Vector3 ToEuler(Vector3 axis, Scalar angle)
	{
		Vector3 out = Vector3();

		Scalar s = sin(angle);
		Scalar c = cos(angle);
		Scalar t = (Scalar)1.0 - c;

		if ((axis.X * axis.Y * t + axis.Z * s) > (Scalar)0.998)// north pole singularity detected
		{
			out.Y = 2 * atan2(axis.X * sin(angle/2), cos(angle/2));
			out.Z = static_cast<Scalar>(W_PI_2);
			out.X = 0;
			return out;
		}
		if ((axis.X * axis.Y * t + axis.Z * s) < (Scalar)-0.998)// south pole singularity detected
		{
			out.Y = (Scalar)-2.0 * atan2(axis.X * sin(angle / (Scalar)2.0), cos(angle / (Scalar)2.0));
			out.Z = -static_cast<Scalar>(W_PI_2);;
			out.X = 0;
			return out;
		}
		out.Y = atan2(axis.Y * s - axis.X * axis.Z * t , 1 - (axis.Y * axis.Y + axis.Z * axis.Z ) * t);
		out.Z = asin(axis.X * axis.Y * t + axis.Z * s) ;
		out.X = atan2(axis.X * s - axis.Y * axis.Z * t , 1 - (axis.X * axis.X + axis.Z * axis.Z) * t);
		return out;
	}
}

You'll notice in the Vector3Util I have some functions ending with "_s", like "Noramlize_s"; this is a notation I'm trying to mean, in this case, a safe normalize function call (won't result in a divide by zero error).  So, if you know the vector you're using can't possibly be zero, use the standard Normalize function, if not, then feel free to use Normalize_s.  Please let me know if you have a comment on the notation!

Anyway, this Vector3 class and utility are code I use in my personal game development, and in other school projects that I may have, and have used it and my personal math libs in a ray tracer.  Concerning the util, I'm still tweaking it, making decisions on how to wrap it in a namespace (like it's own _Math namespace, which was taken out for this post), or perhaps on whether I feel I really need a separate util instead of having them as member functions, which would be more convenient with intellisense at hand. If you're wondering what I'm talking about, check out this article at Dr Dobbs on encapsulation.  I personally have to give it another read and determine if I agree with it or not and really want to stick with that methodology.

 

Please leave your thoughts and suggestions!
[I'll be uploading the upgraded version of this Vector3 class sometime soon, I realize there are parts of this version that may be a little rough/unfinished, and after that I'll include the source files for you to download]

This is an improved Vector2 class I'm working on with suggestions from Leander Hasting, though I haven't touched upon all of them yet.  Beyond that, some of the critiques seem subjective to a point, and other professionals he pointed me to, make the same argument; and that is the argument of the use 0f non-member functions.  With intellisense working, I find using member functions to be the easiest way of doing things, as I think it is easier for other people to work with; as someone who's trying to write an engine, I understand the importance of including extra functions in a separate header file, though I think that can get messy.  So, with what is proposed you could do VectorUtil::len(vector), though having the VectorUtilthere is ugly, though without it there, how do you know that function even exists or where it's coming from?  So for starters, it's more useful to split the vector up like this, because everything doesn't need access to these functions, and it helps build times.  Though, in the end, when this engine is done, all of the information is most likely going to be included anyway;  lets say I want to add scripting support with my own version of intellisense, I want to make it as easy as possible for someone not used to my engine to be able to interactively see what they can do with a Vector by simply using "vector." and everything they have available to them pop up.  So, because the functions are accessing public members, they have no need to be member functions; so while some may claim using member functions breaks encapsulation, I think it makes it easier to open up a class to the user and what it can do.  Though it's interesting that intellisense in Visual Studio also shows private and protected functions you don't have access to...

Anyway, what I would like to do with my code is make it as easy as possible for anyone to use, I'm not worried that much about technicalities and hardcore programmers squirming over things I don't care about.  Though that makes me wonder, should I care about that, and perhaps just take it with a grain of salt?

Anyway, here's my Vector2 class in it's improved glory.

Vector2.h:

/*  __      __   ___     _____    ____
 *  \ \    / /  / _ \   |  __ \  |    |
 *   \ \/\/ /  / / \ \  | | / /  |  __|
 *    \_/\_/  /_/   \_\ |_| \_\  |_|
 *      Take it to the next Level
 *
 *  Copyright (c) 2009 Brian Ernst.
 */
#ifndef w_Vector2
#define w_Vector2

#ifndef FALSE
#define FALSE 0
#endif

#ifndef TRUE
#define TRUE 1
#endif

namespace _Warp
{
	typedef float Scalar;
	typedef int Bool;

	class Vector2
	{
	public:
		Scalar X;
		Scalar Y;

		Vector2();
		Vector2(Scalar x, Scalar y);

		Vector2& operator+=(const Vector2& pVector);
		Vector2& operator-=(const Vector2& pVector);
		Vector2& operator*=(Scalar num);
		Vector2& operator/=(Scalar num);

		Bool operator!=(const Vector2& vect) const;
		Bool operator==(const Vector2&; vect) const;

		friend Vector2 operator-(Vector2& vect);
		friend Vector2 operator+(const Vector2& vect1,const Vector2& vect2);
		friend Vector2 operator-(const Vector2& vect1,const Vector2& vect2);
		friend Vector2 operator*(const Vector2& vect1, Scalar value);
		friend Vector2 operator/(const Vector2& vect1, Scalar value);
		friend Vector2 operator*(const Vector2& vect1,const Vector2& vect2);
		friend Vector2 operator/(const Vector2& vect1,const Vector2& vect2);
	};

	inline Vector2::Vector2()
	{
	}

	inline Vector2::Vector2(Scalar x,Scalar y)
		: X( x )
		, Y( y )
	{
	}

	inline Bool Vector2::operator!=(const Vector2& vector) const
	{
		return X != vector.X || Y != vector.Y;
	}

	inline Bool Vector2::operator==(const Vector2& vect) const
	{
		return (*this != vect) == FALSE;
	}

	inline Vector2& Vector2::operator+=(const Vector2& pVector)
	{
		X += pVector.X;
		Y += pVector.Y;
		return *this;
	}

	inline Vector2& Vector2::operator-=(const Vector2& pVector)
	{
		X -= pVector.X;
		Y -= pVector.Y;
		return *this;
	}

	inline Vector2& Vector2::operator*=(Scalar num)
	{
		X *= num;
		Y *= num;
		return *this;
	}

	inline Vector2& Vector2::operator/=(Scalar num)
	{
		X /= num;
		Y /= num;
		return *this;
	}

	inline Vector2 operator+(const Vector2& vect1,const Vector2& vect2)
	{
		return Vector2(vect1.X + vect2.X,vect1.Y + vect2.Y);
	}

	inline Vector2 operator-(const Vector2& vect1,const Vector2& vect2)
	{
		return Vector2(vect1.X - vect2.X,vect1.Y - vect2.Y);
	}

	inline Vector2 operator-(Vector2& vect)
	{
		return vect * -1;
	}

	inline Vector2 operator*(const Vector2& vect1, Scalar value)
	{
		return Vector2(vect1.X * value,vect1.Y * value);
	}

	inline Vector2 operator/(const Vector2& vect1, Scalar value)
	{
		return Vector2(vect1.X / value,vect1.Y / value);
	}

	inline Vector2 operator*(const Vector2& vect1,const Vector2& vect2)
	{
		return Vector2(vect1.X * vect2.X,vect1.Y * vect2.Y);
	}

	inline Vector2 operator/(const Vector2& vect1,const Vector2& vect2)
	{
		return Vector2(vect1.X / vect2.X,vect1.Y / vect2.Y);
	}
}

#endif

VectorUtil.h

/*  __      __   ___     _____    ____
 *  \ \    / /  / _ \   |  __ \  |    |
 *   \ \/\/ /  / / \ \  | | / /  |  __|
 *    \_/\_/  /_/   \_\ |_| \_\  |_|
 *      Take it to the next Level
 *
 *  Copyright (c) 2009 Brian Ernst.
 */

#ifndef w_VectorUtil
#define w_VectorUtil

#include <cmath>

using std::sin;
using std::cos;
using std::sqrt;
using std::atan2;

#include "Vector2.h"

namespace _Warp
{
	class Vector2Util
	{
		static Scalar 	len(const Vector2& vect);
		static Scalar 	len2(const Vector2& vect);

		static Vector2& invert(Vector2& vect);
		static Vector2& normalize(Vector2& vect);
		static Vector2& clamp(Vector2& vect, Scalar value);
		static Vector2& setLength(Vector2& vect, Scalar value);

		static Vector2	polar		(Scalar x, Scalar y);
		static Vector2 	cartesian	(Scalar radius,	Scalar angle);
		static Scalar 	dot			(const Vector2& pVec1, const Vector2& pVec2);
		static Vector2 	rotate		(const Vector2& pVec, Scalar angle);
	};

	inline Scalar len(const Vector2& vect)
	{
		return sqrt(vect.X * vect.X + vect.Y * vect.Y);
	}

	inline Scalar len2(const Vector2& vect)
	{
		return vect.X * vect.X + vect.Y * vect.Y;
	}

	inline Vector2& invert(Vector2& vect)
	{
		return vect *= -1;
	}

	inline Vector2& normalize(Vector2& vect)
	{
		if(vect.X == 0 &amp;&amp; vect.Y == 0)
		{
			return vect;
		}

		Scalar length = len(vect);

		vect.X /= length;
		vect.Y /= length;
		return vect;
	}

	inline Vector2& clamp(Vector2& vect,Scalar value)
	{
		Scalar length = len2(vect);
		if(length &lt;= value * value)
		{
			return vect;
		}

		length = sqrt(length);

		vect.X *= value / length;
		vect.Y *= value / length;

		return vect;
	}

	inline Vector2& setLength(Vector2& vect, Scalar value)
	{
		if(vect.X == 0 &amp;&amp; vect.Y == 0)
		{
			return vect;
		}

		Scalar length = len(vect);

		vect.X *= value / length;
		vect.Y *= value / length;

		return vect;
	}

	inline Vector2 cartesian(Scalar radius,Scalar angle)
	{
		return Vector2(radius * cos(angle),radius * sin(angle));
	}

	inline Vector2 polar(Scalar x,Scalar y)
	{
		return Vector2(atan2(y,x),sqrt(x * x + y * y));
	}

	inline Scalar dot(const Vector2& pVec1,const Vector2& pVec2)
	{
		return pVec1.X * pVec2.X + pVec1.Y * pVec2.Y;
	}

	inline Vector2 rotate(const Vector2& pVec,Scalar angle)
	{
		Scalar cosResult = cos(angle);
		Scalar sinResult = sin(angle);

		//Essentially, apply a 2x2 rotation matrix to the vector
		Scalar newX = pVec.X * cosResult - pVec.Y * sinResult;
		Scalar newY = pVec.X * sinResult + pVec.Y * cosResult;

		return Vector2(newX,newY);
	}
}

#endif

Notes:

With this class, you can't do this:

Vector2 vect = 2;

This was possible with my old Vector2 class, and frankly should be an error.  If you are going to initialize the vars of a Vector2 at a later time, you can do this:

Vector2 vect = Vector2(Vector2::Uninitialized())

The reason for this is, doing this:

Vector2 vect = Vector2();

...creates a Vector2(0,0) by default. I could setup a default constructor and not use default values, however that could result in bugs from coders not properly initializing Vector2 objects. So, it is this reason the Uninitialized class is being used.

Feel free to use this improved Vector2 class, and if the c-style functions in VectorUtil bug you, feel free to make them member functions again in Vector2.

Download the Vector2 improved here: Vector2 class files.

[Update: As of 5/11/10 I noticed a typo, which I fixed, however I need to update the source files. I've also realized there are also a couple other utility functions I could "add", so will do so sometime soon; I got the idea from looking at another blog, however I realized he just named the functions to something easily understandable. For example, the dot and cross product; their names don't say anything about what the function really does, what the data represents. So, it seems useful to package up those functions to make it easier for programmers using this utility, and of course leaving the original functions in-tact (perhaps?) so other programmers looking for them won't be confused when they think they can't find them. So, more cool things to come! :) ]

[Edit: Checkout the improved Vector2 class here: improved Vector2 blog post.]

Hey, it's been a while since I've posted anything, and I've been wanting to share this Vector2 class that I have written. It started being developed less than a year ago, and has undergone some minor changes since then to try to improve efficiency and add functionality. I haven't touched it in a while since then, as I'm now working on a 3D game engine, but here is what I've got.

/*  __      __   ___     _____    ____
 *  \ \    / /  / _ \   |  __ \  |    |
 *   \ \/\/ /  / / \ \  | | / /  |  __|
 *    \_/\_/  /_/   \_\ |_| \_\  |_|
 *      Take it to the next Level
 *
 *  Copyright (c) 2009 Brian Ernst.
 */

#ifndef w_Vector2
#define w_Vector2

#include <math.h>

namespace _Warp
{
	typedef float Scalar;
	typedef int Bool;

	class Vector2
	{
	public:
		Scalar X;
		Scalar Y;

		Vector2(const Scalar x = 0,const Scalar y = 0);
		~Vector2();

		Vector2 operator+(const Vector2& pVector) const;
		Vector2 operator-(const Vector2& pVector) const;
		Vector2 operator*(const Scalar& num) const;
		Vector2 operator/(const Scalar& num) const;
		Vector2 operator*(const Vector2& vector) const;
		Vector2 operator/(const Vector2& vector) const;
		void operator+=(const Vector2& pVector);
		void operator-=(const Vector2& pVector);
		void operator*=(const Scalar& num);
		void operator/=(const Scalar& num);
		void operator=(const Vector2& pVector);
		Bool operator==(const Vector2& vector) const;
		Bool operator!=(const Vector2& vector) const;

		void Clamp(const Scalar& value);
		void Normalize(const Scalar& value = 1.0f);
		void Invert();

		Scalar Length() const;

		Vector2 Copy() const;

		static Vector2 Cartesian(const Scalar& x,const Scalar& y);
		static Vector2 Polar(const Scalar& radius,const Scalar& angle);
		static Scalar Dot(const Vector2& pVec1,const Vector2& pVec2);
		static Vector2 Rotate(const Vector2& pVec,const Scalar& angle);
		static const Vector2 Zero;
	};

	inline Vector2 Vector2::Copy() const
	{
		return Vector2(X,Y);
	}

	inline Bool Vector2::operator==(const Vector2& vector) const
	{
		return X == vector.X && Y == vector.Y;
	}

	inline Bool Vector2::operator!=(const Vector2& vector) const
	{
		return X != vector.X || Y != vector.Y;
	}

	inline Vector2 Vector2::operator+(const Vector2& pVector) const
	{
		return Vector2(X + pVector.X,Y + pVector.Y);
	}

	inline Vector2 Vector2::operator-(const Vector2& pVector) const
	{
		return Vector2(X - pVector.X,Y - pVector.Y);
	}

	inline Vector2 Vector2::operator*(const Scalar& num) const
	{
		return Vector2(X * num,Y * num);
	}

	inline Vector2 Vector2::operator/(const Scalar& num) const
	{
		return Vector2(X / num,Y / num);
	}

	inline Vector2 Vector2::operator*(const Vector2& vector) const
	{
		return Vector2(X * vector.X,Y * vector.Y);
	}

	inline Vector2 Vector2::operator/(const Vector2& vector) const
	{
		return Vector2(X / vector.X,Y / vector.Y);
	}
}

#endif

And yes, I realize I need to comment this class, and I will. I might include the source files, but you can just as easily click on the "Source" button on the top right corner of the code box. And here's the cpp definitions file for the Vector2 functions:

#include "Vector2.h"

namespace _Warp
{
	const Vector2 Vector2::Zero = Vector2();

	Vector2::Vector2(const Scalar x,const Scalar y)
	{
		X = x;
		Y = y;
	}

	Vector2::~Vector2()
	{
	}

	void Vector2::operator+=(const Vector2& pVector)
	{
		X += pVector.X;
		Y += pVector.Y;
	}

	void Vector2::operator-=(const Vector2& pVector)
	{
		X -= pVector.X;
		Y -= pVector.Y;
	}

	void Vector2::operator*=(const Scalar& num)
	{
		X *= num;
		Y *= num;
	}

	void Vector2::operator/=(const Scalar& num)
	{
		X /= num;
		Y /= num;
	}

	void Vector2::operator=(const Vector2& pVector)
	{
		X = pVector.X;
		Y = pVector.Y;
	}

	Scalar Vector2::Length() const
	{
		return sqrt(pow(X,2.0f) + pow(Y,2.0f));
	}

	void Vector2::Clamp(const Scalar& value)
	{
		if(Length() <= value)
			return;
		Normalize();
		*this *= value;
	}

	void Vector2::Normalize(const Scalar& value)
	{
		Scalar vecLength = Length();

		if(vecLength == 0)
			return;

		X = X/vecLength * value;
		Y = Y/vecLength * value;
	}

	void Vector2::Invert()
	{
		X *= -1;
		Y *= -1;
	}

	Vector2 Vector2::Polar(const Scalar& x,const Scalar& y)
	{
		Vector2 pVector = Vector2();
		pVector.X = atan2(y,x);
		pVector.Y = sqrt(x * x + y * y);
		return pVector;
	}

	Vector2 Vector2::Cartesian(const Scalar& radius,const Scalar& angle)
	{
		Vector2 pVector = Vector2();
		pVector.X = radius * cos(angle);
		pVector.Y = radius * sin(angle);
		return pVector;
	}

	Scalar Vector2::Dot(const Vector2& pVec1,const Vector2& pVec2)
	{
		return pVec1.X * pVec2.X + pVec1.Y * pVec2.Y;
	}

	Vector2 Vector2::Rotate(const Vector2& pVec,const Scalar& angle)
	{
		Scalar cosResult = cos(angle);
		Scalar sinResult = sin(angle);

		//Essentially, apply a 2x2 rotation matrix to the vector
		Scalar newX = pVec.X * cosResult - pVec.Y * sinResult;
		Scalar newY = pVec.X * sinResult + pVec.Y * cosResult;

		return Vector2(newX,newY);
	}
}

It's pretty simple, but quite useful and powerful I think. I put it up here for other people to use for quick reference; let me know what you think or just drop me a line telling me you're using it for something, that'd make my day. (:

So here's a zip file you can download: Vector2

Archive