[ 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.5.0, Dec 07 2006 ) */ 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 "config.hxx" 00044 #include "iteratortags.hxx" 00045 #include "iteratortraits.hxx" 00046 #include "iteratoradapter.hxx" 00047 #include "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 /** Change the width. 00524 */ 00525 void setWidth(int w) 00526 { 00527 x = w; 00528 } 00529 00530 /** Change the height. 00531 */ 00532 void setHeight(int h) 00533 { 00534 y = h; 00535 } 00536 00537 /** Returns width()*height(), the area of a rectangle of this size. 00538 */ 00539 int area() const 00540 { 00541 return width()*height(); 00542 } 00543 00544 /** Copy Assigment. 00545 */ 00546 Size2D & operator=(Diff2D const & v) 00547 { 00548 return static_cast<Size2D &>(Diff2D::operator=(v)); 00549 } 00550 00551 /** Unary negation. 00552 */ 00553 Size2D operator-() const 00554 { 00555 return Size2D(-x, -y); 00556 } 00557 00558 /** Increase size by specified offset. 00559 */ 00560 Size2D & operator+=(Diff2D const & offset) 00561 { 00562 return static_cast<Size2D &>(Diff2D::operator+=(offset)); 00563 } 00564 00565 /** Decrease size by specified offset. 00566 */ 00567 Size2D & operator-=(Diff2D const & offset) 00568 { 00569 return static_cast<Size2D &>(Diff2D::operator-=(offset)); 00570 } 00571 }; 00572 00573 /********************************************************/ 00574 /* */ 00575 /* Point2D */ 00576 /* */ 00577 /********************************************************/ 00578 00579 /** \brief Two dimensional point or position. 00580 00581 Specializes \ref Diff2D for the specification of a 2-dimensional 00582 point or position, in contrast to an extent (for the latter 00583 use \ref Size2D). 00584 00585 \code 00586 // access an image at a point 00587 value = image[Point2D(10, 20)]; 00588 \endcode 00589 00590 <b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>"<br> 00591 Namespace: vigra 00592 */ 00593 class Point2D : public Diff2D 00594 { 00595 public: 00596 /** The iterator's value type: a coordinate. 00597 */ 00598 typedef Point2D PixelType; 00599 00600 /** The iterator's value type: a coordinate. 00601 */ 00602 typedef Point2D value_type; 00603 00604 /** the iterator's reference type (return type of <TT>*iter</TT>) 00605 */ 00606 typedef Point2D const & reference; 00607 00608 /** the iterator's index reference type (return type of <TT>iter[diff]</TT>) 00609 */ 00610 typedef Point2D index_reference; 00611 00612 /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>) 00613 */ 00614 typedef Point2D const * pointer; 00615 00616 /** Default Constructor. Init point at position (0,0) 00617 */ 00618 Point2D() 00619 {} 00620 00621 /** Construct point at given position. 00622 */ 00623 Point2D(int x, int y) 00624 : Diff2D(x, y) 00625 {} 00626 00627 /** Copy Constructor. 00628 */ 00629 Point2D(Point2D const & v) 00630 : Diff2D(v) 00631 {} 00632 00633 /** Explicit conversion Constructor. 00634 */ 00635 explicit Point2D(Diff2D const & v) 00636 : Diff2D(v) 00637 {} 00638 00639 /** Query the points' x coordinate 00640 */ 00641 int px() const 00642 { 00643 return x; 00644 } 00645 00646 /** Query the points' y coordinate 00647 */ 00648 int py() const 00649 { 00650 return y; 00651 } 00652 00653 /** Copy Assigment. 00654 */ 00655 Point2D & operator=(Diff2D const & v) 00656 { 00657 return static_cast<Point2D &>(Diff2D::operator=(v)); 00658 } 00659 00660 /** Unary negation. 00661 */ 00662 Point2D operator-() const 00663 { 00664 return Point2D(-x, -y); 00665 } 00666 00667 /** Increase point coordinates by specified offset. 00668 */ 00669 Point2D & operator+=(Diff2D const & offset) 00670 { 00671 return static_cast<Point2D &>(Diff2D::operator+=(offset)); 00672 } 00673 00674 /** Decrease point coordinates by specified offset. 00675 */ 00676 Point2D & operator-=(Diff2D const & offset) 00677 { 00678 return static_cast<Point2D &>(Diff2D::operator-=(offset)); 00679 } 00680 00681 /** Access current point coordinate. 00682 */ 00683 reference operator*() const 00684 { 00685 return *this; 00686 } 00687 00688 /** Read point coordinate at an offset. 00689 */ 00690 index_reference operator()(int const & dx, int const & dy) const 00691 { 00692 return Point2D(x + dx, y + dy); 00693 } 00694 00695 /** Read point coordinate at an offset. 00696 */ 00697 index_reference operator[](Diff2D const & offset) const 00698 { 00699 return Point2D(x + offset.x, y + offset.y); 00700 } 00701 00702 /** Access current point coordinate. 00703 */ 00704 pointer operator->() const 00705 { 00706 return this; 00707 } 00708 }; 00709 00710 /** Create vector by subtracting specified offset. 00711 */ 00712 inline Diff2D operator-(Diff2D const &a, Diff2D const &b) 00713 { 00714 return Diff2D(a.x - b.x, a.y - b.y); 00715 } 00716 00717 /** Create size by subtracting specified offset. 00718 */ 00719 inline Size2D operator-(Size2D const & s, Diff2D const &offset) 00720 { 00721 return Size2D(s.x - offset.x, s.y - offset.y); 00722 } 00723 00724 /** Calculate size of rect between two points. 00725 */ 00726 inline Point2D operator-(Point2D const & s, Diff2D const & offset) 00727 { 00728 return Point2D(s.x - offset.x, s.y - offset.y); 00729 } 00730 00731 /** The difference of two points is a size 00732 */ 00733 inline Size2D operator-(Point2D const & s, Point2D const & p) 00734 { 00735 return Size2D(s.x - p.x, s.y - p.y); 00736 } 00737 00738 /** Create vector by adding specified offset. 00739 */ 00740 inline Diff2D operator+(Diff2D const &a, Diff2D const &b) 00741 { 00742 return Diff2D(a.x + b.x, a.y + b.y); 00743 } 00744 00745 /** Create size by adding specified offset. 00746 */ 00747 inline Size2D operator+(Size2D const &a, Diff2D const &b) 00748 { 00749 return Size2D(a.x + b.x, a.y + b.y); 00750 } 00751 00752 /** Create point by adding specified offset. 00753 */ 00754 inline Point2D operator+(Point2D const &a, Diff2D const &b) 00755 { 00756 return Point2D(a.x + b.x, a.y + b.y); 00757 } 00758 00759 /** Add size and point 00760 */ 00761 inline Point2D operator+(Size2D const & s, Point2D const & p) 00762 { 00763 return Point2D(s.x + p.x, s.y + p.y); 00764 } 00765 00766 inline Point2D operator*(Point2D l, double r) 00767 { 00768 l *= r; 00769 return l; 00770 } 00771 00772 inline Point2D operator*(double l, Point2D r) 00773 { 00774 r *= l; 00775 return r; 00776 } 00777 00778 inline Size2D operator*(Size2D l, double r) 00779 { 00780 l *= r; 00781 return l; 00782 } 00783 00784 inline Size2D operator*(double l, Size2D r) 00785 { 00786 r *= l; 00787 return r; 00788 } 00789 00790 inline Point2D operator/(Point2D l, double r) 00791 { 00792 l /= r; 00793 return l; 00794 } 00795 00796 inline Size2D operator/(Size2D l, double r) 00797 { 00798 l /= r; 00799 return l; 00800 } 00801 00802 inline Point2D operator*(Point2D l, int r) 00803 { 00804 l *= r; 00805 return l; 00806 } 00807 00808 inline Point2D operator*(int l, Point2D r) 00809 { 00810 r *= l; 00811 return r; 00812 } 00813 00814 inline Size2D operator*(Size2D l, int r) 00815 { 00816 l *= r; 00817 return l; 00818 } 00819 00820 inline Size2D operator*(int l, Size2D r) 00821 { 00822 r *= l; 00823 return r; 00824 } 00825 00826 inline Point2D operator/(Point2D l, int r) 00827 { 00828 l /= r; 00829 return l; 00830 } 00831 00832 inline Size2D operator/(Size2D l, int r) 00833 { 00834 l /= r; 00835 return l; 00836 } 00837 00838 00839 /********************************************************/ 00840 /* */ 00841 /* Rect2D */ 00842 /* */ 00843 /********************************************************/ 00844 00845 /** \brief Two dimensional rectangle. 00846 00847 This class stores a 2-dimensional rectangular range or region. Thus, 00848 it follows the VIGRA convention that the upper left corner is inside 00849 the rectangle, while the lower right is 1 pixel to the right and below the 00850 last pixel in the rectangle. 00851 00852 A major advantage of this class is that it can be constructed from either 00853 a pair of \ref Point2D, or from a \ref Point2D and an extend 00854 (\ref Size2D). Rect2D overloads operators |=, &=, |, & to realize set 00855 union (in the sense of a minimal bounding rectangle) and set intersection. 00856 00857 \code 00858 Rect2D r1(Point2D(0,0), Point2D(10, 20)), 00859 r2(Point2D(10, 15), Size2D(20, 20)); 00860 Point2D p(0,100); 00861 00862 Rect2D r3 = r1 | r2; // upper left is (0,0), lower right is (30, 35) 00863 assert(r3.contains(r2)); 00864 assert(!r3.contains(p)); 00865 00866 r3 |= p; // lower right now (30,101) so that p is inside r3 00867 assert(r3.contains(p)); 00868 \endcode 00869 00870 <b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>"<br> 00871 Namespace: vigra 00872 */ 00873 class Rect2D 00874 { 00875 Point2D upperLeft_, lowerRight_; 00876 00877 public: 00878 /** Construct a null rectangle (isEmpty() will return true) 00879 */ 00880 Rect2D() 00881 {} 00882 00883 /** Construct a rectangle representing the given range 00884 * (lowerRight is considered to be outside the rectangle as 00885 * usual in the VIGRA) 00886 */ 00887 Rect2D(Point2D const &upperLeft, Point2D const &lowerRight) 00888 : upperLeft_(upperLeft), lowerRight_(lowerRight) 00889 {} 00890 00891 /** Construct a rectangle representing the given range 00892 */ 00893 Rect2D(int left, int top, int right, int bottom) 00894 : upperLeft_(left, top), lowerRight_(right, bottom) 00895 {} 00896 00897 /** Construct a rectangle of given position and size 00898 */ 00899 Rect2D(Point2D const &upperLeft, Size2D const &size) 00900 : upperLeft_(upperLeft), lowerRight_(upperLeft + size) 00901 {} 00902 00903 /** Construct a rectangle of given size at position (0,0) 00904 */ 00905 explicit Rect2D(Size2D const &size) 00906 : lowerRight_(Point2D(size)) 00907 {} 00908 00909 /** Return the first point (scan-order wise) which is 00910 * considered to be "in" the rectangle. 00911 */ 00912 Point2D const & upperLeft() const 00913 { 00914 return upperLeft_; 00915 } 00916 00917 /** Return the first point to the right and below the 00918 * rectangle. 00919 */ 00920 Point2D const & lowerRight() const 00921 { 00922 return lowerRight_; 00923 } 00924 00925 /** Change upperLeft() without changing lowerRight(), which 00926 * will change the size most probably. 00927 */ 00928 void setUpperLeft(Point2D const &ul) 00929 { 00930 upperLeft_ = ul; 00931 } 00932 00933 /** Change lowerRight() without changing upperLeft(), which 00934 * will change the size most probably. 00935 */ 00936 void setLowerRight(Point2D const &lr) 00937 { 00938 lowerRight_ = lr; 00939 } 00940 00941 /** Move the whole rectangle so that the given point will be 00942 * upperLeft() afterwards. 00943 */ 00944 void moveTo(Point2D const &newUpperLeft) 00945 { 00946 lowerRight_ += newUpperLeft - upperLeft_; 00947 upperLeft_ = newUpperLeft; 00948 } 00949 00950 /** Move the whole rectangle so that upperLeft() will become 00951 * Point2D(left, top) afterwards. 00952 */ 00953 void moveTo(int left, int top) 00954 { 00955 moveTo(Point2D(left, top)); 00956 } 00957 00958 /** Move the whole rectangle by the given 2D offset. 00959 */ 00960 void moveBy(Diff2D const &offset) 00961 { 00962 upperLeft_ += offset; 00963 lowerRight_ += offset; 00964 } 00965 00966 /** Move the whole rectangle by the given x- and y-offsets. 00967 */ 00968 void moveBy(int xOffset, int yOffset) 00969 { 00970 moveBy(Diff2D(xOffset, yOffset)); 00971 } 00972 00973 /** Return the left coordinate of this rectangle. 00974 */ 00975 int left() const 00976 { 00977 return upperLeft_.x; 00978 } 00979 00980 /** Return the top coordinate of this rectangle. 00981 */ 00982 int top() const 00983 { 00984 return upperLeft_.y; 00985 } 00986 00987 /** Return the right coordinate of this rectangle. That is the 00988 * first column to the right of the rectangle. 00989 */ 00990 int right() const 00991 { 00992 return lowerRight_.x; 00993 } 00994 00995 /** Return the bottom coordinate of this rectangle. That is the 00996 * first row below the rectangle. 00997 */ 00998 int bottom() const 00999 { 01000 return lowerRight_.y; 01001 } 01002 01003 /** Determine and return the width of this rectangle. It might be 01004 * zero or even negative, and if so, isEmpty() will return true. 01005 */ 01006 int width() const 01007 { 01008 return lowerRight_.x - upperLeft_.x; 01009 } 01010 01011 /** Determine and return the height of this rectangle. It might be 01012 * zero or even negative, and if so, isEmpty() will return true. 01013 */ 01014 int height() const 01015 { 01016 return lowerRight_.y - upperLeft_.y; 01017 } 01018 01019 /** Determine and return the area of this rectangle. That is, if 01020 * this rect isEmpty(), returns zero, otherwise returns 01021 * width()*height(). 01022 */ 01023 int area() const 01024 { 01025 return isEmpty() ? 0 : width()*height(); 01026 } 01027 01028 /** Determine and return the size of this rectangle. The width 01029 * and/or height might be zero or even negative, and if so, 01030 * isEmpty() will return true. 01031 */ 01032 Size2D size() const 01033 { 01034 return lowerRight_ - upperLeft_; 01035 } 01036 01037 /** Resize this rectangle to the given extents. This will move 01038 * the lower right corner only. 01039 */ 01040 void setSize(Size2D const &size) 01041 { 01042 lowerRight_ = upperLeft_ + size; 01043 } 01044 01045 /** Resize this rectangle to the given extents. This will move 01046 * the lower right corner only. 01047 */ 01048 void setSize(int width, int height) 01049 { 01050 lowerRight_ = upperLeft_ + Size2D(width, height); 01051 } 01052 01053 /** Increase the size of the rectangle by the given offset. This 01054 * will move the lower right corner only. (If any of offset's 01055 * components is negative, the rectangle will get smaller 01056 * accordingly.) 01057 */ 01058 void addSize(Size2D const &offset) 01059 { 01060 lowerRight_ += offset; 01061 } 01062 01063 /** Adds a border of the given width around the rectangle. That 01064 * means, upperLeft()'s components are moved by -borderWidth 01065 * and lowerRight()'s by borderWidth. (If borderWidth is 01066 * negative, the rectangle will get smaller accordingly.) 01067 */ 01068 void addBorder(int borderWidth) 01069 { 01070 upperLeft_ += Diff2D(-borderWidth, -borderWidth); 01071 lowerRight_ += Diff2D(borderWidth, borderWidth); 01072 } 01073 01074 /** Adds a border with possibly different widths in x- and 01075 * y-directions around the rectangle. That means, each x 01076 * component is moved borderWidth pixels and each y component 01077 * is moved borderHeight pixels to the outside. (If 01078 * borderWidth is negative, the rectangle will get smaller 01079 * accordingly.) 01080 */ 01081 void addBorder(int borderWidth, int borderHeight) 01082 { 01083 upperLeft_ += Diff2D(-borderWidth, -borderHeight); 01084 lowerRight_ += Diff2D(borderWidth, borderHeight); 01085 } 01086 01087 /// equality check 01088 bool operator==(Rect2D const &r) const 01089 { 01090 return (upperLeft_ == r.upperLeft_) && (lowerRight_ == r.lowerRight_); 01091 } 01092 01093 /// inequality check 01094 bool operator!=(Rect2D const &r) const 01095 { 01096 return (upperLeft_ != r.upperLeft_) || (lowerRight_ != r.lowerRight_); 01097 } 01098 01099 /** Return whether this rectangle is considered empty. It is 01100 * non-empty if both coordinates of the lower right corner are 01101 * greater than the corresponding coordinate of the upper left 01102 * corner. Uniting an empty rectangle with something will return 01103 * the bounding rectangle of the 'something', intersecting with an 01104 * empty rectangle will yield again an empty rectangle. 01105 */ 01106 bool isEmpty() const 01107 { 01108 return ((lowerRight_.x <= upperLeft_.x) || 01109 (lowerRight_.y <= upperLeft_.y)); 01110 } 01111 01112 /** Return whether this rectangle contains the given point. That 01113 * is, if the point lies within the valid range of an 01114 * ImageIterator walking from upperLeft() to lowerRight() 01115 * (excluding the latter). 01116 */ 01117 bool contains(Point2D const &p) const 01118 { 01119 return ((upperLeft_.x <= p.x) && 01120 (upperLeft_.y <= p.y) && 01121 (p.x < lowerRight_.x) && 01122 (p.y < lowerRight_.y)); 01123 } 01124 01125 /** Return whether this rectangle contains the given 01126 * one. <tt>r1.contains(r2)</tt> returns the same as 01127 * <tt>r1 == (r1|r2)</tt> (but is of course more 01128 * efficient). That also means, a rectangle (even an empty one!) 01129 * contains() any empty rectangle. 01130 */ 01131 bool contains(Rect2D const &r) const 01132 { 01133 return r.isEmpty() || 01134 contains(r.upperLeft()) && contains(r.lowerRight()-Diff2D(1,1)); 01135 } 01136 01137 /** Return whether this rectangle overlaps with the given 01138 * one. <tt>r1.intersects(r2)</tt> returns the same as 01139 * <tt>!(r1&r2).isEmpty()</tt> (but is of course much more 01140 * efficient). 01141 */ 01142 bool intersects(Rect2D const &r) const 01143 { 01144 return ((r.upperLeft_.x < lowerRight_.x) && 01145 (upperLeft_.x < r.lowerRight_.x) && 01146 (r.upperLeft_.y < lowerRight_.y) && 01147 (upperLeft_.y < r.lowerRight_.y)) 01148 && !r.isEmpty(); 01149 } 01150 01151 /** Modifies this rectangle by including the given point. The 01152 * result is the bounding rectangle of the rectangle and the 01153 * point. If isEmpty returns true, the union will be a 01154 * rectangle containing only the given point. 01155 */ 01156 Rect2D &operator|=(Point2D const &p) 01157 { 01158 if(isEmpty()) 01159 { 01160 upperLeft_ = p; 01161 lowerRight_ = p + Diff2D(1, 1); 01162 } 01163 else 01164 { 01165 if(p.x < upperLeft_.x) 01166 upperLeft_.x = p.x; 01167 if(p.y < upperLeft_.y) 01168 upperLeft_.y = p.y; 01169 if(lowerRight_.x <= p.x) 01170 lowerRight_.x = p.x + 1; 01171 if(lowerRight_.y <= p.y) 01172 lowerRight_.y = p.y + 1; 01173 } 01174 return *this; 01175 } 01176 01177 /** Returns the union of this rectangle and the given 01178 * point. The result is the bounding rectangle of the 01179 * rectangle and the point. If isEmpty returns true, the union 01180 * will be a rectangle containing only the given point. 01181 */ 01182 Rect2D operator|(Point2D const &p) const 01183 { 01184 Rect2D result(*this); 01185 result |= p; 01186 return result; 01187 } 01188 01189 /** Modifies this rectangle by uniting it with the given 01190 * one. The result is the bounding rectangle of both 01191 * rectangles. If one of the rectangles isEmpty(), the union 01192 * will be the other one. 01193 */ 01194 Rect2D &operator|=(Rect2D const &r) 01195 { 01196 if(r.isEmpty()) 01197 return *this; 01198 if(isEmpty()) 01199 return operator=(r); 01200 01201 if(r.upperLeft_.x < upperLeft_.x) 01202 upperLeft_.x = r.upperLeft_.x; 01203 if(r.upperLeft_.y < upperLeft_.y) 01204 upperLeft_.y = r.upperLeft_.y; 01205 if(lowerRight_.x < r.lowerRight_.x) 01206 lowerRight_.x = r.lowerRight_.x; 01207 if(lowerRight_.y < r.lowerRight_.y) 01208 lowerRight_.y = r.lowerRight_.y; 01209 return *this; 01210 } 01211 01212 /** Returns the union of this rectangle and the given one. The 01213 * result is the bounding rectangle of both rectangles. If one 01214 * of the rectangles isEmpty(), the union will be the other 01215 * one. 01216 */ 01217 Rect2D operator|(Rect2D const &r) const 01218 { 01219 Rect2D result(*this); 01220 result |= r; 01221 return result; 01222 } 01223 01224 /** Modifies this rectangle by intersecting it with the given 01225 * point. The result is the bounding rect of the point (with 01226 * width and height equal to 1) if it was contained in the 01227 * original rect, or an empty rect otherwise. 01228 */ 01229 Rect2D &operator&=(Point2D const &p) 01230 { 01231 if(contains(p)) 01232 { 01233 upperLeft_ = p; 01234 lowerRight_ = p + Diff2D(1, 1); 01235 } 01236 else 01237 lowerRight_ = upperLeft_; 01238 return *this; 01239 } 01240 01241 /** Intersects this rectangle with the given point. The result 01242 * is the bounding rect of the point (with width and height 01243 * equal to 1) if it was contained in the original rect, or an 01244 * empty rect otherwise. 01245 */ 01246 Rect2D operator&(Point2D const &p) const 01247 { 01248 Rect2D result(*this); 01249 result &= p; 01250 return result; 01251 } 01252 01253 /** Modifies this rectangle by intersecting it with the given 01254 * one. The result is the maximal rectangle contained in both 01255 * original ones. Intersecting with an empty rectangle will 01256 * yield again an empty rectangle. 01257 */ 01258 Rect2D &operator&=(Rect2D const &r) 01259 { 01260 if(isEmpty()) 01261 return *this; 01262 if(r.isEmpty()) 01263 return operator=(r); 01264 01265 if(upperLeft_.x < r.upperLeft_.x) 01266 upperLeft_.x = r.upperLeft_.x; 01267 if(upperLeft_.y < r.upperLeft_.y) 01268 upperLeft_.y = r.upperLeft_.y; 01269 if(r.lowerRight_.x < lowerRight_.x) 01270 lowerRight_.x = r.lowerRight_.x; 01271 if(r.lowerRight_.y < lowerRight_.y) 01272 lowerRight_.y = r.lowerRight_.y; 01273 return *this; 01274 } 01275 01276 /** Intersects this rectangle with the given one. The result 01277 * is the maximal rectangle contained in both original ones. 01278 * Intersecting with an empty rectangle will yield again an 01279 * empty rectangle. 01280 */ 01281 Rect2D operator&(Rect2D const &r) const 01282 { 01283 Rect2D result(*this); 01284 result &= r; 01285 return result; 01286 } 01287 }; 01288 01289 /********************************************************/ 01290 /* */ 01291 /* Dist2D */ 01292 /* */ 01293 /********************************************************/ 01294 01295 /** @deprecated use \ref vigra::Diff2D instead 01296 */ 01297 class Dist2D 01298 { 01299 public: 01300 Dist2D(int the_width, int the_height) 01301 : width(the_width), 01302 height(the_height) 01303 {} 01304 01305 Dist2D(Dist2D const & s) 01306 : width(s.width), 01307 height(s.height) 01308 {} 01309 01310 Dist2D & operator=(Dist2D const & s) 01311 { 01312 if(this != &s) 01313 { 01314 width = s.width; 01315 height = s.height; 01316 } 01317 return *this; 01318 } 01319 01320 Dist2D & operator+=(Dist2D const & s) 01321 { 01322 width += s.width; 01323 height += s.height; 01324 01325 return *this; 01326 } 01327 01328 Dist2D operator+(Dist2D const & s) const 01329 { 01330 Dist2D ret(*this); 01331 ret += s; 01332 01333 return ret; 01334 } 01335 01336 operator Diff2D() 01337 { return Diff2D(width, height); } 01338 01339 int width; 01340 int height; 01341 }; 01342 01343 //@} 01344 01345 /** 01346 * Output a \ref vigra::Diff2D as a tuple. 01347 * Example Diff2D(-12, 13) -> "(-12, 13)" 01348 */ 01349 inline 01350 std::ostream & operator<<(std::ostream & o, vigra::Diff2D const & d) 01351 { 01352 o << '(' << d.x << ", " << d.y << ')'; 01353 return o; 01354 } 01355 01356 /** 01357 * Output a \ref vigra::Size2D. 01358 * Example Size2D(100, 200) -> "(100x200)" 01359 */ 01360 inline 01361 std::ostream &operator <<(std::ostream &s, vigra::Size2D const &d) 01362 { 01363 s << '(' << d.x << 'x' << d.y << ')'; 01364 return s; 01365 } 01366 01367 /** 01368 * Output a description of a \ref vigra::Rect2D. 01369 * Example Rect2D(10, 10, 30, 20) -> "[(10, 10) to (30, 20) = (20x10)]" 01370 */ 01371 inline 01372 std::ostream &operator <<(std::ostream &s, vigra::Rect2D const &r) 01373 { 01374 s << "[" << r.upperLeft() << " to " << r.lowerRight() 01375 << " = " << r.size() << "]"; 01376 return s; 01377 } 01378 01379 } // namespace vigra 01380 01381 #endif // VIGRA_DIFF2D_HXX
© Ullrich Köthe (koethe@informatik.uni-hamburg.de) |
html generated using doxygen and Python
|