LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiFastLine.h

00001 /*
00002  * Copyright (C) 2003, 2004, 2005, 2006
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  * 
00005  * This file is part of the LTI-Computer Vision Library (LTI-Lib)
00006  *
00007  * The LTI-Lib is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License (LGPL)
00009  * as published by the Free Software Foundation; either version 2.1 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * The LTI-Lib is distributed in the hope that it will be
00013  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00014  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public 
00018  * License along with the LTI-Lib; see the file LICENSE.  If
00019  * not, write to the Free Software Foundation, Inc., 59 Temple Place -
00020  * Suite 330, Boston, MA 02111-1307, USA.  
00021  */ 
00022 
00023  
00024 /*----------------------------------------------------------------
00025  * project ....: LTI Digital Image/Signal Processing Library
00026  * file .......: ltiFastLine.h
00027  * authors ....: Claudia Goenner
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 07.02.2003
00030  * revisions ..: $Id: ltiFastLine.h,v 1.7 2006/02/08 12:21:37 ltilib Exp $
00031  */
00032 
00033 #ifndef LTI_FAST_LINE_H
00034 #define LTI_FAST_LINE_H
00035 
00036 #include "ltiConfig.h"
00037 
00038 #include <iostream>
00039 #include <limits>
00040 
00041 #include "ltiIoHandler.h"
00042 #include "ltiMath.h"
00043 #include "ltiPoint.h"
00044 #include "ltiLine.h"
00045 #include "ltiRectangle.h"
00046 
00047 namespace lti {
00048 
00049 
00050   /**
00051    * Type for computations with lines.
00052    *
00053    * A line (or more generally a tfastLine<T>) is represented by a start point
00054    * and an end point.
00055    *
00056    * The type T correspond to the coordinate type used in both points.
00057    *
00058    * This class stores besides the two delimiting points other derived
00059    * information that can save some time in some intensive computations 
00060    * involving distances and intersections of lines.
00061    *
00062    * Of course, the class becomes faster, if the operations are done with
00063    * lines that do not change much in time.  If you have thousends of lines
00064    * and want to compute the intersection among all of them, this class 
00065    * provides a good solution.  If you have one line that changes continously 
00066    * and want to compute the intersection with another changing line, the 
00067    * parent class can be even faster, due to the fact that the internal stage
00068    * do not need to be updated.
00069    *
00070    * @see tline<T>
00071    *
00072    * @ingroup gGeomData
00073    */
00074   template <class T>
00075   class tfastLine : public tline<T> {
00076   protected:
00077     /**
00078      * @name dependent attributes
00079      *
00080      * These attributes depend on the start and end points and cannot be
00081      * considered as a normal state component of a line instance.  They can be
00082      * changed by "const" methods, which do not change the start and end
00083      * points.  Therefore, this attributes are all mutable.
00084      */
00085     //@{
00086     /**
00087      * flag indicating state of the slope
00088      */
00089     mutable bool uptodate;
00090 
00091     /**
00092      * delta
00093      */
00094     mutable tpoint<T> delta;
00095 
00096     /**
00097      * flag indicating if the stored value is slope (false)  or 1/slope (true)
00098      */
00099     mutable bool invSlope;
00100 
00101     /**
00102      * value of the slope: always between -1 and 1.
00103      */
00104     mutable float normSlope;
00105 
00106     //@}
00107 
00108     /**
00109      * Method called if a change in the points have been done.
00110      *
00111      * This policy does nothing here.
00112      */
00113     inline void updateRequest();
00114     
00115     /**
00116      * const method called when slope and other attributes need to be
00117      * updated.
00118      */
00119     inline void ensureCorrectSlope() const;
00120 
00121   public:
00122     /**
00123      * default constructor.
00124      *
00125      * Both points are left uninitialized (this can save some time)
00126      */
00127     explicit tfastLine();
00128     
00129     /**
00130      * constructor with both points
00131      */
00132     tfastLine(const tpoint<T>& theStart, const tpoint<T>& theEnd);
00133     
00134     /**
00135      * copy constructor
00136      */
00137     template <class U> 
00138     tfastLine(const tfastLine<U>& other) 
00139       : tline<T>(other),uptodate(other.uptodate),delta(other.delta),
00140         invSlope(other.invSlope),normSlope(other.normSlope) {
00141     };
00142 
00143     /**
00144      * copy constructor
00145      */
00146     template <class U> 
00147     tfastLine(const tline<U>& other) 
00148       : tline<T>(other),uptodate(false) {
00149     };
00150 
00151     /**
00152      * cast operator
00153      */
00154     template <class U>
00155     tfastLine<T>& castFrom(const tfastLine<U>& other) {
00156       tline<T>::castFrom(other);
00157       updateRequest();
00158       return (*this);
00159     };
00160 
00161     /**
00162      * general operator to set both points of the line
00163      */
00164     inline void set(const tpoint<T>& theStart,const tpoint<T>& theEnd);
00165 
00166     /**
00167      * set the start point. 
00168      */
00169     inline void setStart(const tpoint<T>& theStart);
00170 
00171     /**
00172      * set the end point. Does not compute the slope.
00173      */
00174     inline void setEnd(const tpoint<T>& theEnd);
00175 
00176     /**
00177      * exchange the start and end points, making the previous end a
00178      * start point and the previous start the end point.
00179      */
00180     inline void invert();
00181     
00182     /**
00183      * @name Computation of line attributes
00184      */
00185     //@{
00186     /**
00187      * Update slope can be called to force update of the internal variables
00188      * containing the line attributes (for example, at a not critical
00189      * computation time you will want to call this.)
00190      */
00191     inline void updateSlope();
00192 
00193     /**
00194      * returns a point containing getEnd() - getStart().
00195      */
00196     inline const tpoint<T>& getDelta() const;
00197 
00198     /**
00199      * Get slope of the line ensuring that its absolute value is
00200      * between -1 and 1.  
00201      *
00202      * Let delta=getDelta():
00203      *
00204      * - If the returned boolean is \c true, the \a slope variable will
00205      *   contain usual slope (delta.y/delta.x).
00206      * - If the returned boolean is false, it means that the inverse of the
00207      *   slope has being set in \a slope (delta.x/delta.y).
00208      *
00209      * This way, there is no risk to become an infinite slope.
00210      */
00211     inline bool getNormalizedSlope(float& slope) const;
00212 
00213     /**
00214      * To avoid extra computations, this method allows you to get
00215      * three line attributes at once: 
00216      * @param deltaLine corresponds to end-start.
00217      * @param nslope normalized slope, always in interval -1 to 1.  
00218      * @param normalSlope if true, \a nslope contains the usual definition
00219      *                     of slope (deltaLine.y/deltaLine.x), if false,
00220      *                     \a nslope contains (deltaLine.x/deltaLine.y)
00221      */
00222     inline void getLineAttributes(tpoint<T>& deltaLine,
00223                                   float& nslope,
00224                                   bool&  normalSlope) const;
00225 
00226 
00227 
00228     //@}
00229 
00230     /**
00231      * @name Distance computation
00232      */
00233     //@{
00234 
00235     /**
00236      * Calculate %square of distance to the point c to the infinite
00237      * line (eXtraPolated) containing this line segment.
00238      *
00239      * @param c point to which the minimal distance is searched.
00240      * @param p point in the extrapolated line segment with the
00241      *          minimal distance to c.
00242      *
00243      * This method is faster than distanceToXPol (because it does not
00244      * calculate the square root).
00245      *
00246      * If not update of state (slope, delta and so on) is required, this
00247      * method is about 12\% faster than the normal one (in tline<T>).
00248      * If an update is required, the opposite happens, and this method is
00249      * about 10\% slower than the tline<T> one.
00250      *
00251      * @see sqrDistanceTo()
00252      */
00253     T distanceSqrXPol(const tpoint<T>& c,tpoint<T>& p) const;
00254 
00255     /**
00256      * Calculate distance to the point c to the infinite line (eXtraPolated)
00257      * containing this line segment.
00258      *
00259      * @return the minimal distance to c
00260      */
00261     inline T distanceToXPol(const tpoint<T>& c,tpoint<T>& p) const;
00262 
00263     /**
00264      * Calculate %square of distance to the point c to the infinite
00265      * line (eXtraPolated) containing this line segment.
00266      *
00267      * @param c point to which the minimal distance is searched.
00268      *
00269      * @return the square of the minimal distance to c
00270      * @see sqrDistanceTo()
00271      *
00272      * This method is faster than distanceToXPol (because it does not
00273      * calculate the square root).
00274      */
00275     T distanceSqrXPol(const tpoint<T>& c) const;
00276 
00277     /**
00278      * Calculate distance to the point c to the infinite line (eXtraPolated)
00279      * containing this line segment.
00280      *
00281      * @return the minimal distance to c
00282      */
00283     inline T distanceToXPol(const tpoint<T>& c) const;
00284 
00285     //@}
00286   
00287     /**
00288      * @name Intersections
00289      */
00290     //@{ 
00291 
00292     /**
00293      * Check if this line segment intersects the \a other given one.
00294      *
00295      * @param other the other line segment to which an intersection is
00296      *              going to be checked.
00297      * @return true if both line segments intersect.
00298      */
00299     bool doIntersect(const tfastLine<T>& other) const;
00300 
00301     /**
00302      * Check if this line segment intersects the \a other given one.
00303      *
00304      * @param other the other line segment to which an intersection is
00305      *              going to be checked.
00306      * @param p     if there is an intersection between both line segments
00307      *              or between their respective infinite line extrapolations,
00308      *              the intersection point will be written here.
00309      * @param onThisLine if the intersection occurs on a point on the line
00310      *              segment, this parameter will be set to true.  Otherwise
00311      *              false.
00312      * @param onOtherLine if the intersection occurs on a point on the other
00313      *              line segment, this parameter will be set to true.
00314      * @param colinear this parameter is set to true in case both line segments
00315      *              are parallel and co-linear.
00316      *
00317      * @return true if both line segments intersect, i.e. this method
00318      *              returns \c true if the intersection of both infinite
00319      *              extrapolations lay within both line segments (\a onThisLine
00320      *              and \a onOtherLine are both set to \c true).  It returns 
00321      *              \c false otherwise.  Note that even if the return value is
00322      *              \c false, the value of the point \a p is updated to the
00323      *              proper intersection of the two infinite lines containing
00324      *              the segments.  If both line segments are parallel and
00325      *              colinear, this method returns \c true only if both segments
00326      *              overlap.
00327      *            
00328      *
00329      * For parallel line segments following values can be therefore expected:
00330      * - Parallel but not colinear: return false and \a colinear is false.
00331      * - Parallel and colinear: return \c true if both segments overlap, 
00332      *            \c false otherwise.  \a colinear is set to \c true.
00333      *
00334      * In case the lines are parallel (colinear or not) the point \a p
00335      * is leaved unchaged, because the intersection occurs at none or
00336      * more than one points.
00337      *
00338      * This method is for updated slope values about 25% faster than the
00339      * normal tline method.  When one of the lines needs update
00340      * both methods need almost the same time.
00341      */
00342     bool getIntersectionPointXPol(const tfastLine<T>& other, 
00343           //bool intersect(const tfastLine<T>& other, 
00344                    tpoint<T>& p, 
00345                    bool& onThisLine, 
00346                    bool& onOtherLine,
00347                    bool& colinear) const;
00348 
00349     /**
00350      * Compute the part of this line segment which lies within the
00351      * given rectangle, and leave the result here.
00352      *
00353      * This method assumes, the rectangle is already consistent, i.e.
00354      * the \a rect.ul point is in both coordinates smaller than \a rect.br.
00355      *
00356      * @return true if part of this line lies within the rectangle or its
00357      *              border, false otherwise.
00358      */
00359     bool intersect(const trectangle<T>& rect);
00360 
00361     /**
00362      * Compute the part of the \a other line segment which lies within the
00363      * given rectangle, and leave the result here.
00364      *
00365      * This method assumes, the rectangle is already consistent, i.e.
00366      * the \a rect.ul point is in both coordinates smaller than \a rect.br.
00367      *
00368      * @return true if part of this line lies within the rectangle or its
00369      *              border, false otherwise.
00370      */
00371     inline bool intersect(const tfastLine<T>& other,
00372                           const trectangle<T>& rect);
00373 
00374 
00375     /**
00376      * Compute the part of the infinite extrapolated line containing this line
00377      * segment which lies within the given rectangle, and leave the result
00378      * here.
00379      *
00380      * This method assumes, the rectangle is already consistent, i.e.
00381      * the \a rect.ul point is in both coordinates smaller than \a rect.br.
00382      *
00383      * @return true if part of this line lies within the rectangle or its
00384      *              border, false otherwise.
00385      */
00386     bool intersectXPol(const trectangle<T>& rect);
00387 
00388     /**
00389      * Compute the part of the infinite extrapolated line containing the \a
00390      * other line segment which lies within the given rectangle, and leave the
00391      * result here.
00392      *
00393      * This method assumes, the rectangle is already consistent, i.e.
00394      * the \a rect.ul point is in both coordinates smaller than \a rect.br.
00395      *
00396      * @return true if part of this line lies within the rectangle or its
00397      *              border, false otherwise.
00398      */
00399     inline bool intersectXPol(const tfastLine<T>& other,
00400                               const trectangle<T>& rect);
00401 
00402     /**
00403      * @name Scaling and Translation operations
00404      */
00405     //@{
00406     
00407     /**
00408      * scale this line by the given \a c factor.
00409      */
00410     template<class U>
00411     inline tfastLine<T>& scale(const U c) {
00412       this->start.multiply(c);
00413       this->end.multiply(c);
00414       updateRequest();
00415       return *this;
00416     };
00417 
00418     /**
00419      * create a new line equal this one scaled by the given \a c factor.
00420      */
00421     template<class U>
00422     inline tfastLine<T> operator*(const U c) const {
00423       return tfastLine<T>(this->start*c,this->end*c);
00424     };
00425 
00426     /**
00427      * scale this line by the given \a c factor.
00428      */
00429     template<class U>
00430     inline tfastLine<T>& operator*=(const U c) {
00431       return multiply(c);
00432     };
00433 
00434     /**
00435      * divide both points by the given \a c factor
00436      */
00437     template<class U>
00438     inline tfastLine<T>& divide(const U c) {
00439       this->start.divide(c);
00440       this->end.divide(c);
00441       updateRequest();
00442       return *this;      
00443     };
00444 
00445     /**
00446      * divide both points by the given \a c factor
00447      */
00448     template <class U>
00449     inline tfastLine<T> operator/(const U c) const {
00450       return tfastLine<T>(this->start/c,this->end/c);
00451     };
00452 
00453     /**
00454      * divide both points of tfastLine<T> by a given factor
00455      */
00456     template <class U>
00457     inline tfastLine<T>& operator/=(const U c) {
00458       return divide(c);  
00459     };
00460 
00461     /**
00462      * add given point to both ends of this line and leave the result here.
00463      * @param p the other line to be added to this one
00464      * @return a reference to this line
00465      */
00466     inline tfastLine<T>& translate(const tpoint<T>& p);
00467 
00468     /**
00469      * add given point to both ends of the \a other line and leave the
00470      * result here.  
00471      * @param other the other line to be tranlated
00472      * @param p the translation factor
00473      * @return a reference to this line
00474      */
00475     inline tfastLine<T>& translate(const tline<T>& other,
00476                                    const tpoint<T>& p);
00477 
00478     //@}
00479 
00480     /**
00481      * copy operator
00482      */
00483     inline tfastLine<T>& copy(const tline<T>& other);
00484 
00485     /**
00486      * copy operator
00487      */
00488     inline tfastLine<T>& copy(const tfastLine<T>& other);
00489 
00490     /**
00491      * operator =
00492      */
00493     inline tfastLine<T>& operator=(const tfastLine<T>& other);
00494 
00495     /**
00496      * operator =
00497      */
00498     inline tfastLine<T>& operator=(const tline<T>& other);
00499   };
00500 
00501 
00502   // ----------------------------------------------------------------------
00503   // Type definitions
00504   // ----------------------------------------------------------------------
00505 
00506   /**
00507    * A line with integer coordinates
00508    */
00509   typedef tfastLine<int> fastLine;
00510 
00511   /**
00512    * A line with double coordinates
00513    */
00514   typedef tfastLine<double> dfastLine;
00515 
00516   /**
00517    * A line with float coordinates
00518    */
00519   typedef tfastLine<float> ffastLine;
00520 
00521   // ---------------------------------------------------
00522   // Storable interface
00523   // ---------------------------------------------------
00524 
00525   /**
00526    * read the vector from the given ioHandler. The complete flag indicates
00527    * if the enclosing begin and end should be also be read
00528    *
00529    * @ingroup gStorable
00530    */
00531   template <class T>
00532   bool read(ioHandler& handler,tfastLine<T>& l, const bool complete=true);
00533   
00534 
00535 } // namespace lti
00536 
00537 namespace std {
00538   
00539   template <class T>
00540   istream& operator>>(istream& s,lti::tfastLine<T>& l);
00541 
00542 } // namespace std
00543 
00544 // implementation of inline methods
00545 #include "ltiFastLine_inline.h"
00546 
00547 #endif

Generated on Sat Apr 10 15:25:28 2010 for LTI-Lib by Doxygen 1.6.1