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_