last update 20 Sep 2009 |
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