00001 /*---------------------------------------------------------------------+ 00002 | Library QgarLib, graphics analysis and recognition | 00003 | Copyright (C) 2002 Qgar Project, LORIA | 00004 | | 00005 | This library is free software; you can redistribute it and/or | 00006 | modify it under the terms of the GNU Lesser General Public | 00007 | License version 2.1, as published by the Free Software Foundation. | 00008 | | 00009 | This library is distributed in the hope that it will be useful, | 00010 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 00011 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 00012 | See the GNU Lesser General Public License for more details. | 00013 | | 00014 | The GNU Lesser General Public License is included in the file | 00015 | LICENSE.LGPL, in the root directory of the Qgar packaging. See | 00016 | http://www.gnu.org/licenses/lgpl.html for the terms of the licence. | 00017 | To receive a paper copy, write to the Free Software Foundation, | 00018 | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | 00019 | | 00020 | Contact Project Qgar for any information: | 00021 | LORIA - équipe Qgar | 00022 | B.P. 239, 54506 Vandoeuvre-lès-Nancy Cedex, France | 00023 | email: qgar-contact@loria.fr | 00024 | http://www.qgar.org/ | 00025 *---------------------------------------------------------------------*/ 00026 00027 00028 /** 00029 * @file _QGAR_GenPoint.TCC 00030 * @brief Implementation of function members of class qgar::GenPoint. 00031 * 00032 * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a> 00033 * @date December 15, 2004 15:55 00034 * @since Qgar 2.2 00035 */ 00036 00037 00038 00039 // STL 00040 #include <algorithm> 00041 #include <cmath> 00042 #include <cctype> 00043 #include <iostream> 00044 // QGAR 00045 #include <qgarlib/ISerializable.H> 00046 00047 00048 00049 namespace qgar 00050 { 00051 00052 00053 // ------------------------------------------------------------------- 00054 // JUST A FAKE CLASS (NOT DEFINED) 00055 // TO BE USED TO CAUSE COMPILATION ERRORS WHEN SOME TEMPLATE FUNCTION 00056 // CANNOT BE INSTANTIATED USING ANY TYPE 00057 // ------------------------------------------------------------------- 00058 00059 00060 class TEMPLATE_FUNCTION_CANNOT_BE_INSTANTIATED_SEE_DOC; 00061 00062 00063 // ------------------------------------------------------------------- 00064 // C O N S T R U C T O R S 00065 // ------------------------------------------------------------------- 00066 00067 00068 // DEFAULT CONSTRUCTOR 00069 00070 template <class T> 00071 GenPoint<T>::GenPoint() 00072 00073 : _x(0), 00074 _y(0) 00075 00076 { 00077 // VOID 00078 } 00079 00080 00081 // COPY-CONSTRUCTOR 00082 00083 template <class T> 00084 GenPoint<T>::GenPoint(const GenPoint<T>& aPt) 00085 00086 : _x(aPt._x), 00087 _y(aPt._y) 00088 00089 { 00090 // VOID 00091 } 00092 00093 00094 // CONVERSION OF A POINT OF A TYPE DIFFERENT FROM THE EFFECTIVE TYPE 00095 00096 template <class T> 00097 template <class U> 00098 GenPoint<T>::GenPoint(const GenPoint<U>& aPt) 00099 00100 : _x(static_cast<T>(aPt.x())), 00101 _y(static_cast<T>(aPt.y())) 00102 00103 { 00104 // VOID 00105 } 00106 00107 00108 // INITIALIZE FROM COORDINATES 00109 00110 template <class T> 00111 GenPoint<T>::GenPoint(T aX, T aY) 00112 00113 : _x(aX), 00114 _y(aY) 00115 00116 { 00117 // VOID 00118 } 00119 00120 00121 // ------------------------------------------------------------------- 00122 // D E S T R U C T O R 00123 // ------------------------------------------------------------------- 00124 00125 00126 // NON-VIRTUAL DESTRUCTOR 00127 00128 template <class T> 00129 GenPoint<T>::~GenPoint() 00130 { 00131 // VOID 00132 } 00133 00134 00135 // ------------------------------------------------------------------- 00136 // A C C E S S T O C O O R D I N A T E S 00137 // ------------------------------------------------------------------- 00138 00139 00140 // GET X COORDINATE 00141 00142 template <class T> 00143 inline T 00144 GenPoint<T>::x() const 00145 { 00146 return _x; 00147 } 00148 00149 00150 // GET Y COORDINATE 00151 00152 template <class T> 00153 inline T 00154 GenPoint<T>::y() const 00155 { 00156 return _y; 00157 } 00158 00159 00160 // GET RADIUS (rho) IN POLAR COORDINATES 00161 00162 template <class T> 00163 inline double 00164 GenPoint<T>::rho() const 00165 { 00166 return hypot((double) _x, (double) _y); 00167 } 00168 00169 00170 // GET ANGLE (theta) IN POLAR COORDINATES 00171 00172 template <class T> 00173 inline double 00174 GenPoint<T>::theta() const 00175 { 00176 return atan2((double)_y, (double)_x); 00177 } 00178 00179 00180 // ------------------------------------------------------------------- 00181 // A S S I G N C O O R D I N A T E S 00182 // ------------------------------------------------------------------- 00183 00184 00185 // SET X COORDINATE 00186 00187 00188 template <class T> 00189 inline void 00190 GenPoint<T>::setX(T aX) 00191 { 00192 _x = aX; 00193 } 00194 00195 00196 // SET Y COORDINATE 00197 00198 template <class T> 00199 inline void 00200 GenPoint<T>::setY(T aY) 00201 { 00202 _y = aY; 00203 } 00204 00205 00206 // SET BOTH X AND Y COORDINATES 00207 00208 template <class T> 00209 inline void 00210 GenPoint<T>::setXY(T aX, T aY) 00211 { 00212 _x = aX; 00213 _y = aY; 00214 } 00215 00216 00217 // ------------------------------------------------------------------- 00218 // G E O M E T R Y : p r o j e c t i o n 00219 // ------------------------------------------------------------------- 00220 00221 00222 // ****************************************************** 00223 // ****************************************************** 00224 // WARNING: Functions applying to points with coordinates 00225 // of type other than double are not defined 00226 // ****************************************************** 00227 // ****************************************************** 00228 00229 00230 template <class T> 00231 inline void 00232 GenPoint<T>::project(const GenSegment<T>& aSeg) 00233 { 00234 TEMPLATE_FUNCTION_CANNOT_BE_INSTANTIATED_SEE_DOC(); 00235 } 00236 00237 00238 template <class T> 00239 inline void 00240 GenPoint<T>::project(const GenQgarSegment<T>& aQSeg) 00241 { 00242 TEMPLATE_FUNCTION_CANNOT_BE_INSTANTIATED_SEE_DOC(); 00243 } 00244 00245 00246 // ORTHOGONAL PROJECTION OF THE CURRENT POINT 00247 // ONTO THE LINE SUPPORTING A GIVEN SEGMENT 00248 00249 template <> 00250 inline void 00251 GenPoint<double>::project(const GenSegment<double>& aSeg) 00252 { 00253 qgProject(*this, aSeg); 00254 } 00255 00256 00257 // CASE OF A Qgar SEGMENT 00258 00259 template <> 00260 inline void 00261 GenPoint<double>::project(const GenQgarSegment<double>& aQSeg) 00262 { 00263 qgProject(*this, aQSeg); 00264 } 00265 00266 00267 // ------------------------------------------------------------------- 00268 // G E O M E T R Y : t r a n s l a t i o n 00269 // ------------------------------------------------------------------- 00270 00271 00272 // TRANSLATE ALONG X AND Y AXIS 00273 00274 template <class T> 00275 inline void 00276 GenPoint<T>::translate(T aTransX, T aTransY) 00277 { 00278 _x += aTransX; 00279 _y += aTransY; 00280 } 00281 00282 00283 // // ------------------------------------------------------------------- 00284 // // G E O M E T R Y : r o t a t i o n 00285 // // ------------------------------------------------------------------- 00286 00287 00288 // // ****************************************************** 00289 // // ****************************************************** 00290 // // WARNING: Functions applying to points with coordinates 00291 // // of type other than double are not defined 00292 // // ****************************************************** 00293 // // ****************************************************** 00294 00295 00296 // // ROTATE USING ORIGIN AS CENTER 00297 // // ============================= 00298 00299 00300 // template <class T> 00301 // void 00302 // GenPoint<T>::rotate(double anAngle) 00303 // { 00304 // TEMPLATE_FUNCTION_CANNOT_BE_INSTANTIATED_SEE_DOC(); 00305 // } 00306 00307 00308 // template <> 00309 // void 00310 // GenPoint<double>::rotate(double anAngle) 00311 // { 00312 // double cosA = cos(anAngle); 00313 // double sinA = sin(anAngle); 00314 // double tmpX = _x; 00315 00316 // _x = (tmpX * cosA) - (_y * sinA); 00317 // _y = (tmpX * sinA) + (_y * cosA); 00318 // } 00319 00320 00321 // // ROTATE USING A CENTER AND AN ANGLE 00322 // // ================================== 00323 00324 00325 // template <class T> 00326 // void 00327 // GenPoint<T>::rotate(double anAngle, const GenPoint<T>& aPt) 00328 // { 00329 // TEMPLATE_FUNCTION_CANNOT_BE_INSTANTIATED_SEE_DOC(); 00330 // } 00331 00332 00333 // template <> 00334 // void 00335 // GenPoint<double>::rotate(double anAngle, 00336 // const GenPoint<double>& aPt) 00337 // { 00338 // this->translate(-aPt.x(), -aPt.y()); 00339 // this->rotate(anAngle); 00340 // this->translate(aPt.x(), aPt.y()); 00341 // } 00342 00343 00344 // // ROTATE BY PI/2 USING ORIGIN AS CENTER 00345 // // ===================================== 00346 00347 00348 // template <class T> 00349 // void 00350 // GenPoint<T>::rotate90() 00351 // { 00352 // TEMPLATE_FUNCTION_CANNOT_BE_INSTANTIATED_SEE_DOC(); 00353 // } 00354 00355 00356 // template <> 00357 // void 00358 // GenPoint<double>::rotate90() 00359 // { 00360 // double tmpX = _x; 00361 00362 // _x = -_y; 00363 // _y = tmpX; 00364 // } 00365 00366 00367 // // ROTATE BY PI/2 USING A GIVEN CENTER 00368 // // =================================== 00369 00370 00371 // template <class T> 00372 // void 00373 // GenPoint<T>::rotate90(const GenPoint<T>& aPt) 00374 // { 00375 // TEMPLATE_FUNCTION_CANNOT_BE_INSTANTIATED_SEE_DOC(); 00376 // } 00377 00378 00379 // template <> 00380 // void 00381 // GenPoint<double>::rotate90(const GenPoint<double>& aPt) 00382 // { 00383 // double tmpX = _x; 00384 00385 // _x = (aPt.y() -_y) + aPt.x(); 00386 // _y = (tmpX - aPt.x()) + aPt.y(); 00387 // } 00388 00389 00390 // // ROTATE BY PI USING ORIGIN AS CENTER 00391 // // =================================== 00392 00393 // template <class T> 00394 // inline void 00395 // GenPoint<T>::rotate180() 00396 // { 00397 // TEMPLATE_FUNCTION_CANNOT_BE_INSTANTIATED_SEE_DOC(); 00398 // } 00399 00400 00401 // template <> 00402 // inline void 00403 // GenPoint<double>::rotate180() 00404 // { 00405 // this->symmetry(); 00406 // } 00407 00408 00409 // // ROTATE BY PI USING A GIVEN CENTER 00410 // // ================================= 00411 00412 // template <class T> 00413 // inline void 00414 // GenPoint<T>::rotate180(const GenPoint<T>& aPt) 00415 // { 00416 // TEMPLATE_FUNCTION_CANNOT_BE_INSTANTIATED_SEE_DOC(); 00417 // } 00418 00419 00420 // template <> 00421 // inline void 00422 // GenPoint<double>::rotate180(const GenPoint<double>& aPt) 00423 // { 00424 // this->symmetry(aPt); 00425 // } 00426 00427 00428 // // ROTATE BY 3*PI/2 USING ORIGIN AS ROTATION CENTER 00429 // // ================================================ 00430 00431 // template <class T> 00432 // void 00433 // GenPoint<T>::rotate270() 00434 // { 00435 // TEMPLATE_FUNCTION_CANNOT_BE_INSTANTIATED_SEE_DOC(); 00436 // } 00437 00438 00439 // template <> 00440 // void 00441 // GenPoint<double>::rotate270() 00442 // { 00443 // double tmpX = _x; 00444 00445 // _x = _y; 00446 // _y = -tmpX; 00447 // } 00448 00449 00450 // // ROTATE BY 3*PI/2 USING A GIVEN CENTER 00451 // // ===================================== 00452 00453 // template <class T> 00454 // void 00455 // GenPoint<T>::rotate270(const GenPoint<T>& aPt) 00456 // { 00457 // TEMPLATE_FUNCTION_CANNOT_BE_INSTANTIATED_SEE_DOC(); 00458 // } 00459 00460 00461 // template <> 00462 // void 00463 // GenPoint<double>::rotate270(const GenPoint<double>& aPt) 00464 // { 00465 // double tmpX = _x; 00466 00467 // _x = aPt.x() - aPt.y() + _y; 00468 // _y = aPt.x() + aPt.y() - tmpX; 00469 // } 00470 00471 00472 // // ------------------------------------------------------------------- 00473 // // G E O M E T R Y : h o m o t h e t y 00474 // // ------------------------------------------------------------------- 00475 00476 00477 // // ****************************************************** 00478 // // ****************************************************** 00479 // // WARNING: Functions applying to points with coordinates 00480 // // of type other than double are not defined 00481 // // ****************************************************** 00482 // // ****************************************************** 00483 00484 00485 // // HOMOTHETY USING GIVEN DILATION FACTOR AND THE ORIGIN AS CENTER 00486 // // ============================================================== 00487 00488 00489 // template <class T> 00490 // void 00491 // GenPoint<T>::homothety(double aDilFactor) 00492 // { 00493 // TEMPLATE_FUNCTION_CANNOT_BE_INSTANTIATED_SEE_DOC(); 00494 // } 00495 00496 00497 // template <> 00498 // void 00499 // GenPoint<double>::homothety(double aDilFactor) 00500 // { 00501 // _x = aDilFactor * _x; 00502 // _y = aDilFactor * _y; 00503 // } 00504 00505 00506 // // HOMOTHETY USING GIVEN DILATION FACTOR AND CENTER 00507 // // ================================================ 00508 00509 00510 // template <class T> 00511 // void 00512 // GenPoint<T>::homothety(double aDilFactor, 00513 // const GenPoint<T>& aPt) 00514 // { 00515 // TEMPLATE_FUNCTION_CANNOT_BE_INSTANTIATED_SEE_DOC(); 00516 // } 00517 00518 00519 // template <> 00520 // void 00521 // GenPoint<double>::homothety(double aDilFactor, 00522 // const GenPoint<double>& aPt) 00523 // { 00524 // _x = aPt.x() + aDilFactor * (_x - aPt.x()); 00525 // _y = aPt.y() + aDilFactor * (_y - aPt.y()); 00526 // } 00527 00528 00529 // // ------------------------------------------------------------------- 00530 // // G E O M E T R Y : s y m m e t r y 00531 // // ------------------------------------------------------------------- 00532 00533 00534 // // CENTRAL SYMMETRY USING THE ORIGIN AS CENTER 00535 // // =========================================== 00536 00537 00538 // template <class T> 00539 // void 00540 // GenPoint<T>::symmetry() 00541 // { 00542 // _x = -_x; 00543 // _y = -_y; 00544 // } 00545 00546 00547 // // CENTRAL SYMMETRY USING A GIVEN CENTER 00548 // // ===================================== 00549 00550 00551 // template <class T> 00552 // void 00553 // GenPoint<T>::symmetry(const GenPoint<T>& aPt) 00554 // { 00555 // _x = (2 * aPt.x()) - _x; 00556 // _y = (2 * aPt.y()) - _y; 00557 // } 00558 00559 00560 // // ****************************************************** 00561 // // ****************************************************** 00562 // // WARNING: Functions applying to points with coordinates 00563 // // of type other than double are not defined 00564 // // ****************************************************** 00565 // // ****************************************************** 00566 00567 00568 // // MIRROR SYMMETRY, USING THE LINE SUPPORTING THE GIVEN SEGMENT 00569 // // ============================================================ 00570 00571 00572 // class TEMPLATE_FUNCTION_CANNOT_BE_INSTANTIATED_SEE_DOC; 00573 00574 // template <class T> 00575 // void 00576 // GenPoint<T>::symmetry(const GenSegment<T>& aSeg) 00577 // { 00578 // TEMPLATE_FUNCTION_CANNOT_BE_INSTANTIATED_SEE_DOC(); 00579 // } 00580 00581 00582 // template <> 00583 // void 00584 // GenPoint<double>::symmetry(const GenSegment<double>& aSeg) 00585 // { 00586 // // Project a copy of the current segment onto the given line 00587 // GenPoint<double> p(*this); 00588 // p.project(aSeg); 00589 00590 // // Use the projection as symmetry center 00591 // this->symmetry(p); 00592 // } 00593 00594 00595 // ------------------------------------------------------------------- 00596 // O P E R A T O R S 00597 // ------------------------------------------------------------------- 00598 00599 00600 // ASSIGNMENT 00601 00602 template <class T> 00603 GenPoint<T>& 00604 GenPoint<T>::operator=(const GenPoint<T>& aPt) 00605 { 00606 // ___________________________________________________________ 00607 // 00608 // TEST DISABLED FOR MORE EFFICIENCY 00609 // ___________________________________________________________ 00610 // 00611 // Are left hand side and right hand side different objects? 00612 // if (this != &aPt) 00613 // { 00614 // ___________________________________________________________ 00615 00616 _x = aPt._x; 00617 _y = aPt._y; 00618 00619 // ___________________________________________________________ 00620 // 00621 // } 00622 // ___________________________________________________________ 00623 00624 return *this; 00625 } 00626 00627 00628 // SAME AS FUNCTION qgar::GenPoint::plus 00629 00630 template <class T> 00631 inline const GenPoint<T> 00632 GenPoint<T>::operator+(const GenPoint<T>& aPt) const 00633 { 00634 return plus(aPt); 00635 } 00636 00637 00638 // SAME AS FUNCTION qgar::GenPoint::plusEqual 00639 00640 template <class T> 00641 inline GenPoint<T>& 00642 GenPoint<T>::operator+=(const GenPoint<T>& aPt) 00643 { 00644 return plusEqual(aPt); 00645 } 00646 00647 00648 // SAME AS FUNCTION qgar::GenPoint::minus 00649 00650 template <class T> 00651 inline const GenPoint<T> 00652 GenPoint<T>::operator-(const GenPoint<T>& aPt) const 00653 { 00654 return minus(aPt); 00655 } 00656 00657 00658 // SAME AS FUNCTION qgar::GenPoint::minusEqual 00659 00660 template <class T> 00661 inline GenPoint<T>& 00662 GenPoint<T>::operator-=(const GenPoint<T>& aPt) 00663 { 00664 return minusEqual(aPt); 00665 } 00666 00667 00668 // SAME AS FUNCTION qgar::GenPoint::eq 00669 00670 template <class T> 00671 inline bool 00672 GenPoint<T>::operator==(const GenPoint<T>& aPt) const 00673 { 00674 return eq(aPt); 00675 } 00676 00677 00678 // SAME AS FUNCTION qgar::GenPoint::notEq 00679 00680 template <class T> 00681 inline bool 00682 GenPoint<T>::operator!=(const GenPoint<T>& aPt) const 00683 { 00684 return notEq(aPt); 00685 } 00686 00687 00688 // ------------------------------------------------------------------- 00689 // F U N C T I O N A L O P E R A T O R S 00690 // ------------------------------------------------------------------- 00691 00692 00693 // ADD COORDINATES OF THE GIVEN POINT TO THOSE 00694 // OF THE CURRENT POINT, AND RETURN THEM AS A NEW POINT 00695 00696 template <class T> 00697 const GenPoint<T> 00698 GenPoint<T>::plus(const GenPoint<T>& aPt) const 00699 { 00700 return GenPoint(*this).plusEqual(aPt); 00701 } 00702 00703 00704 // ADD COORDINATES OF THE GIVEN POINT TO THOSE OF THE CURRENT POINT 00705 00706 template <class T> 00707 GenPoint<T>& 00708 GenPoint<T>::plusEqual(const GenPoint<T>& aPt) 00709 { 00710 _x += aPt.x(); 00711 _y += aPt.y(); 00712 return *this; 00713 } 00714 00715 00716 // SUBSTRACT COORDINATES OF THE GIVEN POINT TO THOSE 00717 // OF THE CURRENT POINT, AND RETURN THEM AS A NEW POINT 00718 00719 template <class T> 00720 const GenPoint<T> 00721 GenPoint<T>::minus(const GenPoint<T>& aPt) const 00722 { 00723 return GenPoint(*this).minusEqual(aPt); 00724 } 00725 00726 00727 // SUBSTRACT COORDINATES OF THE GIVEN POINT TO THOSE OF THE CURRENT POINT 00728 00729 template <class T> 00730 GenPoint<T>& 00731 GenPoint<T>::minusEqual(const GenPoint<T>& aPt) 00732 { 00733 _x -= aPt.x(); 00734 _y -= aPt.y(); 00735 return *this; 00736 } 00737 00738 00739 // EQUALITY 00740 00741 template <class T> 00742 bool 00743 GenPoint<T>::eq(const GenPoint<T>& aPt) const 00744 { 00745 return ((_x == aPt.x()) && (_y == aPt.y())); 00746 } 00747 00748 00749 // INEQUALITY 00750 00751 template <class T> 00752 bool 00753 GenPoint<T>::notEq(const GenPoint<T>& aPt) const 00754 { 00755 return (! this->eq(aPt) ); 00756 } 00757 00758 00759 // ------------------------------------------------------------------- 00760 // ------------------------------------------------------------------- 00761 // S E R I A L I Z A T I O N / D E S E R I A L I Z A T I O N 00762 // ------------------------------------------------------------------- 00763 // ------------------------------------------------------------------- 00764 00765 00766 // CLASS qgar::GenPoint DOES NOT DERIVE FROM CLASS qgar::ISerializable 00767 // TO GET A SMALLER IMPLEMENTATION OF A POINT 00768 // 00769 // => THESE ARE GLOBAL FUNCTIONS 00770 00771 00772 // DESERIALIZE A POINT (READ IT FROM AN INPUT STREAM) 00773 00774 template <class T> 00775 inline std::istream& 00776 operator>>(std::istream& anInStream, GenPoint<T>& aPt) 00777 { 00778 qgReadObjName(anInStream, "Point"); 00779 00780 T x; 00781 qgReadObjData(anInStream, x); 00782 00783 T y; 00784 qgReadObjData(anInStream, y); 00785 00786 aPt = GenPoint<T>(x,y); 00787 00788 return anInStream; 00789 } 00790 00791 00792 // SERIALIZE A POINT (WRITE IT INTO AN OUTPUT STREAM) 00793 00794 template <class T> 00795 inline std::ostream& 00796 operator<<(std::ostream& anOutStream, const GenPoint<T>& aPt) 00797 { 00798 anOutStream << "Point(" 00799 << aPt.x() 00800 << ")(" 00801 << aPt.y() 00802 << ')'; 00803 00804 return anOutStream; 00805 } 00806 00807 00808 // ------------------------------------------------------------------- 00809 // ------------------------------------------------------------------- 00810 00811 00812 } // namespace qgar