core/vgl/vgl_vector_2d.txx
Go to the documentation of this file.
00001 // This is core/vgl/vgl_vector_2d.txx
00002 #ifndef vgl_vector_2d_txx_
00003 #define vgl_vector_2d_txx_
00004 //:
00005 // \file
00006 
00007 #include "vgl_vector_2d.h"
00008 
00009 #include <vcl_cmath.h> // sqrt() , acos()
00010 #include <vcl_iostream.h>
00011 
00012 template <class T>
00013 double vgl_vector_2d<T>::length() const
00014 {
00015   return vcl_sqrt( 0.0+sqr_length() );
00016 }
00017 
00018 template<class T>
00019 double angle(vgl_vector_2d<T> const& a, vgl_vector_2d<T> const& b)
00020 {
00021   return vcl_acos(cos_angle(a,b));
00022 }
00023 
00024 
00025 template<class T>
00026 double signed_angle(vgl_vector_2d<T> const& a, vgl_vector_2d<T> const& b)
00027 {
00028   return vcl_atan2(double(cross_product(a, b)), double(dot_product(a, b)));
00029 }
00030 
00031 
00032 template <class T>
00033 bool orthogonal(vgl_vector_2d<T> const& a, vgl_vector_2d<T> const& b, double eps)
00034 {
00035   T dot = dot_product(a,b); // should be zero
00036   if (eps <= 0 || dot == T(0)) return dot == T(0);
00037   eps *= eps * a.sqr_length() * b.sqr_length();
00038   dot *= dot;
00039   return dot < eps;
00040 }
00041 
00042 template <class T>
00043 bool parallel(vgl_vector_2d<T> const& a, vgl_vector_2d<T> const& b, double eps)
00044 {
00045   T cross = cross_product(a,b); // should be zero
00046   if (eps <= 0 || cross == T(0)) return cross == T(0);
00047   eps *= eps * a.sqr_length() * b.sqr_length();
00048   return cross*cross < eps;
00049 }
00050 
00051 
00052 template <class T>
00053 vgl_vector_2d<T>  rotated(vgl_vector_2d<T> const& a, double angle)
00054 {
00055   return vgl_vector_2d<T>( T(vcl_cos(angle)*a.x()-vcl_sin(angle)*a.y()),
00056                            T(vcl_sin(angle)*a.x() + vcl_cos(angle)*a.y()) );
00057 }
00058 
00059 
00060 //: Write "<vgl_vector_2d x,y> " to stream
00061 template <class T>
00062 vcl_ostream&  operator<<(vcl_ostream& s, vgl_vector_2d<T> const& p)
00063 {
00064   return s << "<vgl_vector_2d "<< p.x() << ',' << p.y() <<  "> ";
00065 }
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 template <class T>
00072 vcl_istream& vgl_vector_2d<T>::read(vcl_istream& is)
00073 {
00074   if (! is.good()) return is; // (TODO: should throw an exception)
00075   bool paren = false;
00076   T tx, ty;
00077   is >> vcl_ws; // jump over any leading whitespace
00078   if (is.eof()) return is; // nothing to be set because of EOF (TODO: should throw an exception)
00079   if (is.peek() == '(') { is.ignore(); paren=true; }
00080   is >> vcl_ws >> tx >> vcl_ws;
00081   if (is.eof()) return is;
00082   if (is.peek() == ',') is.ignore();
00083   is >> vcl_ws >> ty >> vcl_ws;
00084   if (paren) {
00085     if (is.eof()) return is;
00086     if (is.peek() == ')') is.ignore();
00087     else                  return is; // closing parenthesis is missing (TODO: throw an exception)
00088   }
00089   set(tx,ty);
00090   return is;
00091 }
00092 
00093 //: Read x y from stream
00094 template <class T>
00095 vcl_istream&  operator>>(vcl_istream& is, vgl_vector_2d<T>& p)
00096 {
00097   return p.read(is);
00098 }
00099 
00100 
00101 #undef VGL_VECTOR_2D_INSTANTIATE
00102 #define VGL_VECTOR_2D_INSTANTIATE(T) \
00103 template class vgl_vector_2d<T >;\
00104 VCL_INSTANTIATE_INLINE(vgl_vector_2d<T >      operator+    (vgl_vector_2d<T > const&, vgl_vector_2d<T > const&));\
00105 VCL_INSTANTIATE_INLINE(vgl_vector_2d<T >      operator-    (vgl_vector_2d<T > const&, vgl_vector_2d<T > const&));\
00106 VCL_INSTANTIATE_INLINE(vgl_vector_2d<T >&     operator+=   (vgl_vector_2d<T >&, vgl_vector_2d<T > const&));\
00107 VCL_INSTANTIATE_INLINE(vgl_vector_2d<T >&     operator-=   (vgl_vector_2d<T >&, vgl_vector_2d<T > const&));\
00108 VCL_INSTANTIATE_INLINE(vgl_vector_2d<T >      operator+    (vgl_vector_2d<T > const&));\
00109 VCL_INSTANTIATE_INLINE(vgl_vector_2d<T >      operator-    (vgl_vector_2d<T > const&));\
00110 VCL_INSTANTIATE_INLINE(vgl_vector_2d<T >      operator*    (double, vgl_vector_2d<T > const&));\
00111 VCL_INSTANTIATE_INLINE(vgl_vector_2d<T >      operator*    (vgl_vector_2d<T > const&, double));\
00112 VCL_INSTANTIATE_INLINE(vgl_vector_2d<T >      operator/    (vgl_vector_2d<T > const&, double));\
00113 VCL_INSTANTIATE_INLINE(vgl_vector_2d<T >&     operator*=   (vgl_vector_2d<T >&, double));\
00114 VCL_INSTANTIATE_INLINE(vgl_vector_2d<T >&     operator/=   (vgl_vector_2d<T >&, double));\
00115 VCL_INSTANTIATE_INLINE(T      dot_product  (vgl_vector_2d<T > const&, vgl_vector_2d<T > const&));\
00116 VCL_INSTANTIATE_INLINE(T      inner_product(vgl_vector_2d<T > const&, vgl_vector_2d<T > const&));\
00117 VCL_INSTANTIATE_INLINE(T      cross_product(vgl_vector_2d<T > const&, vgl_vector_2d<T > const&));\
00118 VCL_INSTANTIATE_INLINE(double cos_angle    (vgl_vector_2d<T > const&, vgl_vector_2d<T > const&));\
00119 template               double angle        (vgl_vector_2d<T > const&, vgl_vector_2d<T > const&);\
00120 template               double signed_angle (vgl_vector_2d<T > const&, vgl_vector_2d<T > const&);\
00121 template               bool   orthogonal   (vgl_vector_2d<T > const&, vgl_vector_2d<T > const&, double);\
00122 template               bool   parallel     (vgl_vector_2d<T > const&, vgl_vector_2d<T > const&, double);\
00123 VCL_INSTANTIATE_INLINE(double operator/    (vgl_vector_2d<T > const&, vgl_vector_2d<T > const&));\
00124 VCL_INSTANTIATE_INLINE(vgl_vector_2d<T >&     normalize    (vgl_vector_2d<T >&));\
00125 VCL_INSTANTIATE_INLINE(vgl_vector_2d<T >      normalized   (vgl_vector_2d<T > const&));\
00126 template vgl_vector_2d<T >    rotated      (vgl_vector_2d<T > const&, double);\
00127 template        vcl_ostream&  operator<<   (vcl_ostream&, vgl_vector_2d<T >const&);\
00128 template        vcl_istream&  operator>>   (vcl_istream&, vgl_vector_2d<T >&)
00129 
00130 #endif // vgl_vector_2d_txx_