core/vgl/vgl_homg_line_2d.txx
Go to the documentation of this file.
00001 // This is core/vgl/vgl_homg_line_2d.txx
00002 #ifndef vgl_homg_line_2d_txx_
00003 #define vgl_homg_line_2d_txx_
00004 //:
00005 // \file
00006 
00007 #include "vgl_homg_line_2d.h"
00008 #include <vcl_cmath.h>
00009 #include <vcl_cassert.h>
00010 #include <vcl_iostream.h>
00011 #include <vgl/vgl_homg_point_2d.h>
00012 #include <vgl/vgl_line_2d.h>
00013 
00014 template <class Type>
00015 vgl_homg_line_2d<Type>::vgl_homg_line_2d (vgl_line_2d<Type> const& l)
00016   : a_(l.a()) , b_(l.b()) , c_(l.c())
00017 {
00018 }
00019 
00020 //: get two points on the line.
00021 //  These two points are normally the intersections with the Y axis and X axis,
00022 //  respectively.  When the line is parallel to one of these, the point with
00023 //  \a y/w=1 or \a x/w=1, resp. are taken.  When the line goes through the origin,
00024 //  the second point is (b, -a, 1).  Finally, when the line is the line at
00025 //  infinity, the returned points are (1,0,0) and (0,1,0).
00026 //
00027 //  Thus, whenever possible, the returned points are not at infinity.
00028 //
00029 template <class Type>
00030 void vgl_homg_line_2d<Type>::get_two_points(vgl_homg_point_2d<Type> &p1, vgl_homg_point_2d<Type> &p2) const
00031 {
00032   if (      b() == 0) p1.set(-c(), a(), a());
00033   else                p1.set(0, -c(), b());
00034   if (      a() == 0) p2.set(b(), -c(), b());
00035   else if ( c() == 0) p2.set(b(), -a(), 1);
00036   else                p2.set(-c(), 0, a());
00037 }
00038 
00039 template <class Type>
00040 vgl_homg_line_2d<Type>::vgl_homg_line_2d (vgl_homg_point_2d<Type> const& p1,
00041                                           vgl_homg_point_2d<Type> const& p2)
00042 {
00043   set(p1.y()*p2.w()-p1.w()*p2.y(),
00044       p1.w()*p2.x()-p1.x()*p2.w(),
00045       p1.x()*p2.y()-p1.y()*p2.x());
00046   assert(a_||b_||c_); // given points should be different
00047 }
00048 
00049 #define vp(os,v,s) { os<<' '; if ((v)>0) os<<'+';\
00050                      if ((v)&&!s[0]) os<<(v); else { \
00051                        if ((v)==-1) os<<'-';\
00052                        else if ((v)!=0&&(v)!=1) os<<(v);\
00053                        if ((v)!=0) os<<' '<<s; } }
00054 
00055 //: Print line equation to stream
00056 template <class Type>
00057 vcl_ostream&  operator<<(vcl_ostream& os, vgl_homg_line_2d<Type>const& l)
00058 {
00059   os << "<vgl_homg_line_2d"; vp(os,l.a(),"x"); vp(os,l.b(),"y"); vp(os,l.c(),"w");
00060   return os << " = 0 >";
00061 }
00062 
00063 #undef vp
00064 
00065 //: Load in line parameters from stream
00066 template <class Type>
00067 vcl_istream&  operator>>(vcl_istream& is, vgl_homg_line_2d<Type>& p)
00068 {
00069   Type a,b,c;
00070   is >> a >> b >> c;
00071   p.set(a,b,c);
00072   return is;
00073 }
00074 
00075 template <class Type>
00076 void vgl_homg_line_2d<Type>::normalize()
00077 {
00078   double sum = a_*a_ + b_*b_;
00079   double den = vcl_sqrt(sum);
00080   if (den<1.0e-8)//don't normalize ideal line
00081     return;
00082   double an= (double)a()/den;
00083   double bn= (double)b()/den;
00084   double cn= (double)c()/den;
00085   //standardize so that a is positive unless a is smaller than b, then
00086   //standardize the sign of b
00087   if (vcl_fabs(an)>vcl_fabs(bn))
00088     if (an>0)
00089     {
00090       a_ = (Type)an;
00091       b_ = (Type)bn;
00092       c_ = (Type)cn;
00093     }
00094     else
00095     {
00096       a_ = -(Type)an;
00097       b_ = -(Type)bn;
00098       c_ = -(Type)cn;
00099     }
00100   else
00101     if (bn>0)
00102     {
00103       a_ = (Type)an;
00104       b_ = (Type)bn;
00105       c_ = (Type)cn;
00106     }
00107     else
00108     {
00109       a_ = -(Type)an;
00110       b_ = -(Type)bn;
00111       c_ = -(Type)cn;
00112     }
00113 
00114   return;
00115 }
00116 
00117 #undef VGL_HOMG_LINE_2D_INSTANTIATE
00118 #define VGL_HOMG_LINE_2D_INSTANTIATE(T) \
00119 template class vgl_homg_line_2d<T >; \
00120 template vcl_ostream& operator<<(vcl_ostream&, vgl_homg_line_2d<T >const&); \
00121 template vcl_istream& operator>>(vcl_istream&, vgl_homg_line_2d<T >&)
00122 
00123 #endif // vgl_homg_line_2d_txx_