core/vgl/vgl_line_2d.h
Go to the documentation of this file.
00001 // This is core/vgl/vgl_line_2d.h
00002 #ifndef vgl_line_2d_h_
00003 #define vgl_line_2d_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \author Don Hamilton, Peter Tu, Peter Vanroose, François BERTEL, Franck Bettinger
00010 // \date   2000-02-16 Don HAMILTON, Peter TU - Creation
00011 //
00012 // \verbatim
00013 //  Modifications
00014 //   2000-02-29 Peter Vanroose    Several minor fixes
00015 //   2000-05-05 François BERTEL   Several minor bugs fixed
00016 //   2000-05-09 Peter Vanroose    dist_origin() re-implemented
00017 //   2000-12-01 Peter Vanroose    moved dist_origin() to vgl_distance.h
00018 //   2001-03-19 Franck Bettinger  added Manchester binary IO code
00019 //   2001-06-27 Peter Vanroose    Added operator==
00020 //   2001-07-05 Peter Vanroose    direction, normal in terms of vgl_vector_2d
00021 //   2001-07-06 Peter Vanroose    Added concurrent(), added assertions
00022 //   2009-05-21 Peter Vanroose    istream operator>> re-implemented
00023 // \endverbatim
00024 
00025 #include <vcl_iosfwd.h>
00026 #include <vcl_cassert.h>
00027 #include <vgl/vgl_fwd.h> // forward declare vgl_point_2d and vgl_homg_line_2d
00028 #include <vgl/vgl_vector_2d.h>
00029 
00030 //: Represents a Euclidean 2D line
00031 // An interface for the line coefficients, [a,b,c], is provided in terms of the
00032 // standard implicit line equation: a*x + b*y + c = 0
00033 template <class Type>
00034 class vgl_line_2d
00035 {
00036   // the data associated with this point
00037   Type a_;
00038   Type b_;
00039   Type c_;
00040 
00041  public:
00042   //: Default constructor (Line 1.y==0, the X axis)
00043   inline vgl_line_2d() : a_(0), b_(1), c_(0) {}
00044 
00045   //: Construct a vgl_line_2d from its equation, three Types.
00046   //  The values of a and b should not be both zero.
00047   inline vgl_line_2d(Type ta, Type tb, Type tc) :a_(ta),b_(tb),c_(tc) { assert(ta||tb); }
00048 
00049   //: Construct from its equation, a 3-vector.
00050   //  The values v[0] and v[1] should not be both zero.
00051   inline vgl_line_2d(const Type v[3]):a_(v[0]),b_(v[1]),c_(v[2]) { assert(a_||b_); }
00052 
00053   //: Construct from homogeneous description of line
00054   //  The line l should not be the line at infinity.
00055   vgl_line_2d (vgl_homg_line_2d<Type> const& l);
00056 
00057   //: Construct from two distinct points (join)
00058   //  The two points must be distinct!
00059   vgl_line_2d (vgl_point_2d<Type> const& p1, vgl_point_2d<Type> const& p2);
00060 
00061   //: Construct from one point and one vector
00062   vgl_line_2d (vgl_point_2d<Type> const& p, vgl_vector_2d<Type> const& v);
00063 
00064 #if 0 // use compiler defaults for these
00065   // Default destructor
00066   inline ~vgl_line_2d () {}
00067 
00068   // Default assignment operator
00069   inline vgl_line_2d<Type>& operator=(const vgl_line_2d<Type>& l)
00070   { set(l.a(),l.b(),l.c()); return *this; }
00071 #endif
00072 
00073   //: the comparison operator
00074   inline bool operator==(vgl_line_2d<Type> const& l) const
00075   {
00076     return (this==&l) ||
00077            (a()*l.c()==c()*l.a() && b()*l.c()==c()*l.b() && b()*l.a()==a()*l.b());
00078   }
00079 
00080   inline bool operator!=(vgl_line_2d<Type>const& other) const { return !operator==(other); }
00081 
00082   //: angle with the horizontal line y=0, measured in radians.
00083   //  Returns values between -pi and pi, i.e., the lines x-y=0 and y-x=0
00084   //  return different values (pi/4 and -3pi/4 respectively) although these
00085   //  lines are identical.
00086   double slope_radians() const;
00087 
00088   //: angle with the horizontal line y=0, measured in 360-degrees.
00089   //  Returns values between -180 and 180, i.e., the lines x-y=0 and y-x=0
00090   //  return different values (45 and -135 respectively) although these
00091   //  lines are identical.
00092   double slope_degrees() const;
00093 
00094   // Data Access-------------------------------------------------------------
00095 
00096   //: Parameter a of line a*x + b*y + c = 0
00097   inline Type a() const {return a_;}
00098   //: Parameter b of line a*x + b*y + c = 0
00099   inline Type b() const {return b_;}
00100   //: Parameter c of line a*x + b*y + c = 0
00101   inline Type c() const {return c_;}
00102 
00103   //: unit vector describing line direction
00104   inline vgl_vector_2d<Type> direction() const
00105   { return normalized(vgl_vector_2d<Type>(b_,-a_)); }
00106 
00107   //: unit vector orthogonal to line
00108   inline vgl_vector_2d<Type> normal() const
00109   { return normalized(vgl_vector_2d<Type>(a_,b_)); }
00110 
00111   //: normalize the line coefficients s.t. a^2 + b^2 = 1
00112   bool normalize();
00113 
00114   //: Set a b c.
00115   //  The values of a and b should not be both zero.
00116   //  Note that it does not make sense to set a, b or c separately
00117   inline void set(Type ta, Type tb, Type tc) { assert(ta||tb); a_=ta; b_=tb; c_=tc; }
00118 
00119   //: Return true iff this line is the line at infinity
00120   //  This always returns "false"
00121   inline bool ideal(Type = (Type)0) const { return false; }
00122 
00123   //: Get two points on the line; normally the intersection with X and Y axes.
00124   // When the line is parallel to one of these,
00125   // the point with \a y=1 or \a x=1, resp. are taken.  When the line goes
00126   // through the origin, the second point is (b, -a).
00127   void get_two_points(vgl_point_2d<Type> &p1, vgl_point_2d<Type> &p2) const;
00128 };
00129 
00130 #define l vgl_line_2d<Type>
00131 
00132 //: Return true iff line is the line at infinity
00133 // \relatesalso vgl_line_2d
00134 template <class Type> inline
00135 bool is_ideal(l const&, Type = (Type)0) { return false; }
00136 
00137 //: Are three lines concurrent, i.e., do they pass through a common point?
00138 // \relatesalso vgl_line_2d
00139 template <class Type> inline
00140 bool concurrent(l const& l1, l const& l2, l const& l3)
00141 {
00142   return l1.a()*(l2.b()*l3.c()-l3.b()*l2.c())
00143         +l2.a()*(l3.b()*l1.c()-l1.b()*l3.c())
00144         +l3.a()*(l1.b()*l2.c()-l2.b()*l1.c())==0;
00145 }
00146 
00147 //: Write line description to stream: "<vgl_line_2d ax+by+c>"
00148 // \relatesalso vgl_line_2d
00149 template <class Type>
00150 vcl_ostream&  operator<<(vcl_ostream& s, l const& line);
00151 
00152 //: Read in three line parameters from stream
00153 //  Either just reads three blank-separated numbers,
00154 //  or reads three comma-separated numbers,
00155 //  or reads three numbers in parenthesized form "(123, 321, -456)"
00156 //  or reads a formatted line equation "123x+321y-456=0"
00157 // \relatesalso vgl_line_2d
00158 template <class Type>
00159 vcl_istream&  operator>>(vcl_istream& s, l& line);
00160 
00161 #undef l
00162 
00163 #define VGL_LINE_2D_INSTANTIATE(T) extern "please include vgl/vgl_line_2d.txx first"
00164 
00165 #endif // vgl_line_2d_h_