[ 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.2.0, Aug 07 2003 ) */ 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 & d) {} 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 double magnitude() const 00339 { 00340 return VIGRA_CSTD::sqrt((double)(x*x + y*y)); 00341 } 00342 00343 /** Equality. 00344 */ 00345 bool operator==(Diff2D const & r) const 00346 { 00347 return (x == r.x) && (y == r.y); 00348 } 00349 00350 /** Inequality. 00351 */ 00352 bool operator!=(Diff2D const & r) const 00353 { 00354 return (x != r.x) || (y != r.y); 00355 } 00356 00357 /** Used for both access to the current x-coordinate \em and 00358 to specify that an iterator navigation command is to be 00359 applied in x-direction. <br> 00360 usage: <TT> x = diff2d.x </TT> (use \p Diff2D::x as component of difference vector) <br> 00361 or <TT> ++diff.x </TT> (use Diff2D as iterator, move right) 00362 */ 00363 int x; 00364 /** Used for both access to the current y-coordinate \em and 00365 to specify that an iterator navigation command is to be 00366 applied in y-direction. <br> 00367 usage: <TT> y = diff2d.y </TT> (use \p Diff2D::y as component of difference vector) <br> 00368 or <TT> ++diff.y </TT> (use Diff2D as iterator, move right) 00369 */ 00370 int y; 00371 00372 /** Access current coordinate. 00373 */ 00374 reference operator*() const 00375 { 00376 return *this; 00377 } 00378 00379 /** Read coordinate at an offset. 00380 */ 00381 index_reference operator()(int const & dx, int const & dy) const 00382 { 00383 return Diff2D(x + dx, y + dy); 00384 } 00385 00386 /** Read coordinate at an offset. 00387 */ 00388 index_reference operator[](Diff2D const & offset) const 00389 { 00390 return Diff2D(x + offset.x, y + offset.y); 00391 } 00392 00393 /** Read vector components. 00394 */ 00395 int operator[](int index) const 00396 { 00397 return (&x)[index]; 00398 } 00399 00400 /** Access current coordinate. 00401 */ 00402 pointer operator->() const 00403 { 00404 return this; 00405 } 00406 00407 /** Get a row iterator at the current position. 00408 */ 00409 row_iterator rowIterator() const 00410 { return row_iterator(*this); } 00411 00412 /** Get a column iterator at the current position. 00413 */ 00414 column_iterator columnIterator() const 00415 { return column_iterator(*this); } 00416 }; 00417 00418 00419 template <> 00420 struct IteratorTraits<Diff2D > 00421 { 00422 typedef Diff2D Iterator; 00423 typedef Iterator iterator; 00424 typedef iterator::iterator_category iterator_category; 00425 typedef iterator::value_type value_type; 00426 typedef iterator::reference reference; 00427 typedef iterator::index_reference index_reference; 00428 typedef iterator::pointer pointer; 00429 typedef iterator::difference_type difference_type; 00430 typedef iterator::row_iterator row_iterator; 00431 typedef iterator::column_iterator column_iterator; 00432 typedef StandardConstValueAccessor<Diff2D> DefaultAccessor; 00433 typedef StandardConstValueAccessor<Diff2D> default_accessor; 00434 00435 }; 00436 00437 00438 /********************************************************/ 00439 /* */ 00440 /* Size2D */ 00441 /* */ 00442 /********************************************************/ 00443 00444 /** \brief Two dimensional size object. 00445 00446 Specializes \ref Diff2D for the specification of a 2-dimensional 00447 extent, in contrast to a point or position (for the latter 00448 use \ref Point2D). 00449 00450 \code 00451 // create an image that is 10 pixels squared 00452 Image new_image(Size2D(10,10)); 00453 \endcode 00454 00455 <b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>"<br> 00456 Namespace: vigra 00457 */ 00458 class Size2D : public Diff2D 00459 { 00460 public: 00461 /** Default Constructor. Init point at position (0,0) 00462 */ 00463 Size2D() 00464 {} 00465 00466 /** Construct point at given position. 00467 */ 00468 Size2D(int width, int height) 00469 : Diff2D(width, height) 00470 {} 00471 00472 /** Copy Constructor. 00473 */ 00474 Size2D(Size2D const & v) 00475 : Diff2D(v) 00476 {} 00477 00478 /** Explicit conversion Constructor. 00479 */ 00480 explicit Size2D(Diff2D const & v) 00481 : Diff2D(v) 00482 {} 00483 00484 /** Query the width 00485 */ 00486 int width() const 00487 { 00488 return x; 00489 } 00490 00491 /** Query the height 00492 */ 00493 int height() const 00494 { 00495 return y; 00496 } 00497 00498 /** Copy Assigment. 00499 */ 00500 Size2D & operator=(Diff2D const & v) 00501 { 00502 return static_cast<Size2D &>(Diff2D::operator=(v)); 00503 } 00504 00505 /** Unary negation. 00506 */ 00507 Size2D operator-() const 00508 { 00509 return Size2D(-x, -y); 00510 } 00511 00512 /** Increase size by specified offset. 00513 */ 00514 Size2D & operator+=(Diff2D const & offset) 00515 { 00516 return static_cast<Size2D &>(Diff2D::operator+=(offset)); 00517 } 00518 00519 /** Decrease size by specified offset. 00520 */ 00521 Size2D & operator-=(Diff2D const & offset) 00522 { 00523 return static_cast<Size2D &>(Diff2D::operator-=(offset)); 00524 } 00525 }; 00526 00527 /********************************************************/ 00528 /* */ 00529 /* Point2D */ 00530 /* */ 00531 /********************************************************/ 00532 00533 /** \brief Two dimensional point or position. 00534 00535 Specializes \ref Diff2D for the specification of a 2-dimensional 00536 point or position, in contrast to an extent (for the latter 00537 use \ref Size2D). 00538 00539 \code 00540 // access an image at a point 00541 value = image[Point2D(10, 20)]; 00542 \endcode 00543 00544 <b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>"<br> 00545 Namespace: vigra 00546 */ 00547 class Point2D : public Diff2D 00548 { 00549 public: 00550 /** The iterator's value type: a coordinate. 00551 */ 00552 typedef Point2D PixelType; 00553 00554 /** The iterator's value type: a coordinate. 00555 */ 00556 typedef Point2D value_type; 00557 00558 /** the iterator's reference type (return type of <TT>*iter</TT>) 00559 */ 00560 typedef Point2D const & reference; 00561 00562 /** the iterator's index reference type (return type of <TT>iter[diff]</TT>) 00563 */ 00564 typedef Point2D index_reference; 00565 00566 /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>) 00567 */ 00568 typedef Point2D const * pointer; 00569 00570 /** Default Constructor. Init point at position (0,0) 00571 */ 00572 Point2D() 00573 {} 00574 00575 /** Construct point at given position. 00576 */ 00577 Point2D(int x, int y) 00578 : Diff2D(x, y) 00579 {} 00580 00581 /** Copy Constructor. 00582 */ 00583 Point2D(Point2D const & v) 00584 : Diff2D(v) 00585 {} 00586 00587 /** Explicit conversion Constructor. 00588 */ 00589 explicit Point2D(Diff2D const & v) 00590 : Diff2D(v) 00591 {} 00592 00593 /** Query the points' x coordinate 00594 */ 00595 int px() const 00596 { 00597 return x; 00598 } 00599 00600 /** Query the points' y coordinate 00601 */ 00602 int py() const 00603 { 00604 return y; 00605 } 00606 00607 /** Copy Assigment. 00608 */ 00609 Point2D & operator=(Diff2D const & v) 00610 { 00611 return static_cast<Point2D &>(Diff2D::operator=(v)); 00612 } 00613 00614 /** Unary negation. 00615 */ 00616 Point2D operator-() const 00617 { 00618 return Point2D(-x, -y); 00619 } 00620 00621 /** Increase point coordinates by specified offset. 00622 */ 00623 Point2D & operator+=(Diff2D const & offset) 00624 { 00625 return static_cast<Point2D &>(Diff2D::operator+=(offset)); 00626 } 00627 00628 /** Decrease point coordinates by specified offset. 00629 */ 00630 Point2D & operator-=(Diff2D const & offset) 00631 { 00632 return static_cast<Point2D &>(Diff2D::operator-=(offset)); 00633 } 00634 00635 /** Access current point coordinate. 00636 */ 00637 reference operator*() const 00638 { 00639 return *this; 00640 } 00641 00642 /** Read point coordinate at an offset. 00643 */ 00644 index_reference operator()(int const & dx, int const & dy) const 00645 { 00646 return Point2D(x + dx, y + dy); 00647 } 00648 00649 /** Read point coordinate at an offset. 00650 */ 00651 index_reference operator[](Diff2D const & offset) const 00652 { 00653 return Point2D(x + offset.x, y + offset.y); 00654 } 00655 00656 /** Access current point coordinate. 00657 */ 00658 pointer operator->() const 00659 { 00660 return this; 00661 } 00662 }; 00663 00664 /** Create vector by subtracting specified offset. 00665 */ 00666 inline Diff2D operator-(Diff2D const &a, Diff2D const &b) 00667 { 00668 return Diff2D(a.x - b.x, a.y - b.y); 00669 } 00670 00671 /** Create size by subtracting specified offset. 00672 */ 00673 inline Size2D operator-(Size2D const & s, Diff2D const &offset) 00674 { 00675 return Size2D(s.x - offset.x, s.y - offset.y); 00676 } 00677 00678 /** Calculate size of rect between two points. 00679 */ 00680 inline Point2D operator-(Point2D const & s, Diff2D const & offset) 00681 { 00682 return Point2D(s.x - offset.x, s.y - offset.y); 00683 } 00684 00685 /** The difference of two points is a size 00686 */ 00687 inline Size2D operator-(Point2D const & s, Point2D const & p) 00688 { 00689 return Size2D(s.x - p.x, s.y - p.y); 00690 } 00691 00692 /** Create vector by adding specified offset. 00693 */ 00694 inline Diff2D operator+(Diff2D const &a, Diff2D const &b) 00695 { 00696 return Diff2D(a.x + b.x, a.y + b.y); 00697 } 00698 00699 /** Create size by adding specified offset. 00700 */ 00701 inline Size2D operator+(Size2D const &a, Diff2D const &b) 00702 { 00703 return Size2D(a.x + b.x, a.y + b.y); 00704 } 00705 00706 /** Create point by adding specified offset. 00707 */ 00708 inline Point2D operator+(Point2D const &a, Diff2D const &b) 00709 { 00710 return Point2D(a.x + b.x, a.y + b.y); 00711 } 00712 00713 /** Add size and point 00714 */ 00715 inline Point2D operator+(Size2D const & s, Point2D const & p) 00716 { 00717 return Point2D(s.x + p.x, s.y + p.y); 00718 } 00719 00720 /********************************************************/ 00721 /* */ 00722 /* Rect2D */ 00723 /* */ 00724 /********************************************************/ 00725 00726 /** \brief Two dimensional rectangle. 00727 00728 This class stores a 2-dimensional rectangular range or region. Thus, 00729 it follows the VIGRA convention that the upper left corner is inside 00730 the rectangle, while the lower right is 1 pixel to the right and below the 00731 last pixel in the rectangle. 00732 00733 A major advantage of this class is that it can be constructed from either 00734 a pair of \ref Point2D, or from a \ref Point2D and an extend 00735 (\ref Size2D). Rect2D overloads operators |=, &=, |, & to realize set 00736 union (in the sense of a minimal bounding rectangle) and set intersection. 00737 00738 \code 00739 Rect2D r1(Point2D(0,0), Point2D(10, 20)), 00740 r2(Point2D(10, 15), Size2D(20, 20)); 00741 Point2D p(0,100); 00742 00743 Rect2D r3 = r1 | r2; // upper left is (0,0), lower right is (30, 35) 00744 assert(r3.contains(r2)); 00745 assert(!r3.contains(p)); 00746 00747 r3 |= p; // lower right now (30,101) so that p is inside r3 00748 assert(r3.contains(p)); 00749 \endcode 00750 00751 <b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>"<br> 00752 Namespace: vigra 00753 */ 00754 class Rect2D 00755 { 00756 Point2D upperLeft_, lowerRight_; 00757 00758 public: 00759 /** Construct a null rectangle (isEmpty() will return true) 00760 */ 00761 Rect2D() 00762 {} 00763 00764 /** Construct a rectangle representing the given range 00765 * (lowerRight is considered to be outside the rectangle as 00766 * usual in the VIGRA) 00767 */ 00768 Rect2D(Point2D const &upperLeft, Point2D const &lowerRight) 00769 : upperLeft_(upperLeft), lowerRight_(lowerRight) 00770 {} 00771 00772 /** Construct a rectangle representing the given range 00773 */ 00774 Rect2D(int left, int top, int right, int bottom) 00775 : upperLeft_(left, top), lowerRight_(right, bottom) 00776 {} 00777 00778 /** Construct a rectangle of given position and size 00779 */ 00780 Rect2D(Point2D const &upperLeft, Size2D const &size) 00781 : upperLeft_(upperLeft), lowerRight_(upperLeft + size) 00782 {} 00783 00784 /** Construct a rectangle of given size at position (0,0) 00785 */ 00786 explicit Rect2D(Size2D const &size) 00787 : lowerRight_(Point2D(size)) 00788 {} 00789 00790 /** Return the first point (scan-order wise) which is 00791 * considered to be "in" the rectangle. 00792 */ 00793 Point2D const & upperLeft() const 00794 { 00795 return upperLeft_; 00796 } 00797 00798 /** Return the first point to the right and below the 00799 * rectangle. 00800 */ 00801 Point2D const & lowerRight() const 00802 { 00803 return lowerRight_; 00804 } 00805 00806 /** Change upperLeft() without changing lowerRight(), which 00807 * will change the size most probably. 00808 */ 00809 void setUpperLeft(Point2D const &ul) 00810 { 00811 upperLeft_ = ul; 00812 } 00813 00814 /** Change lowerRight() without changing upperLeft(), which 00815 * will change the size most probably. 00816 */ 00817 void setLowerRight(Point2D const &lr) 00818 { 00819 lowerRight_ = lr; 00820 } 00821 00822 /** Move the whole rectangle so that the given point will be 00823 * upperLeft() afterwards. 00824 */ 00825 void moveTo(Point2D const &newUpperLeft) 00826 { 00827 lowerRight_ += newUpperLeft - upperLeft_; 00828 upperLeft_ = newUpperLeft; 00829 } 00830 00831 /** Move the whole rectangle so that upperLeft() will become 00832 * Point2D(left, top) afterwards. 00833 */ 00834 void moveTo(int left, int top) 00835 { 00836 moveTo(Point2D(left, top)); 00837 } 00838 00839 /** Move the whole rectangle by the given 2D offset. 00840 */ 00841 void moveBy(Diff2D const &offset) 00842 { 00843 upperLeft_ += offset; 00844 lowerRight_ += offset; 00845 } 00846 00847 /** Move the whole rectangle by the given x- and y-offsets. 00848 */ 00849 void moveBy(int xOffset, int yOffset) 00850 { 00851 moveBy(Diff2D(xOffset, yOffset)); 00852 } 00853 00854 /** Return the left coordinate of this rectangle. 00855 */ 00856 int left() const 00857 { 00858 return upperLeft_.x; 00859 } 00860 00861 /** Return the top coordinate of this rectangle. 00862 */ 00863 int top() const 00864 { 00865 return upperLeft_.y; 00866 } 00867 00868 /** Return the right coordinate of this rectangle. That is the 00869 * first column to the right of the rectangle. 00870 */ 00871 int right() const 00872 { 00873 return lowerRight_.x; 00874 } 00875 00876 /** Return the bottom coordinate of this rectangle. That is the 00877 * first row below the rectangle. 00878 */ 00879 int bottom() const 00880 { 00881 return lowerRight_.y; 00882 } 00883 00884 /** Determine and return the width of this rectangle. It might be 00885 * zero or even negative, and if so, isEmpty() will return true. 00886 */ 00887 int width() const 00888 { 00889 return lowerRight_.x - upperLeft_.x; 00890 } 00891 00892 /** Determine and return the height of this rectangle. It might be 00893 * zero or even negative, and if so, isEmpty() will return true. 00894 */ 00895 int height() const 00896 { 00897 return lowerRight_.y - upperLeft_.y; 00898 } 00899 00900 /** Determine and return the area of this rectangle. That is, if 00901 * this rect isEmpty(), returns zero, otherwise returns 00902 * width()*height(). 00903 */ 00904 int area() const 00905 { 00906 return isEmpty() ? 0 : width()*height(); 00907 } 00908 00909 /** Determine and return the size of this rectangle. The width 00910 * and/or height might be zero or even negative, and if so, 00911 * isEmpty() will return true. 00912 */ 00913 Size2D size() const 00914 { 00915 return lowerRight_ - upperLeft_; 00916 } 00917 00918 /** Resize this rectangle to the given extents. This will move 00919 * the lower right corner only. 00920 */ 00921 void setSize(Size2D const &size) 00922 { 00923 lowerRight_ = upperLeft_ + size; 00924 } 00925 00926 /** Resize this rectangle to the given extents. This will move 00927 * the lower right corner only. 00928 */ 00929 void setSize(int width, int height) 00930 { 00931 lowerRight_ = upperLeft_ + Size2D(width, height); 00932 } 00933 00934 /** Increase the size of the rectangle by the given offset. This 00935 * will move the lower right corner only. (If any of offset's 00936 * components is negative, the rectangle will get smaller 00937 * accordingly.) 00938 */ 00939 void addSize(Size2D const &offset) 00940 { 00941 lowerRight_ += offset; 00942 } 00943 00944 /** Adds a border of the given width around the rectangle. That 00945 * means, upperLeft()'s components are moved by -borderWidth 00946 * and lowerRight()'s by borderWidth. (If borderWidth is 00947 * negative, the rectangle will get smaller accordingly.) 00948 */ 00949 void addBorder(int borderWidth) 00950 { 00951 upperLeft_ += Diff2D(-borderWidth, -borderWidth); 00952 lowerRight_ += Diff2D(borderWidth, borderWidth); 00953 } 00954 00955 /** Adds a border with possibly different widths in x- and 00956 * y-directions around the rectangle. That means, each x 00957 * component is moved borderWidth pixels and each y component 00958 * is moved borderHeight pixels to the outside. (If 00959 * borderWidth is negative, the rectangle will get smaller 00960 * accordingly.) 00961 */ 00962 void addBorder(int borderWidth, int borderHeight) 00963 { 00964 upperLeft_ += Diff2D(-borderWidth, -borderHeight); 00965 lowerRight_ += Diff2D(borderWidth, borderHeight); 00966 } 00967 00968 /// equality check 00969 bool operator==(Rect2D const &r) const 00970 { 00971 return (upperLeft_ == r.upperLeft_) && (lowerRight_ == r.lowerRight_); 00972 } 00973 00974 /// inequality check 00975 bool operator!=(Rect2D const &r) const 00976 { 00977 return (upperLeft_ != r.upperLeft_) || (lowerRight_ != r.lowerRight_); 00978 } 00979 00980 /** Return whether this rectangle is considered empty. It is 00981 * non-empty if both coordinates of the lower right corner are 00982 * greater than the corresponding coordinate of the upper left 00983 * corner. Uniting an empty rectangle with something will return 00984 * the bounding rectangle of the 'something', intersecting with an 00985 * empty rectangle will yield again an empty rectangle. 00986 */ 00987 bool isEmpty() const 00988 { 00989 return ((lowerRight_.x <= upperLeft_.x) || 00990 (lowerRight_.y <= upperLeft_.y)); 00991 } 00992 00993 /** Return whether this rectangle contains the given point. That 00994 * is, if the point lies within the valid range of an 00995 * ImageIterator walking from upperLeft() to lowerRight() 00996 * (excluding the latter). 00997 */ 00998 bool contains(Point2D const &p) const 00999 { 01000 return ((upperLeft_.x <= p.x) && 01001 (upperLeft_.y <= p.y) && 01002 (p.x < lowerRight_.x) && 01003 (p.y < lowerRight_.y)); 01004 } 01005 01006 /** Return whether this rectangle contains the given 01007 * one. <tt>r1.contains(r2)</tt> returns the same as 01008 * <tt>r1 == (r1|r2)</tt> (but is of course more 01009 * efficient). That also means, a rectangle (even an empty one!) 01010 * contains() any empty rectangle. 01011 */ 01012 bool contains(Rect2D const &r) const 01013 { 01014 return r.isEmpty() || 01015 contains(r.upperLeft()) && contains(r.lowerRight()-Diff2D(1,1)); 01016 } 01017 01018 /** Return whether this rectangle overlaps with the given 01019 * one. <tt>r1.intersects(r2)</tt> returns the same as 01020 * <tt>!(r1&r2).isEmpty()</tt> (but is of course much more 01021 * efficient). 01022 */ 01023 bool intersects(Rect2D const &r) const 01024 { 01025 return ((r.upperLeft_.x < lowerRight_.x) && 01026 (upperLeft_.x < r.lowerRight_.x) && 01027 (r.upperLeft_.y < lowerRight_.y) && 01028 (upperLeft_.y < r.lowerRight_.y)) 01029 && !r.isEmpty(); 01030 } 01031 01032 /** Modifies this rectangle by including the given point. The 01033 * result is the bounding rectangle of the rectangle and the 01034 * point. If isEmpty returns true, the union will be a 01035 * rectangle containing only the given point. 01036 */ 01037 Rect2D &operator|=(Point2D const &p) 01038 { 01039 if(isEmpty()) 01040 { 01041 upperLeft_ = p; 01042 lowerRight_ = p + Diff2D(1, 1); 01043 } 01044 else 01045 { 01046 if(p.x < upperLeft_.x) 01047 upperLeft_.x = p.x; 01048 if(p.y < upperLeft_.y) 01049 upperLeft_.y = p.y; 01050 if(lowerRight_.x <= p.x) 01051 lowerRight_.x = p.x + 1; 01052 if(lowerRight_.y <= p.y) 01053 lowerRight_.y = p.y + 1; 01054 } 01055 return *this; 01056 } 01057 01058 /** Returns the union of this rectangle and the given 01059 * point. The result is the bounding rectangle of the 01060 * rectangle and the point. If isEmpty returns true, the union 01061 * will be a rectangle containing only the given point. 01062 */ 01063 Rect2D operator|(Point2D const &p) 01064 { 01065 Rect2D result(*this); 01066 result |= p; 01067 return result; 01068 } 01069 01070 /** Modifies this rectangle by uniting it with the given 01071 * one. The result is the bounding rectangle of both 01072 * rectangles. If one of the rectangles isEmpty(), the union 01073 * will be the other one. 01074 */ 01075 Rect2D &operator|=(Rect2D const &r) 01076 { 01077 if(r.isEmpty()) 01078 return *this; 01079 if(isEmpty()) 01080 return operator=(r); 01081 01082 if(r.upperLeft_.x < upperLeft_.x) 01083 upperLeft_.x = r.upperLeft_.x; 01084 if(r.upperLeft_.y < upperLeft_.y) 01085 upperLeft_.y = r.upperLeft_.y; 01086 if(lowerRight_.x < r.lowerRight_.x) 01087 lowerRight_.x = r.lowerRight_.x; 01088 if(lowerRight_.y < r.lowerRight_.y) 01089 lowerRight_.y = r.lowerRight_.y; 01090 return *this; 01091 } 01092 01093 /** Returns the union of this rectangle and the given one. The 01094 * result is the bounding rectangle of both rectangles. If one 01095 * of the rectangles isEmpty(), the union will be the other 01096 * one. 01097 */ 01098 Rect2D operator|(Rect2D const &r) const 01099 { 01100 Rect2D result(*this); 01101 result |= r; 01102 return result; 01103 } 01104 01105 /** Modifies this rectangle by intersecting it with the given 01106 * point. The result is the bounding rect of the point (with 01107 * width and height equal to 1) if it was contained in the 01108 * original rect, or an empty rect otherwise. 01109 */ 01110 Rect2D &operator&=(Point2D const &p) 01111 { 01112 if(contains(p)) 01113 { 01114 upperLeft_ = p; 01115 lowerRight_ = p + Diff2D(1, 1); 01116 } 01117 else 01118 lowerRight_ = upperLeft_; 01119 return *this; 01120 } 01121 01122 /** Intersects this rectangle with the given point. The result 01123 * is the bounding rect of the point (with width and height 01124 * equal to 1) if it was contained in the original rect, or an 01125 * empty rect otherwise. 01126 */ 01127 Rect2D operator&(Point2D const &p) const 01128 { 01129 Rect2D result(*this); 01130 result &= p; 01131 return result; 01132 } 01133 01134 /** Modifies this rectangle by intersecting it with the given 01135 * one. The result is the maximal rectangle contained in both 01136 * original ones. Intersecting with an empty rectangle will 01137 * yield again an empty rectangle. 01138 */ 01139 Rect2D &operator&=(Rect2D const &r) 01140 { 01141 if(isEmpty()) 01142 return *this; 01143 if(r.isEmpty()) 01144 return operator=(r); 01145 01146 if(upperLeft_.x < r.upperLeft_.x) 01147 upperLeft_.x = r.upperLeft_.x; 01148 if(upperLeft_.y < r.upperLeft_.y) 01149 upperLeft_.y = r.upperLeft_.y; 01150 if(r.lowerRight_.x < lowerRight_.x) 01151 lowerRight_.x = r.lowerRight_.x; 01152 if(r.lowerRight_.y < lowerRight_.y) 01153 lowerRight_.y = r.lowerRight_.y; 01154 return *this; 01155 } 01156 01157 /** Intersects this rectangle with the given one. The result 01158 * is the maximal rectangle contained in both original ones. 01159 * Intersecting with an empty rectangle will yield again an 01160 * empty rectangle. 01161 */ 01162 Rect2D operator&(Rect2D const &r) const 01163 { 01164 Rect2D result(*this); 01165 result &= r; 01166 return result; 01167 } 01168 }; 01169 01170 /********************************************************/ 01171 /* */ 01172 /* Dist2D */ 01173 /* */ 01174 /********************************************************/ 01175 01176 /** @deprecated use \ref vigra::Diff2D instead 01177 */ 01178 class Dist2D 01179 { 01180 public: 01181 Dist2D(int the_width, int the_height) 01182 : width(the_width), 01183 height(the_height) 01184 {} 01185 01186 Dist2D(Dist2D const & s) 01187 : width(s.width), 01188 height(s.height) 01189 {} 01190 01191 Dist2D & operator=(Dist2D const & s) 01192 { 01193 if(this != &s) 01194 { 01195 width = s.width; 01196 height = s.height; 01197 } 01198 return *this; 01199 } 01200 01201 Dist2D & operator+=(Dist2D const & s) 01202 { 01203 width += s.width; 01204 height += s.height; 01205 01206 return *this; 01207 } 01208 01209 Dist2D operator+(Dist2D const & s) const 01210 { 01211 Dist2D ret(*this); 01212 ret += s; 01213 01214 return ret; 01215 } 01216 01217 operator Diff2D() 01218 { return Diff2D(width, height); } 01219 01220 int width; 01221 int height; 01222 }; 01223 01224 //@} 01225 01226 } // namespace vigra 01227 01228 inline 01229 std::ostream & operator<<(std::ostream & o, vigra::Diff2D const & d) 01230 { 01231 o << '(' << d.x << ", " << d.y << ')'; 01232 return o; 01233 } 01234 01235 inline 01236 std::ostream &operator <<(std::ostream &s, vigra::Size2D const &d) 01237 { 01238 s << '(' << d.x << 'x' << d.y << ')'; 01239 return s; 01240 } 01241 01242 inline 01243 std::ostream &operator <<(std::ostream &s, vigra::Rect2D const &r) 01244 { 01245 s << "[" << r.upperLeft() << " to " << r.lowerRight() 01246 << " = " << r.size() << "]"; 01247 return s; 01248 } 01249 01250 #endif // VIGRA_DIFF2D_HXX
© Ullrich Köthe (koethe@informatik.uni-hamburg.de) |
html generated using doxygen and Python
|