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