// -*- Mode: c++ -*- #ifndef __VEC2_H__ #define __VEC2_H__ // uses old-style iostream include; if using Standard C++ iostream (new style) // in the same code, change this include to // #include // to avoid problems #include #include #include // Vectors of length 2 // // The following operations are implemented (v,w are vectors, s is a scalar): // // binary: // v+w; v-w; s*v; v*s; v/s; dot(v,w), Min(v,w); Max(v,w) // assignments and self-modifying: // v = w; v += w; v-= w; v*= s; v /= s; v.normalize() // unary: // -v; v.dot(); v.length(); v.dir(); v.l1(); perp() // input/output: // os << v; is >> v; // class Vec2 { public: enum{ X = 0, Y = 1}; //default constructor: do nothing Vec2( void ) {} // copy constructor Vec2( const Vec2& w ) { v[X] = w.v[X], v[Y] = w.v[Y]; } // vector from three numbers Vec2( double x, double y) { v[X] = x, v[Y] = y; } // assignment Vec2& operator=( const Vec2& w ) { v[X] = w.v[X]; v[Y] = w.v[Y]; return *this; } // accessors to components double& x( void ) { return v[X]; } double x( void ) const { return v[X]; } double& y( void ) { return v[Y]; } double y( void ) const { return v[Y]; } double& operator() (const int i) {assert(i >= 0 && i < 2); return v[i];} double operator() (const int i) const {assert(i >= 0 && i < 2); return v[i]; } // operations combined with assignment Vec2& operator+=( const Vec2& w ) { v[X] += w.v[X], v[Y] += w.v[Y]; return *this; } Vec2& operator-=( const Vec2& w ) { v[X] -= w.v[X], v[Y] -= w.v[Y]; return *this; } Vec2& operator*=( double s ) { v[X] *= s, v[Y] *= s; return *this; } Vec2& operator/=( double s ) { v[X] /= s, v[Y] /= s; return *this; } // unary minus Vec2 operator-( void ) const { return Vec2( -v[X], -v[Y]); } // dot product of a vector with itself double dot( void ) const { return v[X] * v[X] + v[Y] * v[Y]; } double length( void ) const { return sqrt( dot() ); } // l1 norm (sum of abs values of the components) double l1( void ) const { double a = fabs( v[X] ); a += fabs( v[Y] ); return a; } // perpendicular vector pointing to the right Vec2 perp() { return Vec2(-v[Y], v[X]); } // for nonzero vectors, returns the normalized vector Vec2 dir( void ) const { double l = length(); if( ( l == 0) ) return *this; else return Vec2(v[X] / l, v[Y]/l); } // make the vector unit length // returns 1 if normalization was successful, 0 if the vector was zero vector int normalize( void ) { double l = length(); return (l == 0) ? 0 : ( *this *= 1 / l, 1 ); } private: double v[2]; }; // binary operations inline Vec2 operator+( const Vec2& v, const Vec2& w ) { return Vec2( v.x() + w.x(), v.y() + w.y()); } inline Vec2 operator-( const Vec2& v, const Vec2& w ) { return Vec2( v.x() - w.x(), v.y() - w.y()); } inline Vec2 operator*( double s, const Vec2& v ) { return Vec2( s*v.x(), s*v.y()); } inline Vec2 operator*( const Vec2& v, double s ) { return Vec2( s*v.x(), s*v.y()); } inline Vec2 operator/( const Vec2& v, double s ) { assert(s != 0); return Vec2( v.x()/s, v.y()/s); } inline double dot( const Vec2& v, const Vec2& w ) { return v.x() * w.x() + v.y() * w.y(); } // returns the componentwise minimum; we use Min and Max instead // of min and max to avoid problems when compiling in Win32 envorinment // inline Vec2 Min( const Vec2& v, const Vec2& w ) { return Vec2( (v.x() < w.x() )? v.x():w.x(), (v.y() < w.y() )? v.y():w.y()); } // returns the componentwise maximum inline Vec2 Max( const Vec2& v, const Vec2& w ) { return Vec2( (v.x() > w.x() )? v.x():w.x(), (v.y() > w.y() )? v.y():w.y()); } // output and input inline ostream& operator<<(ostream& os, const Vec2& v) { os << v.x() << " " << v.y(); return os; } inline istream& operator>>(istream& is, Vec2& v) { is >> v.x(); is >> v.y(); return is; } #endif /* __VEC2_H__ */