latest version v1.9 - last update 10 Apr 2010 |
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