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