core/vgl/vgl_vector_2d.h
Go to the documentation of this file.
00001 // This is core/vgl/vgl_vector_2d.h
00002 #ifndef vgl_vector_2d_h_
00003 #define vgl_vector_2d_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief direction vector in Euclidean 2D space
00010 // \author Peter Vanroose
00011 // \date 27 June, 2001
00012 //
00013 // \verbatim
00014 // Modifications
00015 // 2001-07-05 Peter Vanroose  Added orthogonal(); operator* now accepts double
00016 // 2009-05-21 Peter Vanroose  istream operator>> re-implemented
00017 // \endverbatim
00018 
00019 #include <vcl_iosfwd.h>
00020 
00021 //----------------------------------------------------------------------
00022 
00023 //: Direction vector in Euclidean 2D space, templated by type of element
00024 // (typically float or double).  A vgl_vector_2d<T> represents the
00025 // difference (or connecting vector) between two vgl_point_2d<T>s.
00026 //
00027 // Use this class to do arithmetic (adding and scaling) in 2d geometric space.
00028 //
00029 template <class T>
00030 class vgl_vector_2d
00031 {
00032  public:
00033   T x_; // Data is public
00034   T y_;
00035   inline T x() const { return x_; }
00036   inline T y() const { return y_; }
00037 
00038   //: Creates the vector (0,0) of zero length.
00039   inline vgl_vector_2d () : x_(0) , y_(0) {}
00040 
00041   //: Creates the vector \a (x,y).
00042   inline vgl_vector_2d (T vx, T vy) : x_(vx) , y_(vy) {}
00043 
00044 #if 0 // The defaults do exactly what they should do...
00045   //: Copy constructor
00046   inline vgl_vector_2d (vgl_vector_2d<T> const& v) : x_(v.x()) , y_(v.y()) {}
00047   //: Assignment operator
00048   inline vgl_vector_2d<T>& operator=(vgl_vector_2d<T> const& v) {
00049     x_=v.x(); y_=v.y(); return *this; }
00050   //: Destructor
00051   inline ~vgl_vector_2d () {}
00052 #endif
00053 
00054   //: Assignment
00055   inline void set(T vx, T vy) { x_=vx; y_=vy; }
00056 
00057   //: Comparison
00058   inline bool operator==(vgl_vector_2d<T>const& v)const{return x_==v.x()&&y_==v.y();}
00059   inline bool operator!=(vgl_vector_2d<T>const& v)const{return !operator==(v);}
00060 
00061   //: Return the length of this vector.
00062   double length() const; // return sqrt( x()*x()+y()*y() );
00063 
00064   //: Return the squared length of this vector.
00065   inline T sqr_length() const { return x()*x()+y()*y(); }
00066 
00067   //: Read from stream, possibly with formatting
00068   //  Either just reads two blank-separated numbers,
00069   //  or reads two comma-separated numbers,
00070   //  or reads two numbers in parenthesized form "(123, 321)"
00071   vcl_istream& read(vcl_istream& is);
00072 };
00073 
00074 #define v vgl_vector_2d<T>
00075 
00076 //  +-+-+ vector_2d simple I/O +-+-+
00077 
00078 //: Write "<vgl_vector_2d x,y> " to stream
00079 // \relatesalso vgl_vector_2d
00080 template <class T> vcl_ostream& operator<<(vcl_ostream& s, v const& p);
00081 
00082 //: Read from stream, possibly with formatting
00083 //  Either just reads two blank-separated numbers,
00084 //  or reads two comma-separated numbers,
00085 //  or reads two numbers in parenthesized form "(123, 321)"
00086 // \relatesalso vgl_vector_2d
00087 template <class T> vcl_istream& operator>>(vcl_istream& s, v& p);
00088 
00089 
00090 //  +-+-+ vector_2d geometry and algebra +-+-+
00091 
00092 //: Return the length of a vector.
00093 // \relatesalso vgl_vector_2d
00094 template <class T> inline double length(v const& a) { return a.length(); }
00095 
00096 //: Return the squared length of a vector.
00097 // \relatesalso vgl_vector_2d
00098 template <class T> inline T sqr_length(v const& a) { return a.sqr_length(); }
00099 
00100 //: c=a+b: add two vectors.
00101 // \relatesalso vgl_vector_2d
00102 template <class T> inline v      operator+(v const& a, v const& b) { return v(a.x()+b.x(), a.y()+b.y()); }
00103 
00104 //: c=a-b: subtract two vectors.
00105 // \relatesalso vgl_vector_2d
00106 template <class T> inline v      operator-(v const& a, v const& b) { return v(a.x()-b.x(), a.y()-b.y()); }
00107 
00108 //: a+=b: add b to a and return a.
00109 // \relatesalso vgl_vector_2d
00110 template <class T> inline v&     operator+=(v& a, v const& b) { a.x_+=b.x_; a.y_+=b.y_; return a; }
00111 
00112 //: a-=b: subtract b from a and return a.
00113 // \relatesalso vgl_vector_2d
00114 template <class T> inline v&     operator-=(v& a, v const& b) { a.x_-=b.x_; a.y_-=b.y_; return a; }
00115 
00116 //: +b: unary plus operator (no-op).
00117 // \relatesalso vgl_vector_2d
00118 template <class T> inline v      operator+(v const& b) { return b; }
00119 
00120 //: -a: unary minus operator (additive inverse).
00121 // \relatesalso vgl_vector_2d
00122 template <class T> inline v      operator-(v const& b) { return v(-b.x(), -b.y()); }
00123 
00124 //: c=f*b: return a scaled version of the vector.
00125 // \relatesalso vgl_vector_2d
00126 template <class T> inline v      operator*(double s, v const& b) { return v(T(s*b.x()), T(s*b.y())); }
00127 
00128 //: c=a*f: return a scaled version of the vector.
00129 // \relatesalso vgl_vector_2d
00130 template <class T> inline v      operator*(v const& a, double s) { return v(T(a.x()*s), T(a.y()*s)); }
00131 
00132 //: c=b/f: return an inversely scaled version of the vector (scale must be nonzero).
00133 //  Note that the argument type is double, not T, to avoid rounding errors
00134 //  when type T has no multiplicative inverses (like T=int).
00135 // \relatesalso vgl_vector_2d
00136 template <class T> inline v      operator/(v const& a, double s) { return v(T(a.x()/s), T(a.y()/s)); }
00137 
00138 //: a*=f: scale the vector.
00139 // \relatesalso vgl_vector_2d
00140 template <class T> inline v&     operator*=(v& a, double s) { a.set(T(a.x()*s), T(a.y()*s)); return a; }
00141 
00142 //: a/=f: inversely scale the vector (scale must be nonzero).
00143 // \relatesalso vgl_vector_2d
00144 template <class T> inline v&     operator/=(v& a, double s) { a.set(T(a.x()/s), T(a.y()/s)); return a; }
00145 
00146 //: dot product or inner product of two vectors.
00147 // \relatesalso vgl_vector_2d
00148 template <class T> inline T      dot_product(v const& a, v const& b) { return a.x()*b.x()+a.y()*b.y(); }
00149 
00150 //: dot product or inner product of two vectors.
00151 // \relatesalso vgl_vector_2d
00152 template <class T> inline T      inner_product(v const& a, v const& b) { return a.x()*b.x()+a.y()*b.y(); }
00153 
00154 //: cross product of two vectors (area of enclosed parallellogram).
00155 // \relatesalso vgl_vector_2d
00156 template <class T> inline T      cross_product(v const& a, v const& b) { return a.x()*b.y()-a.y()*b.x(); }
00157 
00158 //: cosine of the angle between two vectors.
00159 // \relatesalso vgl_vector_2d
00160 template <class T> inline double cos_angle(v const& a, v const& b) { return inner_product(a,b)/(a.length()*b.length()); }
00161 
00162 //: smallest angle between two vectors (in radians, between 0 and Pi).
00163 // \relatesalso vgl_vector_2d
00164 template <class T>        double angle(v const& a, v const& b); // return acos(cos_angle(a,b));
00165 
00166 //: signed angle between two vectors (in radians, between -Pi and Pi).
00167 // return the rotation angle to go from `a' to `b'
00168 // \relatesalso vgl_vector_2d
00169 template <class T>        double signed_angle(v const& a, v const& b);
00170 
00171 //: are two vectors orthogonal, i.e., is their dot product zero?
00172 // If the third argument is specified, it is taken as the "tolerance", i.e.
00173 // in that case this function returns true if the vectors are almost orthogonal.
00174 // \relatesalso vgl_vector_2d
00175 template <class T>        bool orthogonal(v const& a, v const& b, double eps=0.0);
00176 
00177 //: are two vectors parallel, i.e., is one a scalar multiple of the other?
00178 // If the third argument is specified, it is taken as the "tolerance", i.e.
00179 // in that case this function returns true if the vectors are almost parallel.
00180 // \relatesalso vgl_vector_2d
00181 template <class T>        bool parallel(v const& a, v const& b, double eps=0.0);
00182 
00183 //: f=a/b: return the ratio of two vectors, if they are parallel.
00184 //  (If not, return a "least squares" approximation.)
00185 //  Note that the return type is double, not T, since the ratio of e.g.
00186 //  two vgl_vector_2d<int> need not be an int.
00187 // \relatesalso vgl_vector_2d
00188 template <class T> inline double operator/(v const& a, v const& b)
00189 { return dot_product(a,b)/(double)dot_product(b,b); }
00190 
00191 //: Normalise by dividing through by the length, thus returning a length 1 vector.
00192 //  If a is zero length, return (0,0).
00193 // \relatesalso vgl_vector_2d
00194 template <class T> inline v&     normalize(v& a) { double l=a.length(); return l?a/=l:a; }
00195 
00196 //: Return a normalised version of a.
00197 //  If a is zero length, return (0,0).
00198 // \relatesalso vgl_vector_2d
00199 template <class T> inline v      normalized(v const& a) { double l=a.length(); return l?a/l:a; }
00200 
00201 //: Return a CCW rotated version of a (angle in radian)
00202 // \relatesalso vgl_vector_2d
00203 template <class T> v      rotated(v const& a, double angle);
00204 
00205 #undef v
00206 
00207 #define VGL_VECTOR_2D_INSTANTIATE(T) extern "please include vgl/vgl_vector_2d.txx first"
00208 
00209 #endif // vgl_vector_2d_h_