contrib/oxl/mvl/HomgLineSeg2D.cxx
Go to the documentation of this file.
00001 // This is oxl/mvl/HomgLineSeg2D.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 
00008 #include "HomgLineSeg2D.h"
00009 #include <mvl/HomgPoint2D.h>
00010 #include <mvl/HomgLine2D.h>
00011 #include <mvl/HomgOperator2D.h>
00012 #include <vnl/vnl_double_2.h>
00013 #include <vcl_iostream.h>
00014 
00015 //--------------------------------------------------------------
00016 //
00017 //: Constructor forming linesegment from start and end points
00018 HomgLineSeg2D::HomgLineSeg2D (const HomgPoint2D& point1,
00019                               const HomgPoint2D& point2):
00020   HomgLine2D(HomgOperator2D::join (point1, point2)),
00021   point1_(point1),
00022   point2_(point2)
00023 {
00024 }
00025 
00026 //--------------------------------------------------------------
00027 //
00028 //: Constructor forming linesegment (x0,y0) -> (x1,y1)
00029 HomgLineSeg2D::HomgLineSeg2D (double x0, double y0, double x1, double y1):
00030   HomgLine2D(y0 - y1, x1 - x0, x0 * y1 - x1 * y0),
00031   point1_(HomgPoint2D(x0, y0, 1.0)),
00032   point2_(HomgPoint2D(x1, y1, 1.0))
00033 {
00034 }
00035 
00036 //--------------------------------------------------------------
00037 //
00038 //: Set the line segment given two points
00039 void HomgLineSeg2D::set (const HomgPoint2D& point1,
00040                          const HomgPoint2D& point2)
00041 {
00042   point1_ = point1;
00043   point2_ = point2;
00044   HomgLine2D::operator=(HomgOperator2D::join (point1, point2));
00045 }
00046 
00047 //-----------------------------------------------------------------------------
00048 //
00049 //: print to vcl_ostream
00050 vcl_ostream& operator<<(vcl_ostream& s, const HomgLineSeg2D& p)
00051 {
00052   return s << "<HomgLineSeg2D " << p.get_vector()
00053            << " from " << p.get_point1()
00054            << " to " << p.get_point2() << ">";
00055 }
00056 
00057 #ifdef VXL_UNDEF
00058 //-----------------------------------------------------------------------------
00059 //
00060 //: Convert the segment to an ImplicitLine, allocated using new.
00061 // Return 0 if either endpoint is at infinity.
00062 ImplicitLine* HomgLineSeg2D::get_implicitline() const
00063 {
00064   IUPoint *startpoint = get_point1().get_iupoint();
00065   IUPoint *endpoint = get_point2().get_iupoint();
00066   if (!startpoint || !endpoint) {
00067     vcl_cerr << "HomgLineSeg2D::get_implicitline() -- Endpoint at infinity\n"
00068              << "    " << *this << vcl_endl;
00069     return 0;
00070   }
00071 
00072   return new ImplicitLine(startpoint, endpoint);
00073 }
00074 #endif
00075 
00076 //: Return distance to nearest point contained in lineseg
00077 double HomgLineSeg2D::picking_distance(const HomgPoint2D& hp) const
00078 {
00079   const HomgLineSeg2D& l = *this;
00080 
00081   vnl_double_2 p;
00082   hp.get_nonhomogeneous(p[0], p[1]);
00083 
00084   vnl_double_2 l1;
00085   l.get_point1().get_nonhomogeneous(l1[0], l1[1]);
00086 
00087   double x1, y1;
00088   l.get_point2().get_nonhomogeneous(x1, y1);
00089   vnl_double_2 l2(x1, y1);
00090 
00091   vnl_double_2 dir = l2 - l1;
00092 
00093   double seg_length = dir.magnitude() / 2;
00094   dir.normalize();
00095 
00096   vnl_double_2 mid = (l2 + l1);
00097   mid /= 2;
00098 
00099   vnl_double_2 diff = p - mid;
00100 
00101   dir *= dot_product(diff, dir);
00102 
00103   double projection_length = dir.magnitude();
00104   diff = diff - dir;
00105   double d = diff.magnitude();
00106 
00107   //check if outside
00108   if (projection_length > seg_length)
00109     return 1e20;
00110 
00111   return d;
00112 }