CVR-Lib last update 20 Sep 2009

cvrLine.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1998
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  *
00006  * This file is part of the Computer Vision and Robotics Library (CVR-Lib)
00007  *
00008  * The CVR-Lib is free software; you can redistribute it and/or
00009  * modify it under the terms of the BSD License.
00010  *
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  *
00019  * 2. Redistributions in binary form must reproduce the above copyright notice,
00020  *    this list of conditions and the following disclaimer in the documentation
00021  *    and/or other materials provided with the distribution.
00022  *
00023  * 3. Neither the name of the authors nor the names of its contributors may be
00024  *    used to endorse or promote products derived from this software without
00025  *    specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00028  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00033  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00035  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00036  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00037  * POSSIBILITY OF SUCH DAMAGE.
00038  */
00039 
00040 
00041 
00042 /**
00043  * \file   cvrLine.h
00044  * \author Claudia Goenner
00045  * \date   07.02.2003
00046  *
00047  * $Id: cvrLine.h,v 1.3 2005/07/09 04:26:30 alvarado Exp $
00048  */
00049 
00050 #ifndef _CVR_LINE_H_
00051 #define _CVR_LINE_H_
00052 
00053 #include "cvrConfig.h"
00054 
00055 #include <iostream>
00056 #include <limits>
00057 
00058 #include "cvrIoHandler.h"
00059 #include "cvrMath.h"
00060 #include "cvrPoint.h"
00061 #include "cvrRectangle.h"
00062 
00063 namespace cvr {
00064 
00065 
00066   /**
00067    * Type for computations with lines.
00068    *
00069    * A line (or more generally a line<T>) is represented by a start point
00070    * and an end point.
00071    *
00072    * The type T correspond to the coordinate type used in both points.
00073    *
00074    * This class stores only the two points, and provides some functionality
00075    * using them.  Other operations can be achieved more efficiently if more
00076    * information about the line, like its slope, is also stored.  This is
00077    * done by some derived classes.
00078    *
00079    * @ingroup gGeomData
00080    */
00081   template <class T>
00082   class line {
00083   protected:
00084     /**
00085      * start point
00086      */
00087     point<T> start;
00088 
00089     /**
00090      * end point
00091      */
00092     point<T> end;
00093 
00094   public:
00095     /**
00096      * default constructor.
00097      *
00098      * Both points are left uninitialized (this can save some time)
00099      */
00100     explicit line();
00101 
00102     /**
00103      * constructor with both points
00104      */
00105     line(const point<T>& theStart, const point<T>& theEnd);
00106 
00107     /**
00108      * copy constructor
00109      */
00110     template <class U>
00111     inline line(const line<U>& other);
00112 
00113     /**
00114      * cast operator
00115      */
00116     template <class U>
00117     inline line<T>& castFrom(const line<U>& other);
00118 
00119     /**
00120      * general operator to set both points of the line
00121      */
00122     inline void set(const point<T>& theStart,const point<T>& theEnd);
00123 
00124     /**
00125      * set the start point.
00126      */
00127     inline void setStart(const point<T>& theStart);
00128 
00129     /**
00130      * set the end point. Does not compute the slope.
00131      */
00132     inline void setEnd(const point<T>& theEnd);
00133 
00134     /**
00135      * exchange the start and end points, making the previous end a
00136      * start point and the previous start the end point.
00137      */
00138     inline void invert();
00139 
00140     /**
00141      * return a read only reference to the start point
00142      */
00143     inline const point<T>& getStart() const;
00144 
00145     /**
00146      * return a read only reference to the end point
00147      */
00148     inline const point<T>& getEnd() const;
00149 
00150     /**
00151      * @name Distance computation
00152      */
00153     //@{
00154     /**
00155      * calculate minimal euclidian distance of the line segment to the point c.
00156      *
00157      * This method is slower than the sqrDistanceTo, which avoids the
00158      * computation of a (in many cases not required) square root.
00159      *
00160      * @see sqrDistanceTo() distanceToXPol()
00161      */
00162     inline T distanceTo(const point<T>& c) const;
00163 
00164     /**
00165      * Calculate minimal %square of euclidian distance to the point c. This
00166      * method is faster than distanceTo (because it does not calculate
00167      * the square root).
00168      *
00169      * @param c point to which the minimal distance is searched.
00170      * @return the square of the minimal distance to c
00171      */
00172     inline T distanceSqr(const point<T>& c) const;
00173 
00174     /**
00175      * Calculate minimal %square of euclidian distance to the point c. This
00176      * method is faster than distanceTo (because it does not calculate
00177      * the square root).
00178      *
00179      * @param c point to which the minimal distance is searched.
00180      * @param p point in the line segment with the minimal distance to c.
00181      *
00182      * @return the square of the minimal distance to c
00183      */
00184     T distanceSqr(const point<T>& c,point<T>& p) const;
00185 
00186     /**
00187      * Calculate distance to the point c to the infinite line (eXtraPolated)
00188      * containing this line segment.
00189      *
00190      * @return the minimal distance to c
00191      */
00192     inline T distanceToXPol(const point<T>& c) const;
00193 
00194     /**
00195      * Calculate %square of distance to the point c to the infinite
00196      * line (eXtraPolated) containing this line segment.
00197      *
00198      * @param c point to which the minimal distance is searched.
00199      *
00200      * @return the square of the minimal distance to c
00201      * @see sqrDistanceTo()
00202      *
00203      * This method is faster than distanceToXPol (because it does not
00204      * calculate the square root).
00205      */
00206     inline T distanceSqrXPol(const point<T>& c) const;
00207 
00208     /**
00209      * Calculate %square of distance to the point c to the infinite
00210      * line (eXtraPolated) containing this line segment.
00211      *
00212      * @param c point to which the minimal distance is searched.
00213      * @param p point in the extrapolated line segment with the
00214      *          minimal distance to c.
00215      *
00216      * This method is faster than distanceToXPol (because it does not
00217      * calculate the square root).
00218      *
00219      *
00220      * @see sqrDistanceTo()
00221      */
00222     T distanceSqrXPol(const point<T>& c,point<T>& p) const;
00223 
00224     /**
00225      * square of the length of this line
00226      */
00227     inline T sqrLength() const;
00228     //@}
00229 
00230     /**
00231      * @name Intersections
00232      */
00233     //@{
00234 
00235     /**
00236      * Check if this line segment intersects the \a other given one.
00237      *
00238      * @param other the other line segment to which an intersection is
00239      *              going to be checked.
00240      * @return true if both line segments intersect.
00241      */
00242     bool doesIntersect(const line<T>& other) const;
00243 
00244     /**
00245      * Check if this line segment is parallel to the \a other given one.
00246      *
00247      * @param other the other line segment to which parallelism is
00248      *              going to be checked.
00249      * @return true if both line segments are parallel.
00250      */
00251     bool isParallel(const line<T>& other) const;
00252 
00253     /**
00254      * Check if this line segment is parallel and colinear to the
00255      * \a other given one.
00256      *
00257      * @param other the other line segment to which parallelism is
00258      *              going to be checked.
00259      * @return true if both line segments are parallel.
00260      */
00261     bool isColinear(const line<T>& other) const;
00262 
00263     /**
00264      * Compute the part of this line segment which lies within the
00265      * given rectangle, and leave the result here.
00266      *
00267      * This method assumes, the rectangle is already consistent, i.e.
00268      * the \a rect.ul point is in both coordinates smaller than \a rect.br.
00269      *
00270      * @return true if part of this line lies within the rectangle or its
00271      *              border, false otherwise.
00272      */
00273     bool intersect(const rectangle<T>& rect);
00274 
00275     /**
00276      * Compute the part of the \a other line segment which lies within the
00277      * given rectangle, and leave the result here.
00278      *
00279      * This method assumes, the rectangle is already consistent, i.e.
00280      * the \a rect.ul point is in both coordinates smaller than \a rect.br.
00281      *
00282      * @return true if part of this line lies within the rectangle or its
00283      *              border, false otherwise.
00284      */
00285     inline bool intersect(const line<T>& other,
00286         const rectangle<T>& rect);
00287 
00288     /**
00289      * Compute the intersection point of this line segment with the
00290      * \a other given one.
00291      *
00292      * @param other the other line segment to which the intersection point
00293      *              is going to be computed.
00294      * @param p     if there is an intersection between both line segments
00295      *              the intersection point will be written here.
00296      * @param colinear this parameter is set to true in case both line segments
00297      *              are parallel and co-linear.
00298      *
00299      * @return true if an unique intersection point exists. It returns
00300      *              \c false otherwise. If both line segments are parallel and
00301      *              colinear, this method returns \c true and determines the
00302      *              intersection if the intersection is inifinitely small.
00303      *
00304      * This method can be overloaded in derived classes and other information
00305      * to accellerate the computations.
00306      */
00307     template<class U>
00308     bool getIntersectionPoint(const line<T>& other, point<U>& p,
00309             bool& colinear) const;
00310 
00311     /**
00312      * Compute the common line segment between this line segment and the
00313      * \a other given one and leave the result here. This intersection is only
00314      * going to be computed if both lines are colinear.
00315      *
00316      * @param other the other line segment to which the intersection
00317      *              is going to be computed.
00318      *
00319      * @return true if an common line segment exists. It returns
00320      *              \c false otherwise. If both line segments are parallel and
00321      *              colinear, this method returns \c true and determines the
00322      *              line segment even if it is inifinitely small, i.e. a point.
00323      *
00324      * This method can be overloaded in derived classes and other information
00325      * to accellerate the computations.
00326      */
00327     bool getCommonLine(const line<T>& other);
00328 
00329     /**
00330      * Compute the common line segment between the given line
00331      * segments.  This intersection is only going to be computed if
00332      * both lines are colinear.
00333      *
00334      * @param first first line segment.
00335      * @param second second line segment.
00336      *
00337      * @return true if a common line segment exists. It returns
00338      *              \c false otherwise. If both line segments are parallel and
00339      *              colinear, this method returns \c true and determines the
00340      *              line segment even if it is inifinitely small, i.e. a point.
00341      *
00342      * The common line segment will be left in this instance.
00343      *
00344      * This method can be overloaded in derived classes and other information
00345      * to accellerate the computations.
00346      */
00347     inline bool getCommonLine(const line<T>& first, const line<T>& second);
00348 
00349     /**
00350      * Check if this infinitely extrapolated line intersects the \a other given
00351      * infinite line at a single finite point.
00352      *
00353      * @param other the other line segment to which an intersection is
00354      *              going to be checked.
00355      *
00356      * @return true if both inifinite lines intersect at a single finite point.
00357      *
00358      * This method can be overloaded in derived classes and other information
00359      * to accellerate the computations.
00360      */
00361     bool doesPointIntersectXPol(const line<T>& other) const;
00362 
00363     /**
00364      * Compute the intersection point of this infinitely extrapolated line with the
00365      * \a other given infinite line.
00366      *
00367      * @param other the other line segment to which the intersection point
00368      *              is going to be computed.
00369      * @param p     if there is an intersection between both line segments
00370      *              or between their respective infinite line extrapolations,
00371      *              the intersection point will be written here.
00372      * @param onThisLine if the intersection occurs at a point on the line
00373      *              segment, this parameter will be set to true.  Otherwise
00374      *              false.
00375      * @param onOtherLine if the intersection occurs at a point on the other
00376      *              line segment, this parameter will be set to true.
00377      * @param colinear this parameter is set to true in case both line segments
00378      *              are parallel and co-linear.
00379      *
00380      * @return true if an unique intersection point exists. It returns
00381      *              \c false otherwise. If both line segments are parallel and
00382      *              colinear, this method returns \c false.
00383      *
00384      * This method can be overloaded in derived classes and other information
00385      * to accellerate the computations.
00386      */
00387     template<class U>
00388     bool getIntersectionPointXPol(const line<T>& other, point<U>& p,
00389           bool& onThisLine, bool& onOtherLine,
00390           bool& colinear) const;
00391 
00392     /**
00393      * Compute the intersection point of this infinitely extrapolated line with the
00394      * \a other given infinite line.
00395      *
00396      * @param other the other line segment to which the intersection point
00397      *              is going to be computed.
00398      * @param p     if there is an intersection between both line segments
00399      *              or between their respective infinite line extrapolations,
00400      *              the intersection point will be written here.
00401      *
00402      * @return true if an unique intersection point exists. It returns
00403      *              \c false otherwise.
00404      *
00405      * This method can be overloaded in derived classes and other information
00406      * to accellerate the computations.
00407      */
00408     template<class U>
00409     bool getIntersectionPointXPol(const line<T>& other, point<U>& p) const;
00410 
00411     /**
00412      * Compute the part of the infinite extrapolated line containing this line
00413      * segment which lies within the given rectangle, and leave the result
00414      * here.
00415      *
00416      * This method assumes, the rectangle is already consistent, i.e.
00417      * the \a rect.ul point is in both coordinates smaller than \a rect.br.
00418      *
00419      * @return true if part of this line lies within the rectangle or its
00420      *              border, false otherwise.
00421      */
00422     bool intersectXPol(const rectangle<T>& rect);
00423 
00424     /**
00425      * Compute the part of the infinite extrapolated line containing the \a
00426      * other line segment which lies within the given rectangle, and leave the
00427      * result here.
00428      *
00429      * This method assumes, the rectangle is already consistent, i.e.
00430      * the \a rect.ul point is in both coordinates smaller than \a rect.br.
00431      *
00432      * @return true if part of this line lies within the rectangle or its
00433      *              border, false otherwise.
00434      */
00435     inline bool intersectXPol(const line<T>& other,
00436                               const rectangle<T>& rect);
00437     //@}
00438 
00439     /**
00440      * @name Scaling and Translation operations
00441      */
00442     //@{
00443 
00444     /**
00445      * scale this line by the given \a c factor.
00446      */
00447     template<class U>
00448     inline line<T>& scale(const U c);
00449 
00450     /**
00451      * create a new line equal this one scaled by the given \a c factor.
00452      */
00453     template<class U>
00454     inline line<T> operator*(const U c) const;
00455 
00456     /**
00457      * scale this line by the given \a c factor.
00458      */
00459     template<class U>
00460     inline line<T>& operator*=(const U c);
00461 
00462     /**
00463      * divide both points by the given \a c factor
00464      */
00465     template<class U>
00466     inline line<T>& divide(const U c);
00467 
00468     /**
00469      * divide both points by the given \a c factor
00470      */
00471     template <class U>
00472     inline line<T> operator/(const U c) const;
00473 
00474     /**
00475      * divide both points of line<T> by a given factor
00476      */
00477     template <class U>
00478     inline line<T>& operator/=(const U c);
00479 
00480     /**
00481      * add given point to both ends of this line and leave the result here.
00482      * @param p the other line to be added to this one
00483      * @return a reference to this line
00484      */
00485     inline line<T>& translate(const point<T>& p);
00486 
00487     /**
00488      * add given point to both ends of the \a other line and leave the
00489      * result here.
00490      * @param other the other line to be tranlated
00491      * @param p the translation factor
00492      * @return a reference to this line
00493      */
00494     inline line<T>& translate(const line<T>& other,const point<T>& p);
00495 
00496     /**
00497      * Compute the orthogonal line and leave the result here.
00498      *
00499      * @param offset the offset to the point on the line, where the orthogonal
00500      *               shall start. This parameter is scaled by the length of the line.
00501      * @return a reference to this line
00502      *
00503      * This method can be overloaded in derived classes and other information
00504      * to accellerate the computations.
00505      */
00506     line<T>& getOrthogonal(double offset);
00507 
00508     /**
00509      * Compute the orthogonal line to the other line and leave the result here.
00510      *
00511      * @param other  the line segment of which the orthogonal line
00512      *               is going to be computed.
00513      * @param offset the offset to the point on the line, where the orthogonal
00514      *               shall start. This parameter is scaled by the length of the line.
00515      * @return a reference to this line
00516      *
00517      * This method can be overloaded in derived classes and other information
00518      * to accellerate the computations.
00519      */
00520     inline line<T>& getOrthogonal(const line<T>& other, double offset);
00521 
00522     //@}
00523 
00524     /**
00525      * copy operator
00526      */
00527     inline line<T>& copy(const line<T>& other);
00528 
00529     /**
00530      * operator =
00531      */
00532     inline line<T>& operator=(const line<T>& other) {return copy(other);};
00533 
00534     /**
00535      * operator ==
00536      */
00537     inline bool operator==(const line<T>& other) const;
00538 
00539     /**
00540      * operator !=
00541      */
00542     inline bool operator!=(const line<T>& other) const;
00543   };
00544 
00545 
00546   // ----------------------------------------------------------------------
00547   // Type definitions
00548   // ----------------------------------------------------------------------
00549 
00550   /**
00551    * A line with integer coordinates
00552    */
00553   typedef line<int> iline;
00554 
00555   /**
00556    * A line with double coordinates
00557    */
00558   typedef line<double> dline;
00559 
00560   /**
00561    * A line with float coordinates
00562    */
00563   typedef line<float> fline;
00564 
00565   // ---------------------------------------------------
00566   // Storable interface
00567   // ---------------------------------------------------
00568 
00569   /**
00570    * read the vector from the given ioHandler. The complete flag indicates
00571    * if the enclosing begin and end should be also be read
00572    *
00573    * @ingroup gStorable
00574    */
00575   template <class T>
00576   bool read(ioHandler& handler,line<T>& l, const bool complete=true);
00577 
00578   /**
00579    * write the vector in the given ioHandler. The complete flag indicates
00580    * if the enclosing begin and end should be also be written or not
00581    *
00582    * @ingroup gStorable
00583    */
00584   template<class T>
00585   bool write(ioHandler& handler,const line<T>& l,const bool complete=true);
00586 
00587 } // namespace cvr
00588 
00589 namespace std {
00590 
00591   template <class T>
00592   ostream& operator<<(ostream& s,const cvr::line<T>& l);
00593 
00594   template <class T>
00595   istream& operator>>(istream& s,cvr::line<T>& l);
00596 
00597 } // namespace std
00598 
00599 // implementation of inline methods
00600 #include "cvrLine_inline.h"
00601 
00602 #endif

Generated on Sun Sep 20 22:07:59 2009 for CVR-Lib by Doxygen 1.5.8