[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]
![]() |
vigra/diff2d.hxx | ![]() |
---|
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 1998-2003 by Hans Meine */ 00004 /* Cognitive Systems Group, University of Hamburg, Germany */ 00005 /* */ 00006 /* This file is part of the VIGRA computer vision library. */ 00007 /* ( Version 1.4.0, Dec 21 2005 ) */ 00008 /* The VIGRA Website is */ 00009 /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ 00010 /* Please direct questions, bug reports, and contributions to */ 00011 /* koethe@informatik.uni-hamburg.de or */ 00012 /* vigra@kogs1.informatik.uni-hamburg.de */ 00013 /* */ 00014 /* Permission is hereby granted, free of charge, to any person */ 00015 /* obtaining a copy of this software and associated documentation */ 00016 /* files (the "Software"), to deal in the Software without */ 00017 /* restriction, including without limitation the rights to use, */ 00018 /* copy, modify, merge, publish, distribute, sublicense, and/or */ 00019 /* sell copies of the Software, and to permit persons to whom the */ 00020 /* Software is furnished to do so, subject to the following */ 00021 /* conditions: */ 00022 /* */ 00023 /* The above copyright notice and this permission notice shall be */ 00024 /* included in all copies or substantial portions of the */ 00025 /* Software. */ 00026 /* */ 00027 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ 00028 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ 00029 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ 00030 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ 00031 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ 00032 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ 00033 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ 00034 /* OTHER DEALINGS IN THE SOFTWARE. */ 00035 /* */ 00036 /************************************************************************/ 00037 00038 #ifndef VIGRA_DIFF2D_HXX 00039 #define VIGRA_DIFF2D_HXX 00040 00041 #include <cmath> // for sqrt() 00042 #include <iosfwd> 00043 #include "vigra/config.hxx" 00044 #include "vigra/iteratortags.hxx" 00045 #include "vigra/iteratortraits.hxx" 00046 #include "vigra/iteratoradapter.hxx" 00047 #include "vigra/tuple.hxx" 00048 00049 namespace vigra { 00050 00051 template <class Diff> 00052 class Diff2DConstRowIteratorPolicy 00053 { 00054 public: 00055 typedef Diff BaseType; 00056 typedef Diff value_type; 00057 typedef typename Diff::MoveX difference_type; 00058 typedef Diff const & reference; 00059 typedef Diff index_reference; 00060 typedef Diff const * pointer; 00061 typedef std::random_access_iterator_tag iterator_category; 00062 00063 static void initialize(BaseType &) {} 00064 00065 static reference dereference(BaseType const & d) 00066 { return d; } 00067 00068 static index_reference dereference(BaseType d, difference_type n) 00069 { 00070 d.x += n; 00071 return d; 00072 } 00073 00074 static bool equal(BaseType const & d1, BaseType const & d2) 00075 { return d1.x == d2.x; } 00076 00077 static bool less(BaseType const & d1, BaseType const & d2) 00078 { return d1.x < d2.x; } 00079 00080 static difference_type difference(BaseType const & d1, BaseType const & d2) 00081 { return d1.x - d2.x; } 00082 00083 static void increment(BaseType & d) 00084 { ++d.x; } 00085 00086 static void decrement(BaseType & d) 00087 { --d.x; } 00088 00089 static void advance(BaseType & d, difference_type n) 00090 { d.x += n; } 00091 }; 00092 00093 template <class Diff> 00094 class Diff2DConstColumnIteratorPolicy 00095 { 00096 public: 00097 typedef Diff BaseType; 00098 typedef Diff value_type; 00099 typedef typename Diff::MoveY difference_type; 00100 typedef Diff const & reference; 00101 typedef Diff index_reference; 00102 typedef Diff const * pointer; 00103 typedef std::random_access_iterator_tag iterator_category; 00104 00105 static void initialize(BaseType & /*d*/) {} 00106 00107 static reference dereference(BaseType const & d) 00108 { return d; } 00109 00110 static index_reference dereference(BaseType d, difference_type n) 00111 { 00112 d.y += n; 00113 return d; 00114 } 00115 00116 static bool equal(BaseType const & d1, BaseType const & d2) 00117 { return d1.y == d2.y; } 00118 00119 static bool less(BaseType const & d1, BaseType const & d2) 00120 { return d1.y < d2.y; } 00121 00122 static difference_type difference(BaseType const & d1, BaseType const & d2) 00123 { return d1.y - d2.y; } 00124 00125 static void increment(BaseType & d) 00126 { ++d.y; } 00127 00128 static void decrement(BaseType & d) 00129 { --d.y; } 00130 00131 static void advance(BaseType & d, difference_type n) 00132 { d.y += n; } 00133 }; 00134 00135 /** \addtogroup RangesAndPoints Two-dimensional Ranges and Points 00136 00137 Specify a 2D position, extent, or rectangle. 00138 */ 00139 //@{ 00140 00141 /********************************************************/ 00142 /* */ 00143 /* Diff2D */ 00144 /* */ 00145 /********************************************************/ 00146 00147 /** \brief Two dimensional difference vector. 00148 00149 This class acts primarily as a difference vector for specifying 00150 pixel coordinates and region sizes. In addition, Diff2D fulfills 00151 the requirements of an \ref ImageIterator, so that it can be used to 00152 simulate an image whose pixels' values equal their coordinates. This 00153 secondary usage is explained on page \ref CoordinateIterator. 00154 00155 Standard usage as a difference vector is mainly needed in the context 00156 of images. For example, Diff2D may be used as an index for <TT>operator[]</TT>: 00157 00158 \code 00159 vigra::Diff2D location(...); 00160 00161 value = image[location]; 00162 \endcode 00163 00164 This is especially important in connection with accessors, where the 00165 offset variant of <TT>operator()</TT> takes only one offset object: 00166 00167 \code 00168 // accessor(iterator, dx, dy); is not allowed 00169 value = accessor(iterator, vigra::Diff2D(dx, dy)); 00170 \endcode 00171 00172 00173 Diff2D is also returned by <TT>image.size()</TT>, so that we can create 00174 new images by calculating their size using Diff2D's arithmetic 00175 functions: 00176 00177 \code 00178 // create an image that is 10 pixels smaller in each direction 00179 Image new_image(old_image.size() - Diff2D(10,10)); 00180 \endcode 00181 00182 <b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>"<br> 00183 Namespace: vigra 00184 */ 00185 class Diff2D 00186 { 00187 public: 00188 /** The iterator's value type: a coordinate. 00189 */ 00190 typedef Diff2D PixelType; 00191 00192 /** The iterator's value type: a coordinate. 00193 */ 00194 typedef Diff2D value_type; 00195 00196 /** the iterator's reference type (return type of <TT>*iter</TT>) 00197 */ 00198 typedef Diff2D const & reference; 00199 00200 /** the iterator's index reference type (return type of <TT>iter[diff]</TT>) 00201 */ 00202 typedef Diff2D index_reference; 00203 00204 /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>) 00205 */ 00206 typedef Diff2D const * pointer; 00207 00208 /** the iterator's difference type (argument type of <TT>iter[diff]</TT>) 00209 */ 00210 typedef Diff2D difference_type; 00211 00212 /** the iterator tag (image traverser) 00213 */ 00214 typedef image_traverser_tag iterator_category; 00215 00216 /** The associated row iterator. 00217 */ 00218 typedef IteratorAdaptor<Diff2DConstRowIteratorPolicy<Diff2D> > row_iterator; 00219 00220 /** The associated column iterator. 00221 */ 00222 typedef IteratorAdaptor<Diff2DConstColumnIteratorPolicy<Diff2D> > column_iterator; 00223 00224 /** type of the iterator's x-navigator 00225 */ 00226 typedef int MoveX; 00227 /** type of the iterator's y-navigator 00228 */ 00229 typedef int MoveY; 00230 00231 00232 /** Default Constructor. Init iterator at position (0,0) 00233 */ 00234 Diff2D() 00235 : x(0), y(0) 00236 {} 00237 00238 /** Construct at given position. 00239 */ 00240 Diff2D(int ax, int ay) 00241 : x(ax), y(ay) 00242 {} 00243 00244 /** Copy Constructor. 00245 */ 00246 Diff2D(Diff2D const & v) 00247 : x(v.x), y(v.y) 00248 {} 00249 00250 /** Copy Assigment. 00251 */ 00252 Diff2D & operator=(Diff2D const & v) 00253 { 00254 if(this != &v) 00255 { 00256 x = v.x; 00257 y = v.y; 00258 } 00259 return *this; 00260 } 00261 00262 /** Unary negation. 00263 */ 00264 Diff2D operator-() const 00265 { 00266 return Diff2D(-x, -y); 00267 } 00268 00269 /** Increase coordinate by specified offset. 00270 */ 00271 Diff2D & operator+=(Diff2D const & offset) 00272 { 00273 x += offset.x; 00274 y += offset.y; 00275 return *this; 00276 } 00277 00278 /** Decrease coordinate by specified vector. 00279 */ 00280 Diff2D & operator-=(Diff2D const & offset) 00281 { 00282 x -= offset.x; 00283 y -= offset.y; 00284 return *this; 00285 } 00286 00287 /** Create vector by scaling by factor. 00288 */ 00289 Diff2D & operator*=(int factor) 00290 { 00291 x *= factor; 00292 y *= factor; 00293 return *this; 00294 } 00295 00296 /** Create vector by scaling by factor. 00297 */ 00298 Diff2D & operator*=(double factor) 00299 { 00300 x = (int)(x * factor); 00301 y = (int)(y * factor); 00302 return *this; 00303 } 00304 00305 /** Create vector by scaling by 1/factor. 00306 */ 00307 Diff2D & operator/=(int factor) 00308 { 00309 x /= factor; 00310 y /= factor; 00311 return *this; 00312 } 00313 00314 /** Create vector by scaling by 1/factor. 00315 */ 00316 Diff2D & operator/=(double factor) 00317 { 00318 x = (int)(x / factor); 00319 y = (int)(y / factor); 00320 return *this; 00321 } 00322 00323 /** Create vector by scaling by factor. 00324 */ 00325 Diff2D operator*(int factor) const 00326 { 00327 return Diff2D(x * factor, y * factor); 00328 } 00329 00330 /** Create vector by scaling by factor. 00331 */ 00332 Diff2D operator*(double factor) const 00333 { 00334 return Diff2D((int)(x * factor), (int)(y * factor)); 00335 } 00336 00337 /** Create vector by scaling by 1/factor. 00338 */ 00339 Diff2D operator/(int factor) const 00340 { 00341 return Diff2D(x / factor, y / factor); 00342 } 00343 00344 /** Create vector by scaling by 1/factor. 00345 */ 00346 Diff2D operator/(double factor) const 00347 { 00348 return Diff2D((int)(x / factor), (int)(y / factor)); 00349 } 00350 00351 /** Calculate length of difference vector. 00352 */ 00353 int squaredMagnitude() const 00354 { 00355 return x*x + y*y; 00356 } 00357 00358 /** Calculate length of difference vector. 00359 */ 00360 double magnitude() const 00361 { 00362 return VIGRA_CSTD::sqrt((double)squaredMagnitude()); 00363 } 00364 00365 /** Equality. 00366 */ 00367 bool operator==(Diff2D const & r) const 00368 { 00369 return (x == r.x) && (y == r.y); 00370 } 00371 00372 /** Inequality. 00373 */ 00374 bool operator!=(Diff2D const & r) const 00375 { 00376 return (x != r.x) || (y != r.y); 00377 } 00378 00379 /** Used for both access to the current x-coordinate \em and 00380 to specify that an iterator navigation command is to be 00381 applied in x-direction. <br> 00382 usage: <TT> x = diff2d.x </TT> (use \p Diff2D::x as component of difference vector) <br> 00383 or <TT> ++diff.x </TT> (use Diff2D as iterator, move right) 00384 */ 00385 int x; 00386 /** Used for both access to the current y-coordinate \em and 00387 to specify that an iterator navigation command is to be 00388 applied in y-direction. <br> 00389 usage: <TT> y = diff2d.y </TT> (use \p Diff2D::y as component of difference vector) <br> 00390 or <TT> ++diff.y </TT> (use Diff2D as iterator, move right) 00391 */ 00392 int y; 00393 00394 /** Access current coordinate. 00395 */ 00396 reference operator*() const 00397 { 00398 return *this; 00399 } 00400 00401 /** Read coordinate at an offset. 00402 */ 00403 index_reference operator()(int const & dx, int const & dy) const 00404 { 00405 return Diff2D(x + dx, y + dy); 00406 } 00407 00408 /** Read coordinate at an offset. 00409 */ 00410 index_reference operator[](Diff2D const & offset) const 00411 { 00412 return Diff2D(x + offset.x, y + offset.y); 00413 } 00414 00415 /** Read vector components. 00416 */ 00417 int operator[](int index) const 00418 { 00419 return (&x)[index]; 00420 } 00421 00422 /** Access current coordinate. 00423 */ 00424 pointer operator->() const 00425 { 00426 return this; 00427 } 00428 00429 /** Get a row iterator at the current position. 00430 */ 00431 row_iterator rowIterator() const 00432 { return row_iterator(*this); } 00433 00434 /** Get a column iterator at the current position. 00435 */ 00436 column_iterator columnIterator() const 00437 { return column_iterator(*this); } 00438 }; 00439 00440 00441 template <> 00442 struct IteratorTraits<Diff2D > 00443 { 00444 typedef Diff2D Iterator; 00445 typedef Iterator iterator; 00446 typedef Iterator const_iterator; 00447 // typedef multable_iterator; undefined 00448 typedef iterator::iterator_category iterator_category; 00449 typedef iterator::value_type value_type; 00450 typedef iterator::reference reference; 00451 typedef iterator::index_reference index_reference; 00452 typedef iterator::pointer pointer; 00453 typedef iterator::difference_type difference_type; 00454 typedef iterator::row_iterator row_iterator; 00455 typedef iterator::column_iterator column_iterator; 00456 typedef StandardConstValueAccessor<Diff2D> DefaultAccessor; 00457 typedef StandardConstValueAccessor<Diff2D> default_accessor; 00458 typedef VigraTrueType hasConstantStrides; 00459 00460 }; 00461 00462 00463 /********************************************************/ 00464 /* */ 00465 /* Size2D */ 00466 /* */ 00467 /********************************************************/ 00468 00469 /** \brief Two dimensional size object. 00470 00471 Specializes \ref Diff2D for the specification of a 2-dimensional 00472 extent, in contrast to a point or position (for the latter 00473 use \ref Point2D). 00474 00475 \code 00476 // create an image that is 10 pixels squared 00477 Image new_image(Size2D(10,10)); 00478 \endcode 00479 00480 <b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>"<br> 00481 Namespace: vigra 00482 */ 00483 class Size2D : public Diff2D 00484 { 00485 public: 00486 /** Default Constructor. Init point at position (0,0) 00487 */ 00488 Size2D() 00489 {} 00490 00491 /** Construct point at given position. 00492 */ 00493 Size2D(int width, int height) 00494 : Diff2D(width, height) 00495 {} 00496 00497 /** Copy Constructor. 00498 */ 00499 Size2D(Size2D const & v) 00500 : Diff2D(v) 00501 {} 00502 00503 /** Explicit conversion Constructor. 00504 */ 00505 explicit Size2D(Diff2D const & v) 00506 : Diff2D(v) 00507 {} 00508 00509 /** Query the width. 00510 */ 00511 int width() const 00512 { 00513 return x; 00514 } 00515 00516 /** Query the height. 00517 */ 00518 int height() const 00519 { 00520 return y; 00521 } 00522 00523 /** Returns width()*height(), the area of a rectangle of this size. 00524 */ 00525 int area() const 00526 { 00527 return width()*height(); 00528 } 00529 00530 /** Copy Assigment. 00531 */ 00532 Size2D & operator=(Diff2D const & v) 00533 { 00534 return static_cast<Size2D &>(Diff2D::operator=(v)); 00535 } 00536 00537 /** Unary negation. 00538 */ 00539 Size2D operator-() const 00540 { 00541 return Size2D(-x, -y); 00542 } 00543 00544 /** Increase size by specified offset. 00545 */ 00546 Size2D & operator+=(Diff2D const & offset) 00547 { 00548 return static_cast<Size2D &>(Diff2D::operator+=(offset)); 00549 } 00550 00551 /** Decrease size by specified offset. 00552 */ 00553 Size2D & operator-=(Diff2D const & offset) 00554 { 00555 return static_cast<Size2D &>(Diff2D::operator-=(offset)); 00556 } 00557 }; 00558 00559 /********************************************************/ 00560 /* */ 00561 /* Point2D */ 00562 /* */ 00563 /********************************************************/ 00564 00565 /** \brief Two dimensional point or position. 00566 00567 Specializes \ref Diff2D for the specification of a 2-dimensional 00568 point or position, in contrast to an extent (for the latter 00569 use \ref Size2D). 00570 00571 \code 00572 // access an image at a point 00573 value = image[Point2D(10, 20)]; 00574 \endcode 00575 00576 <b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>"<br> 00577 Namespace: vigra 00578 */ 00579 class Point2D : public Diff2D 00580 { 00581 public: 00582 /** The iterator's value type: a coordinate. 00583 */ 00584 typedef Point2D PixelType; 00585 00586 /** The iterator's value type: a coordinate. 00587 */ 00588 typedef Point2D value_type; 00589 00590 /** the iterator's reference type (return type of <TT>*iter</TT>) 00591 */ 00592 typedef Point2D const & reference; 00593 00594 /** the iterator's index reference type (return type of <TT>iter[diff]</TT>) 00595 */ 00596 typedef Point2D index_reference; 00597 00598 /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>) 00599 */ 00600 typedef Point2D const * pointer; 00601 00602 /** Default Constructor. Init point at position (0,0) 00603 */ 00604 Point2D() 00605 {} 00606 00607 /** Construct point at given position. 00608 */ 00609 Point2D(int x, int y) 00610 : Diff2D(x, y) 00611 {} 00612 00613 /** Copy Constructor. 00614 */ 00615 Point2D(Point2D const & v) 00616 : Diff2D(v) 00617 {} 00618 00619 /** Explicit conversion Constructor. 00620 */ 00621 explicit Point2D(Diff2D const & v) 00622 : Diff2D(v) 00623 {} 00624 00625 /** Query the points' x coordinate 00626 */ 00627 int px() const 00628 { 00629 return x; 00630 } 00631 00632 /** Query the points' y coordinate 00633 */ 00634 int py() const 00635 { 00636 return y; 00637 } 00638 00639 /** Copy Assigment. 00640 */ 00641 Point2D & operator=(Diff2D const & v) 00642 { 00643 return static_cast<Point2D &>(Diff2D::operator=(v)); 00644 } 00645 00646 /** Unary negation. 00647 */ 00648 Point2D operator-() const 00649 { 00650 return Point2D(-x, -y); 00651 } 00652 00653 /** Increase point coordinates by specified offset. 00654 */ 00655 Point2D & operator+=(Diff2D const & offset) 00656 { 00657 return static_cast<Point2D &>(Diff2D::operator+=(offset)); 00658 } 00659 00660 /** Decrease point coordinates by specified offset. 00661 */ 00662 Point2D & operator-=(Diff2D const & offset) 00663 { 00664 return static_cast<Point2D &>(Diff2D::operator-=(offset)); 00665 } 00666 00667 /** Access current point coordinate. 00668 */ 00669 reference operator*() const 00670 { 00671 return *this; 00672 } 00673 00674 /** Read point coordinate at an offset. 00675 */ 00676 index_reference operator()(int const & dx, int const & dy) const 00677 { 00678 return Point2D(x + dx, y + dy); 00679 } 00680 00681 /** Read point coordinate at an offset. 00682 */ 00683 index_reference operator[](Diff2D const & offset) const 00684 { 00685 return Point2D(x + offset.x, y + offset.y); 00686 } 00687 00688 /** Access current point coordinate. 00689 */ 00690 pointer operator->() const 00691 { 00692 return this; 00693 } 00694 }; 00695 00696 /** Create vector by subtracting specified offset. 00697 */ 00698 inline Diff2D operator-(Diff2D const &a, Diff2D const &b) 00699 { 00700 return Diff2D(a.x - b.x, a.y - b.y); 00701 } 00702 00703 /** Create size by subtracting specified offset. 00704 */ 00705 inline Size2D operator-(Size2D const & s, Diff2D const &offset) 00706 { 00707 return Size2D(s.x - offset.x, s.y - offset.y); 00708 } 00709 00710 /** Calculate size of rect between two points. 00711 */ 00712 inline Point2D operator-(Point2D const & s, Diff2D const & offset) 00713 { 00714 return Point2D(s.x - offset.x, s.y - offset.y); 00715 } 00716 00717 /** The difference of two points is a size 00718 */ 00719 inline Size2D operator-(Point2D const & s, Point2D const & p) 00720 { 00721 return Size2D(s.x - p.x, s.y - p.y); 00722 } 00723 00724 /** Create vector by adding specified offset. 00725 */ 00726 inline Diff2D operator+(Diff2D const &a, Diff2D const &b) 00727 { 00728 return Diff2D(a.x + b.x, a.y + b.y); 00729 } 00730 00731 /** Create size by adding specified offset. 00732 */ 00733 inline Size2D operator+(Size2D const &a, Diff2D const &b) 00734 { 00735 return Size2D(a.x + b.x, a.y + b.y); 00736 } 00737 00738 /** Create point by adding specified offset. 00739 */ 00740 inline Point2D operator+(Point2D const &a, Diff2D const &b) 00741 { 00742 return Point2D(a.x + b.x, a.y + b.y); 00743 } 00744 00745 /** Add size and point 00746 */ 00747 inline Point2D operator+(Size2D const & s, Point2D const & p) 00748 { 00749 return Point2D(s.x + p.x, s.y + p.y); 00750 } 00751 00752 inline Point2D operator*(Point2D l, double r) 00753 { 00754 l *= r; 00755 return l; 00756 } 00757 00758 inline Point2D operator*(double l, Point2D r) 00759 { 00760 r *= l; 00761 return r; 00762 } 00763 00764 inline Size2D operator*(Size2D l, double r) 00765 { 00766 l *= r; 00767 return l; 00768 } 00769 00770 inline Size2D operator*(double l, Size2D r) 00771 { 00772 r *= l; 00773 return r; 00774 } 00775 00776 inline Point2D operator/(Point2D l, double r) 00777 { 00778 l /= r; 00779 return l; 00780 } 00781 00782 inline Size2D operator/(Size2D l, double r) 00783 { 00784 l /= r; 00785 return l; 00786 } 00787 00788 inline Point2D operator*(Point2D l, int r) 00789 { 00790 l *= r; 00791 return l; 00792 } 00793 00794 inline Point2D operator*(int l, Point2D r) 00795 { 00796 r *= l; 00797 return r; 00798 } 00799 00800 inline Size2D operator*(Size2D l, int r) 00801 { 00802 l *= r; 00803 return l; 00804 } 00805 00806 inline Size2D operator*(int l, Size2D r) 00807 { 00808 r *= l; 00809 return r; 00810 } 00811 00812 inline Point2D operator/(Point2D l, int r) 00813 { 00814 l /= r; 00815 return l; 00816 } 00817 00818 inline Size2D operator/(Size2D l, int r) 00819 { 00820 l /= r; 00821 return l; 00822 } 00823 00824 00825 /********************************************************/ 00826 /* */ 00827 /* Rect2D */ 00828 /* */ 00829 /********************************************************/ 00830 00831 /** \brief Two dimensional rectangle. 00832 00833 This class stores a 2-dimensional rectangular range or region. Thus, 00834 it follows the VIGRA convention that the upper left corner is inside 00835 the rectangle, while the lower right is 1 pixel to the right and below the 00836 last pixel in the rectangle. 00837 00838 A major advantage of this class is that it can be constructed from either 00839 a pair of \ref Point2D, or from a \ref Point2D and an extend 00840 (\ref Size2D). Rect2D overloads operators |=, &=, |, & to realize set 00841 union (in the sense of a minimal bounding rectangle) and set intersection. 00842 00843 \code 00844 Rect2D r1(Point2D(0,0), Point2D(10, 20)), 00845 r2(Point2D(10, 15), Size2D(20, 20)); 00846 Point2D p(0,100); 00847 00848 Rect2D r3 = r1 | r2; // upper left is (0,0), lower right is (30, 35) 00849 assert(r3.contains(r2)); 00850 assert(!r3.contains(p)); 00851 00852 r3 |= p; // lower right now (30,101) so that p is inside r3 00853 assert(r3.contains(p)); 00854 \endcode 00855 00856 <b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>"<br> 00857 Namespace: vigra 00858 */ 00859 class Rect2D 00860 { 00861 Point2D upperLeft_, lowerRight_; 00862 00863 public: 00864 /** Construct a null rectangle (isEmpty() will return true) 00865 */ 00866 Rect2D() 00867 {} 00868 00869 /** Construct a rectangle representing the given range 00870 * (lowerRight is considered to be outside the rectangle as 00871 * usual in the VIGRA) 00872 */ 00873 Rect2D(Point2D const &upperLeft, Point2D const &lowerRight) 00874 : upperLeft_(upperLeft), lowerRight_(lowerRight) 00875 {} 00876 00877 /** Construct a rectangle representing the given range 00878 */ 00879 Rect2D(int left, int top, int right, int bottom) 00880 : upperLeft_(left, top), lowerRight_(right, bottom) 00881 {} 00882 00883 /** Construct a rectangle of given position and size 00884 */ 00885 Rect2D(Point2D const &upperLeft, Size2D const &size) 00886 : upperLeft_(upperLeft), lowerRight_(upperLeft + size) 00887 {} 00888 00889 /** Construct a rectangle of given size at position (0,0) 00890 */ 00891 explicit Rect2D(Size2D const &size) 00892 : lowerRight_(Point2D(size)) 00893 {} 00894 00895 /** Return the first point (scan-order wise) which is 00896 * considered to be "in" the rectangle. 00897 */ 00898 Point2D const & upperLeft() const 00899 { 00900 return upperLeft_; 00901 } 00902 00903 /** Return the first point to the right and below the 00904 * rectangle. 00905 */ 00906 Point2D const & lowerRight() const 00907 { 00908 return lowerRight_; 00909 } 00910 00911 /** Change upperLeft() without changing lowerRight(), which 00912 * will change the size most probably. 00913 */ 00914 void setUpperLeft(Point2D const &ul) 00915 { 00916 upperLeft_ = ul; 00917 } 00918 00919 /** Change lowerRight() without changing upperLeft(), which 00920 * will change the size most probably. 00921 */ 00922 void setLowerRight(Point2D const &lr) 00923 { 00924 lowerRight_ = lr; 00925 } 00926 00927 /** Move the whole rectangle so that the given point will be 00928 * upperLeft() afterwards. 00929 */ 00930 void moveTo(Point2D const &newUpperLeft) 00931 { 00932 lowerRight_ += newUpperLeft - upperLeft_; 00933 upperLeft_ = newUpperLeft; 00934 } 00935 00936 /** Move the whole rectangle so that upperLeft() will become 00937 * Point2D(left, top) afterwards. 00938 */ 00939 void moveTo(int left, int top) 00940 { 00941 moveTo(Point2D(left, top)); 00942 } 00943 00944 /** Move the whole rectangle by the given 2D offset. 00945 */ 00946 void moveBy(Diff2D const &offset) 00947 { 00948 upperLeft_ += offset; 00949 lowerRight_ += offset; 00950 } 00951 00952 /** Move the whole rectangle by the given x- and y-offsets. 00953 */ 00954 void moveBy(int xOffset, int yOffset) 00955 { 00956 moveBy(Diff2D(xOffset, yOffset)); 00957 } 00958 00959 /** Return the left coordinate of this rectangle. 00960 */ 00961 int left() const 00962 { 00963 return upperLeft_.x; 00964 } 00965 00966 /** Return the top coordinate of this rectangle. 00967 */ 00968 int top() const 00969 { 00970 return upperLeft_.y; 00971 } 00972 00973 /** Return the right coordinate of this rectangle. That is the 00974 * first column to the right of the rectangle. 00975 */ 00976 int right() const 00977 { 00978 return lowerRight_.x; 00979 } 00980 00981 /** Return the bottom coordinate of this rectangle. That is the 00982 * first row below the rectangle. 00983 */ 00984 int bottom() const 00985 { 00986 return lowerRight_.y; 00987 } 00988 00989 /** Determine and return the width of this rectangle. It might be 00990 * zero or even negative, and if so, isEmpty() will return true. 00991 */ 00992 int width() const 00993 { 00994 return lowerRight_.x - upperLeft_.x; 00995 } 00996 00997 /** Determine and return the height of this rectangle. It might be 00998 * zero or even negative, and if so, isEmpty() will return true. 00999 */ 01000 int height() const 01001 { 01002 return lowerRight_.y - upperLeft_.y; 01003 } 01004 01005 /** Determine and return the area of this rectangle. That is, if 01006 * this rect isEmpty(), returns zero, otherwise returns 01007 * width()*height(). 01008 */ 01009 int area() const 01010 { 01011 return isEmpty() ? 0 : width()*height(); 01012 } 01013 01014 /** Determine and return the size of this rectangle. The width 01015 * and/or height might be zero or even negative, and if so, 01016 * isEmpty() will return true. 01017 */ 01018 Size2D size() const 01019 { 01020 return lowerRight_ - upperLeft_; 01021 } 01022 01023 /** Resize this rectangle to the given extents. This will move 01024 * the lower right corner only. 01025 */ 01026 void setSize(Size2D const &size) 01027 { 01028 lowerRight_ = upperLeft_ + size; 01029 } 01030 01031 /** Resize this rectangle to the given extents. This will move 01032 * the lower right corner only. 01033 */ 01034 void setSize(int width, int height) 01035 { 01036 lowerRight_ = upperLeft_ + Size2D(width, height); 01037 } 01038 01039 /** Increase the size of the rectangle by the given offset. This 01040 * will move the lower right corner only. (If any of offset's 01041 * components is negative, the rectangle will get smaller 01042 * accordingly.) 01043 */ 01044 void addSize(Size2D const &offset) 01045 { 01046 lowerRight_ += offset; 01047 } 01048 01049 /** Adds a border of the given width around the rectangle. That 01050 * means, upperLeft()'s components are moved by -borderWidth 01051 * and lowerRight()'s by borderWidth. (If borderWidth is 01052 * negative, the rectangle will get smaller accordingly.) 01053 */ 01054 void addBorder(int borderWidth) 01055 { 01056 upperLeft_ += Diff2D(-borderWidth, -borderWidth); 01057 lowerRight_ += Diff2D(borderWidth, borderWidth); 01058 } 01059 01060 /** Adds a border with possibly different widths in x- and 01061 * y-directions around the rectangle. That means, each x 01062 * component is moved borderWidth pixels and each y component 01063 * is moved borderHeight pixels to the outside. (If 01064 * borderWidth is negative, the rectangle will get smaller 01065 * accordingly.) 01066 */ 01067 void addBorder(int borderWidth, int borderHeight) 01068 { 01069 upperLeft_ += Diff2D(-borderWidth, -borderHeight); 01070 lowerRight_ += Diff2D(borderWidth, borderHeight); 01071 } 01072 01073 /// equality check 01074 bool operator==(Rect2D const &r) const 01075 { 01076 return (upperLeft_ == r.upperLeft_) && (lowerRight_ == r.lowerRight_); 01077 } 01078 01079 /// inequality check 01080 bool operator!=(Rect2D const &r) const 01081 { 01082 return (upperLeft_ != r.upperLeft_) || (lowerRight_ != r.lowerRight_); 01083 } 01084 01085 /** Return whether this rectangle is considered empty. It is 01086 * non-empty if both coordinates of the lower right corner are 01087 * greater than the corresponding coordinate of the upper left 01088 * corner. Uniting an empty rectangle with something will return 01089 * the bounding rectangle of the 'something', intersecting with an 01090 * empty rectangle will yield again an empty rectangle. 01091 */ 01092 bool isEmpty() const 01093 { 01094 return ((lowerRight_.x <= upperLeft_.x) || 01095 (lowerRight_.y <= upperLeft_.y)); 01096 } 01097 01098 /** Return whether this rectangle contains the given point. That 01099 * is, if the point lies within the valid range of an 01100 * ImageIterator walking from upperLeft() to lowerRight() 01101 * (excluding the latter). 01102 */ 01103 bool contains(Point2D const &p) const 01104 { 01105 return ((upperLeft_.x <= p.x) && 01106 (upperLeft_.y <= p.y) && 01107 (p.x < lowerRight_.x) && 01108 (p.y < lowerRight_.y)); 01109 } 01110 01111 /** Return whether this rectangle contains the given 01112 * one. <tt>r1.contains(r2)</tt> returns the same as 01113 * <tt>r1 == (r1|r2)</tt> (but is of course more 01114 * efficient). That also means, a rectangle (even an empty one!) 01115 * contains() any empty rectangle. 01116 */ 01117 bool contains(Rect2D const &r) const 01118 { 01119 return r.isEmpty() || 01120 contains(r.upperLeft()) && contains(r.lowerRight()-Diff2D(1,1)); 01121 } 01122 01123 /** Return whether this rectangle overlaps with the given 01124 * one. <tt>r1.intersects(r2)</tt> returns the same as 01125 * <tt>!(r1&r2).isEmpty()</tt> (but is of course much more 01126 * efficient). 01127 */ 01128 bool intersects(Rect2D const &r) const 01129 { 01130 return ((r.upperLeft_.x < lowerRight_.x) && 01131 (upperLeft_.x < r.lowerRight_.x) && 01132 (r.upperLeft_.y < lowerRight_.y) && 01133 (upperLeft_.y < r.lowerRight_.y)) 01134 && !r.isEmpty(); 01135 } 01136 01137 /** Modifies this rectangle by including the given point. The 01138 * result is the bounding rectangle of the rectangle and the 01139 * point. If isEmpty returns true, the union will be a 01140 * rectangle containing only the given point. 01141 */ 01142 Rect2D &operator|=(Point2D const &p) 01143 { 01144 if(isEmpty()) 01145 { 01146 upperLeft_ = p; 01147 lowerRight_ = p + Diff2D(1, 1); 01148 } 01149 else 01150 { 01151 if(p.x < upperLeft_.x) 01152 upperLeft_.x = p.x; 01153 if(p.y < upperLeft_.y) 01154 upperLeft_.y = p.y; 01155 if(lowerRight_.x <= p.x) 01156 lowerRight_.x = p.x + 1; 01157 if(lowerRight_.y <= p.y) 01158 lowerRight_.y = p.y + 1; 01159 } 01160 return *this; 01161 } 01162 01163 /** Returns the union of this rectangle and the given 01164 * point. The result is the bounding rectangle of the 01165 * rectangle and the point. If isEmpty returns true, the union 01166 * will be a rectangle containing only the given point. 01167 */ 01168 Rect2D operator|(Point2D const &p) const 01169 { 01170 Rect2D result(*this); 01171 result |= p; 01172 return result; 01173 } 01174 01175 /** Modifies this rectangle by uniting it with the given 01176 * one. The result is the bounding rectangle of both 01177 * rectangles. If one of the rectangles isEmpty(), the union 01178 * will be the other one. 01179 */ 01180 Rect2D &operator|=(Rect2D const &r) 01181 { 01182 if(r.isEmpty()) 01183 return *this; 01184 if(isEmpty()) 01185 return operator=(r); 01186 01187 if(r.upperLeft_.x < upperLeft_.x) 01188 upperLeft_.x = r.upperLeft_.x; 01189 if(r.upperLeft_.y < upperLeft_.y) 01190 upperLeft_.y = r.upperLeft_.y; 01191 if(lowerRight_.x < r.lowerRight_.x) 01192 lowerRight_.x = r.lowerRight_.x; 01193 if(lowerRight_.y < r.lowerRight_.y) 01194 lowerRight_.y = r.lowerRight_.y; 01195 return *this; 01196 } 01197 01198 /** Returns the union of this rectangle and the given one. The 01199 * result is the bounding rectangle of both rectangles. If one 01200 * of the rectangles isEmpty(), the union will be the other 01201 * one. 01202 */ 01203 Rect2D operator|(Rect2D const &r) const 01204 { 01205 Rect2D result(*this); 01206 result |= r; 01207 return result; 01208 } 01209 01210 /** Modifies this rectangle by intersecting it with the given 01211 * point. The result is the bounding rect of the point (with 01212 * width and height equal to 1) if it was contained in the 01213 * original rect, or an empty rect otherwise. 01214 */ 01215 Rect2D &operator&=(Point2D const &p) 01216 { 01217 if(contains(p)) 01218 { 01219 upperLeft_ = p; 01220 lowerRight_ = p + Diff2D(1, 1); 01221 } 01222 else 01223 lowerRight_ = upperLeft_; 01224 return *this; 01225 } 01226 01227 /** Intersects this rectangle with the given point. The result 01228 * is the bounding rect of the point (with width and height 01229 * equal to 1) if it was contained in the original rect, or an 01230 * empty rect otherwise. 01231 */ 01232 Rect2D operator&(Point2D const &p) const 01233 { 01234 Rect2D result(*this); 01235 result &= p; 01236 return result; 01237 } 01238 01239 /** Modifies this rectangle by intersecting it with the given 01240 * one. The result is the maximal rectangle contained in both 01241 * original ones. Intersecting with an empty rectangle will 01242 * yield again an empty rectangle. 01243 */ 01244 Rect2D &operator&=(Rect2D const &r) 01245 { 01246 if(isEmpty()) 01247 return *this; 01248 if(r.isEmpty()) 01249 return operator=(r); 01250 01251 if(upperLeft_.x < r.upperLeft_.x) 01252 upperLeft_.x = r.upperLeft_.x; 01253 if(upperLeft_.y < r.upperLeft_.y) 01254 upperLeft_.y = r.upperLeft_.y; 01255 if(r.lowerRight_.x < lowerRight_.x) 01256 lowerRight_.x = r.lowerRight_.x; 01257 if(r.lowerRight_.y < lowerRight_.y) 01258 lowerRight_.y = r.lowerRight_.y; 01259 return *this; 01260 } 01261 01262 /** Intersects this rectangle with the given one. The result 01263 * is the maximal rectangle contained in both original ones. 01264 * Intersecting with an empty rectangle will yield again an 01265 * empty rectangle. 01266 */ 01267 Rect2D operator&(Rect2D const &r) const 01268 { 01269 Rect2D result(*this); 01270 result &= r; 01271 return result; 01272 } 01273 }; 01274 01275 /********************************************************/ 01276 /* */ 01277 /* Dist2D */ 01278 /* */ 01279 /********************************************************/ 01280 01281 /** @deprecated use \ref vigra::Diff2D instead 01282 */ 01283 class Dist2D 01284 { 01285 public: 01286 Dist2D(int the_width, int the_height) 01287 : width(the_width), 01288 height(the_height) 01289 {} 01290 01291 Dist2D(Dist2D const & s) 01292 : width(s.width), 01293 height(s.height) 01294 {} 01295 01296 Dist2D & operator=(Dist2D const & s) 01297 { 01298 if(this != &s) 01299 { 01300 width = s.width; 01301 height = s.height; 01302 } 01303 return *this; 01304 } 01305 01306 Dist2D & operator+=(Dist2D const & s) 01307 { 01308 width += s.width; 01309 height += s.height; 01310 01311 return *this; 01312 } 01313 01314 Dist2D operator+(Dist2D const & s) const 01315 { 01316 Dist2D ret(*this); 01317 ret += s; 01318 01319 return ret; 01320 } 01321 01322 operator Diff2D() 01323 { return Diff2D(width, height); } 01324 01325 int width; 01326 int height; 01327 }; 01328 01329 //@} 01330 01331 /** 01332 * Output a \ref vigra::Diff2D as a tuple. 01333 * Example Diff2D(-12, 13) -> "(-12, 13)" 01334 */ 01335 inline 01336 std::ostream & operator<<(std::ostream & o, vigra::Diff2D const & d) 01337 { 01338 o << '(' << d.x << ", " << d.y << ')'; 01339 return o; 01340 } 01341 01342 /** 01343 * Output a \ref vigra::Size2D. 01344 * Example Size2D(100, 200) -> "(100x200)" 01345 */ 01346 inline 01347 std::ostream &operator <<(std::ostream &s, vigra::Size2D const &d) 01348 { 01349 s << '(' << d.x << 'x' << d.y << ')'; 01350 return s; 01351 } 01352 01353 /** 01354 * Output a description of a \ref vigra::Rect2D. 01355 * Example Rect2D(10, 10, 30, 20) -> "[(10, 10) to (30, 20) = (20x10)]" 01356 */ 01357 inline 01358 std::ostream &operator <<(std::ostream &s, vigra::Rect2D const &r) 01359 { 01360 s << "[" << r.upperLeft() << " to " << r.lowerRight() 01361 << " = " << r.size() << "]"; 01362 return s; 01363 } 01364 01365 } // namespace vigra 01366 01367 #endif // VIGRA_DIFF2D_HXX
© Ullrich Köthe (koethe@informatik.uni-hamburg.de) |
html generated using doxygen and Python
|