Vec2

See: vec2.h   vec2.cpp

vec2.h


/*\file vec2.h
*/
/*!    Vec2 is a two dimensional point
*/

#pragma once
#include <iostream>
#include <assert.h>
#include <math.h>


//! defines two-dimensional point
class Vec2 {
public:	
	Vec2() { Vec2(0.0,0.0); } //!< default no-argument constructor
	~Vec2() {} //!< destructor
	//! constructs Vec2 from (x,y) coordinates
	Vec2(double x, double y) { body[0] = x; body[1] = y; }
	//! constucts unit vector at angle theta (in degrees) from x-axis
	Vec2(double theta);
	//! returns length of associated array
	int length() const { return 2; }
	//! return pointer to first element
	double * vptr() { return body; }
	//! subscript operator (non-const object)
	double &operator[](int k)  { return body[k]; }
	//! subscript operator (const object)
	const double &operator[](int k) const { return body[k]; }
	Vec2 &operator+=(const Vec2&b);
	//! set Vec2 to new value
	Vec2 &set(double x, double y) { body[0]=x; body[1]=y; return *this; }
	Vec2 &scale(double scl) { body[0]*=scl; body[1] *=scl; return *this; }
	Vec2 &rotate(double theta);
	//! translate Vec2
	Vec2 &translate(double x, double y) { body[0] += x; body[1] += y; return *this; }
	Vec2 &translate(Vec2 &v) { body[0] += v[0]; body[1] += v[1]; return *this; }
	friend void sum(Vec2 &result,const Vec2 &a,const Vec2 &b);
	friend void diff(Vec2 &result, const Vec2 &a, const Vec2 &b);
	double getSize() const;
	Vec2 &setSize(double sz);
	//operator overloads
	friend Vec2 operator+(const Vec2&a, const Vec2&b);
	friend Vec2 operator-(const Vec2&a, const Vec2&b);
	friend Vec2 operator-(const Vec2&a);
	friend Vec2 operator+(const Vec2&a, double b);
	friend Vec2 operator-(const Vec2&a, double b);
	friend Vec2 operator*(const Vec2&a, double b);
	friend Vec2 operator/(const Vec2&a, double b);
	
	//! iostream output
	friend std::ostream& operator << (std::ostream& s, const Vec2& v);
	//! iostream input
	friend std::istream& operator >> (std::istream& s, Vec2& v);
private:
	double body[2]; //!< contains the elements of a 2D point or vector
};

//! returns a += b;
inline Vec2 & Vec2::operator+=(const Vec2 &b)
{
	body[0] += b[0];
	body[1] += b[1];
	return *this;
}


//! returns (a+b)
inline Vec2 operator+(const Vec2 &a, const Vec2 &b)
{
	return Vec2(a[0]+b[0],a[1]+b[1]);
}

inline void sum(Vec2 &result, const Vec2 &a, const Vec2 &b)
{
	result[0] = a[0]+b[0];
	result[1] = a[1]+b[1];
}

//! returns (a-b)
inline Vec2 operator-(const Vec2 &a, const Vec2 &b)
{
	return Vec2(a[0]-b[0],a[1]-b[1]);
}

inline void diff(Vec2 &result, const Vec2 &a, const Vec2 &b)
{
	result[0] = a[0]-b[0];
	result[1] = a[1]-b[1];
}

//! returns -a
inline Vec2 operator-(const Vec2 &a) { return Vec2(-a[0],-a[1]); }

//! returns a + scalar
inline Vec2 operator+(const Vec2&a, double b) {return Vec2(a[0]+b,a[1]+b); }
//! returns a - scalar
inline Vec2 operator-(const Vec2&a, double b) {return Vec2(a[0]-b,a[1]-b); }
//! returns a * scalar
inline Vec2 operator*(const Vec2&a, double b) {return Vec2(a[0]*b,a[1]*b); }
//! returns a / scalar
inline Vec2 operator/(const Vec2&a, double b) {return Vec2(a[0]/b,a[1]/b); }

//! return dot product 
inline double dot(const Vec2 &a, const Vec2 &b)
{
	return a[0]*b[0]+a[1]*b[1];
}

//! return 2D point perpendicular to argument
inline Vec2 perp(const Vec2 &v) { return Vec2(-v[1],v[0]); }

//! return 2-norm (vector length, distance from origin)
inline double magn(const Vec2 &a)
{
	return a.getSize();
}

//! return 2-norm (vector magnitude or length, distance from origin)
inline double Vec2::getSize() const
{
	const Vec2 &p = *this;
	return sqrt(p[0]*p[0]+p[1]*p[1]);
}

//! set vector to specified length or magnitude
inline Vec2 &Vec2::setSize(double sz)
{
	Vec2 &p = *this;
	double vn = getSize();
	assert(vn>0.0);
	sz /= vn;
	p[0] *= sz;
	p[1] *= sz;
	return *this;
}
	

//! return distance between two points
inline double distance(const Vec2 &a, const Vec2 &b)
{
	return _hypot(a[0]-b[0],a[1]-b[1]);
}


double perpdot(const Vec2 &a, const Vec2 &b);
double angle(const Vec2 &a,const Vec2 &b);
Vec2 rotate(const Vec2 &a, double theta);


vec2.cpp


/* \file vec2.cpp
 *
 */
//#include "stdafx.h"
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <iostream>
#include "vec2.h"

//! overloaded insertion operator <<
std::ostream& operator << (std::ostream& s, const Vec2& v)
{
	s << "[" << v[0] << " "  << v[1] << "]";
	return s ;
}

//! overloaded extraction operator >>
std::istream& operator >> (std::istream& s, Vec2& v) {
	char	c = ' ';

	while (isspace(c))
		s >> c;
    // The vectors can be formatted either as x y or [ x y ]
	if (c == '[') {
		s >> v[0] >> v[1];
		while (s >> c && isspace(c)) ;
		if (c != ']') s.putback(c); // let someone else deal with it
	}
	else {
		s.putback(c);
		s >> v[0] >> v[1];
	}
	return s;
}

//! return magnitude of cross product
/*!
 *  for 2D this is dot(perp(a),b)\n
 *  for 3D this is the magnitude of cross(a,b)
 */
double perpdot(const Vec2 &a, const Vec2 &b)
{
	return a[0]*b[1]-a[1]*b[0];
}

//! returns angle (in degrees) between two vectors
double angle(const Vec2 &a, const Vec2 &b)
{
	double c, s;
	const double dgr = 45.0/atan(1.0);
	c = dot(a,b);
	s = perpdot(a,b);
	return dgr*atan2(s,c);
}

const double radg = atan(1.0)/45.0;


Vec2::Vec2(double theta)
{
	theta *= radg;
	set(cos(theta),sin(theta));
}

//! rotate Vec2 about the origin by angle theta in degrees
Vec2 &Vec2::rotate(double theta)
{
	double c, s;
	Vec2 &a = *this;
	theta *= radg;
	c = cos(theta);
	s = sin(theta);
	double tmp = s*a[0]+c*a[1];
	a[0] = c*a[0]-s*a[1];
	a[1] = tmp;
	return a;
}

//! returns vec rotated by angle theta in degrees
Vec2 rotate(const Vec2 &a, double theta)
{
	double c, s;
	theta *= radg;
	c = cos(theta);
	s = sin(theta);
	return Vec2(c*a[0]-s*a[1],s*a[0]+c*a[1]);
}


Maintained by John Loomis, updated Sat Feb 03 11:15:31 2007