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