Go to the documentation of this file.00001
00002 #ifndef vgl_line_2d_txx_
00003 #define vgl_line_2d_txx_
00004
00005
00006
00007 #include "vgl_line_2d.h"
00008 #include <vcl_cmath.h>
00009 #include <vcl_cassert.h>
00010 #include <vcl_iostream.h>
00011 #include <vgl/vgl_point_2d.h>
00012 #include <vgl/vgl_homg_line_2d.h>
00013
00014
00015 template <class Type>
00016 vgl_line_2d<Type>::vgl_line_2d (vgl_point_2d<Type> const& p1, vgl_point_2d<Type> const& p2)
00017 : a_ ( p1.y() - p2.y() )
00018 , b_ ( p2.x() - p1.x() )
00019 , c_ ( p1.x() * p2.y() - p1.y() * p2.x() )
00020 {
00021 assert(a_||b_);
00022 }
00023
00024
00025 template <class Type>
00026 vgl_line_2d<Type>::vgl_line_2d (vgl_point_2d<Type> const& p, vgl_vector_2d<Type> const& v)
00027 : a_ ( -v.y() )
00028 , b_ ( v.x() )
00029 , c_ ( -a_*p.x() - b_*p.y() )
00030 {
00031 }
00032
00033 template <class Type>
00034 vgl_line_2d<Type>::vgl_line_2d (vgl_homg_line_2d<Type> const& l)
00035 : a_(l.a()) , b_(l.b()) , c_(l.c())
00036 {
00037
00038
00039 }
00040
00041
00042
00043
00044
00045
00046 template <class Type>
00047 void vgl_line_2d<Type>::get_two_points(vgl_point_2d<Type> &p1, vgl_point_2d<Type> &p2) const
00048 {
00049 if (b() == 0) p1.set(-c()/a(), 1);
00050 else p1.set(0, -c()/b());
00051 if (a() == 0) p2.set(1, -c()/b());
00052 else if ( c() == 0) p2.set(b(), -a());
00053 else p2.set(-c()/a(), 0);
00054 }
00055
00056 template <class Type>
00057 double vgl_line_2d<Type>::slope_degrees() const
00058 {
00059 static const double deg_per_rad = 45.0/vcl_atan2(1.0,1.0);
00060
00061 if (a() == 0) return b()<0 ? 0.0 : 180.0;
00062 if (b() == 0) return a()<0 ? -90.0 : 90.0;
00063 if (a() == b()) return a()<0 ? -45.0 : 135.0;
00064 if (a()+b() == 0) return a()<0 ? -135.0 : 45.0;
00065
00066 return deg_per_rad * vcl_atan2(double(a()),-double(b()));
00067 }
00068
00069 template <class Type>
00070 double vgl_line_2d<Type>::slope_radians() const
00071 {
00072 return vcl_atan2(double(a()),-double(b()));
00073 }
00074
00075 template <class Type>
00076 bool vgl_line_2d<Type>::normalize()
00077 {
00078 double mag = a_*a_ + b_*b_;
00079 if (mag==1.0) return true;
00080 if (mag==0.0) return false;
00081 mag = 1.0/vcl_sqrt(mag);
00082 a_ = Type(a_*mag);
00083 b_ = Type(b_*mag);
00084 c_ = Type(c_*mag);
00085 mag = a_*a_ + b_*b_;
00086
00087 return mag>0.99 && mag<1.01;
00088 }
00089
00090 #define vp(os,v,s) { os<<' '; if ((v)>0) os<<'+'; if ((v)&&!s[0]) os<<(v); else { \
00091 if ((v)==-1) os<<'-';\
00092 else if ((v)!=0&&(v)!=1) os<<(v);\
00093 if ((v)!=0) os<<' '<<s; } }
00094
00095
00096 template <class Type>
00097 vcl_ostream& operator<<(vcl_ostream& os, vgl_line_2d<Type> const& l)
00098 {
00099 os << "<vgl_line_2d"; vp(os,l.a(),"x"); vp(os,l.b(),"y"); vp(os,l.c(),"");
00100 return os << " = 0 >";
00101 }
00102
00103 #undef vp
00104
00105
00106
00107
00108
00109
00110 template <class Type>
00111 vcl_istream& operator>>(vcl_istream& is, vgl_line_2d<Type>& line)
00112 {
00113 if (! is.good()) return is;
00114 bool paren = false;
00115 bool formatted = false;
00116 Type a, b, c;
00117 is >> vcl_ws;
00118 if (is.eof()) return is;
00119 if (is.peek() == '(') { is.ignore(); paren=true; }
00120 is >> vcl_ws >> a >> vcl_ws;
00121 if (is.eof()) return is;
00122 if (is.peek() == ',') is.ignore();
00123 else if (is.peek() == 'x') { is.ignore(); formatted=true; }
00124 is >> vcl_ws >> b >> vcl_ws;
00125 if (is.eof()) return is;
00126 if (formatted) {
00127 if (is.eof()) return is;
00128 if (is.peek() == 'y') is.ignore();
00129 else return is;
00130 }
00131 else if (is.peek() == ',') is.ignore();
00132 is >> vcl_ws >> c >> vcl_ws;
00133 if (paren) {
00134 if (is.eof()) return is;
00135 if (is.peek() == ')') is.ignore();
00136 else return is;
00137 }
00138 if (formatted) {
00139 if (is.eof()) return is;
00140 if (is.peek() == '=') is.ignore();
00141 else return is;
00142 is >> vcl_ws;
00143 if (is.peek() == '0') is.ignore();
00144 else return is;
00145 }
00146 line.set(a,b,c);
00147 return is;
00148 }
00149
00150 #undef VGL_LINE_2D_INSTANTIATE
00151 #define VGL_LINE_2D_INSTANTIATE(T) \
00152 template class vgl_line_2d<T >; \
00153 template vcl_ostream& operator<<(vcl_ostream&, vgl_line_2d<T >const&); \
00154 template vcl_istream& operator>>(vcl_istream&, vgl_line_2d<T >&)
00155
00156 #endif // vgl_line_2d_txx_