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