contrib/gel/vifa/vifa_imp_line.txx
Go to the documentation of this file.
00001 // This is gel/vifa/vifa_imp_line.txx
00002 #ifndef _VIFA_IMP_LINE_TXX_
00003 #define _VIFA_IMP_LINE_TXX_
00004 
00005 #include "vifa_imp_line.h"
00006 //:
00007 // \file
00008 
00009 #include <vcl_cmath.h>  // for vcl_sqrt()
00010 #include <vcl_cassert.h>
00011 #include <vgl/vgl_line_2d.h>
00012 
00013 
00014 template <class Type> vifa_imp_line<Type>::
00015 vifa_imp_line(vgl_point_2d<Type> const&  p1,
00016               vgl_point_2d<Type> const&  p2)
00017   : vgl_line_segment_2d<Type>(p1, p2)
00018 {
00019   dx_ = p2.x() - p1.x();
00020   dy_ = p2.y() - p1.y();
00021 }
00022 
00023 template <class Type> vifa_imp_line<Type>::
00024 vifa_imp_line(vgl_vector_2d<Type>  d,
00025               vgl_point_2d<Type>  m)
00026 {
00027   dx_ = d.x();
00028   dy_ = d.y();
00029 
00030   vgl_point_2d<Type>  p1(m.x() - (dx_ / 2.0), m.y() - (dy_ / 2.0));
00031   vgl_point_2d<Type>  p2(m.x() + (dx_ / 2.0), m.y() + (dy_ / 2.0));
00032   this->set(p1, p2);
00033 }
00034 
00035 template <class Type> vifa_imp_line<Type>::
00036 vifa_imp_line(Type  a,
00037               Type  b,
00038               Type  c
00039        )
00040 {
00041   // The values of a and b should not both be zero
00042   assert (a || b);
00043 
00044   // Use implicit coefficients to compute two on-axis points
00045   vgl_point_2d<Type>  p1;
00046   vgl_point_2d<Type>  p2;
00047   vgl_line_2d<Type>  l(a, b, c);
00048   l.get_two_points(p1, p2);
00049 
00050   // Use the on-axis points for line segment endpoints
00051   set_points(p1, p2);
00052 }
00053 
00054 template <class Type> double vifa_imp_line<Type>::
00055 get_dir_x(void)
00056 {
00057   vgl_vector_2d<double>  v(dx_, dy_);
00058   double          s = v.length();
00059 
00060   s = (near_zero(s) ? 1.0 : 1.0 / s);
00061 
00062   double  dx = dx_ * s;
00063   return near_zero(dx) ? 0.0 : dx;
00064 }
00065 
00066 template <class Type> double vifa_imp_line<Type>::
00067 length(void)
00068 {
00069   vgl_vector_2d<double>  v = this->point2() - this->point1();
00070   double          s = v.length();
00071 
00072   return s;
00073 }
00074 
00075 template <class Type> double vifa_imp_line<Type>::
00076 get_dir_y(void)
00077 {
00078   vgl_vector_2d<double>  v(dx_, dy_);
00079   double          s = v.length();
00080 
00081   s = (near_zero(s) ? 1.0 : 1.0 / s);
00082   double  dy = dy_ * s;
00083   return near_zero(dy) ? 0.0 : dy;
00084 }
00085 
00086 template <class Type> void vifa_imp_line<Type>::
00087 set_points(vgl_point_2d<Type> const&  p1,
00088            vgl_point_2d<Type> const&  p2)
00089 {
00090   // Call base method to update the endpoints
00091   this->set(p1, p2);
00092 
00093   // Set axis projections of unit direction vector
00094   vgl_vector_2d<double>  d = this->direction();
00095   dx_ = d.x();
00096   dy_ = d.y();
00097 }
00098 
00099 template <class Type> void vifa_imp_line<Type>::
00100 project_2d_pt(const Type& p,
00101               const Type& q,
00102               Type&       x,
00103               Type&       y) const
00104 {
00105   double  a = this->a();
00106   double  b = this->b();
00107   double  c = this->c();
00108   double  a2 = a * a;
00109   double  b2 = b * b;
00110   double  m = vcl_sqrt(a2 + b2);
00111 
00112   a /= m;
00113   b /= m;
00114   c /= m;
00115 
00116   if (b != 0)
00117   {
00118     x = (Type)(- (a * c) + b2 * p + a * b * q);
00119     y = (Type)((- c + a2 * c - a * b2 * p + a2 * b * q) / b);
00120   }
00121   else
00122   {
00123     x = (Type)(- c / a);
00124     y = (Type)(q);
00125   }
00126 }
00127 
00128 template <class Type> vgl_point_2d<Type> vifa_imp_line<Type>::
00129 project_2d_pt(const vgl_point_2d<Type>&  t) const
00130 {
00131   Type  p = t.x();
00132   Type  q = t.y();
00133   Type  x;
00134   Type  y;
00135 
00136   project_2d_pt(p, q, x, y);
00137 
00138   vgl_point_2d<Type>  u(x, y);
00139   return u;
00140 }
00141 
00142 // Find parametric t-value for a given point relative to line segment.
00143 template <class Type> double vifa_imp_line<Type>::
00144 find_t(vgl_point_2d<Type> const&  p)
00145 {
00146   double  dirx = get_dir_x();
00147   double  diry = get_dir_y();
00148   double  s = dx_ * dirx + dy_ * diry;
00149 
00150   if (near_zero(s))
00151   {
00152     return 0.5;
00153   }
00154 
00155   double  x = p.x() - this->point1().x();
00156   double  y = p.y() - this->point1().y();
00157   double  t = (x * dirx + y * diry) / s;
00158   return t;
00159 }
00160 
00161 
00162 // Find point on line (defined by line segment) for a parametric t-value.
00163 template <class Type> vgl_point_2d<Type> vifa_imp_line<Type>::
00164 find_at_t(double  t)
00165 {
00166   Type  x = (Type)(this->point1().x() + dx_ * t);
00167   Type  y = (Type)(this->point1().y() + dy_ * t);
00168 
00169   vgl_point_2d<Type>  p(x, y);
00170   return p;
00171 }
00172 
00173 
00174 #endif  // _VIFA_IMP_LINE_TXX_