[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 1998-2003 by Hans Meine */ 00004 /* */ 00005 /* This file is part of the VIGRA computer vision library. */ 00006 /* The VIGRA Website is */ 00007 /* http://hci.iwr.uni-heidelberg.de/vigra/ */ 00008 /* Please direct questions, bug reports, and contributions to */ 00009 /* ullrich.koethe@iwr.uni-heidelberg.de or */ 00010 /* vigra@informatik.uni-hamburg.de */ 00011 /* */ 00012 /* Permission is hereby granted, free of charge, to any person */ 00013 /* obtaining a copy of this software and associated documentation */ 00014 /* files (the "Software"), to deal in the Software without */ 00015 /* restriction, including without limitation the rights to use, */ 00016 /* copy, modify, merge, publish, distribute, sublicense, and/or */ 00017 /* sell copies of the Software, and to permit persons to whom the */ 00018 /* Software is furnished to do so, subject to the following */ 00019 /* conditions: */ 00020 /* */ 00021 /* The above copyright notice and this permission notice shall be */ 00022 /* included in all copies or substantial portions of the */ 00023 /* Software. */ 00024 /* */ 00025 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ 00026 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ 00027 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ 00028 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ 00029 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ 00030 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ 00031 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ 00032 /* OTHER DEALINGS IN THE SOFTWARE. */ 00033 /* */ 00034 /************************************************************************/ 00035 00036 #ifndef VIGRA_DIFF2D_HXX 00037 #define VIGRA_DIFF2D_HXX 00038 00039 #include <cmath> // for sqrt() 00040 #include <iosfwd> 00041 #include "config.hxx" 00042 #include "iteratortags.hxx" 00043 #include "iteratortraits.hxx" 00044 #include "iteratoradapter.hxx" 00045 #include "tuple.hxx" 00046 00047 00048 namespace vigra { 00049 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 /* 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 /** Scale this rectangle by the given factor. 01276 * To be specific, both upperLeft() and lowerRight() are 01277 * multiplicated by `factor`. 01278 */ 01279 Rect2D & operator*=(int factor) 01280 { 01281 upperLeft_ *= factor; 01282 lowerRight_ *= factor; 01283 return *this; 01284 } 01285 01286 /** Scale this rectangle by the given factor. 01287 * To be specific, both upperLeft() and lowerRight() are 01288 * multiplicated by `factor`. 01289 */ 01290 Rect2D & operator*=(double factor) 01291 { 01292 upperLeft_ *= factor; 01293 lowerRight_ *= factor; 01294 return *this; 01295 } 01296 01297 /** Return rectangle scaled by the given factor. 01298 * To be specific, both upperLeft() and lowerRight() are 01299 * multiplicated by `factor`. 01300 */ 01301 Rect2D operator*(int factor) const 01302 { 01303 return Rect2D(*this)*=factor; 01304 } 01305 01306 /** Return rectangle scaled by the given factor. 01307 * To be specific, both upperLeft() and lowerRight() are 01308 * multiplicated by `factor`. 01309 */ 01310 Rect2D operator*(double factor) const 01311 { 01312 return Rect2D(*this)*=factor; 01313 } 01314 01315 /** Intersects this rectangle with the given one. The result 01316 * is the maximal rectangle contained in both original ones. 01317 * Intersecting with an empty rectangle will yield again an 01318 * empty rectangle. 01319 */ 01320 Rect2D operator&(Rect2D const &r) const 01321 { 01322 Rect2D result(*this); 01323 result &= r; 01324 return result; 01325 } 01326 }; 01327 01328 01329 /********************************************************/ 01330 /* */ 01331 /* Dist2D */ 01332 /* */ 01333 /********************************************************/ 01334 01335 /** @deprecated use \ref vigra::Diff2D instead 01336 */ 01337 class Dist2D 01338 { 01339 public: 01340 Dist2D(int the_width, int the_height) 01341 : width(the_width), 01342 height(the_height) 01343 {} 01344 01345 Dist2D(Dist2D const & s) 01346 : width(s.width), 01347 height(s.height) 01348 {} 01349 01350 Dist2D & operator=(Dist2D const & s) 01351 { 01352 if(this != &s) 01353 { 01354 width = s.width; 01355 height = s.height; 01356 } 01357 return *this; 01358 } 01359 01360 Dist2D & operator+=(Dist2D const & s) 01361 { 01362 width += s.width; 01363 height += s.height; 01364 01365 return *this; 01366 } 01367 01368 Dist2D operator+(Dist2D const & s) const 01369 { 01370 Dist2D ret(*this); 01371 ret += s; 01372 01373 return ret; 01374 } 01375 01376 operator Diff2D() 01377 { return Diff2D(width, height); } 01378 01379 int width; 01380 int height; 01381 }; 01382 01383 //@} 01384 01385 } // namespace vigra 01386 01387 namespace std { 01388 01389 /** 01390 * Output a \ref vigra::Diff2D as a tuple. 01391 * Example Diff2D(-12, 13) -> "(-12, 13)" 01392 */ 01393 inline 01394 ostream & operator<<(ostream & o, vigra::Diff2D const & d) 01395 { 01396 o << '(' << d.x << ", " << d.y << ')'; 01397 return o; 01398 } 01399 01400 /** 01401 * Output a \ref vigra::Size2D. 01402 * Example Size2D(100, 200) -> "(100x200)" 01403 */ 01404 inline 01405 ostream &operator <<(ostream &s, vigra::Size2D const &d) 01406 { 01407 s << '(' << d.x << 'x' << d.y << ')'; 01408 return s; 01409 } 01410 01411 /** 01412 * Output a description of a \ref vigra::Rect2D. 01413 * Example Rect2D(10, 10, 30, 20) -> "[(10, 10) to (30, 20) = (20x10)]" 01414 */ 01415 inline 01416 ostream &operator <<(ostream &s, vigra::Rect2D const &r) 01417 { 01418 s << "[" << r.upperLeft() << " to " << r.lowerRight() 01419 << " = " << r.size() << "]"; 01420 return s; 01421 } 01422 01423 } // namespace std 01424 01425 #endif // VIGRA_DIFF2D_HXX
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|