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