[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]

details vigra/diff2d.hxx VIGRA

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>&nbsp; ++diff.x &nbsp; </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>&nbsp; ++diff.y &nbsp; </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)
Cognitive Systems Group, University of Hamburg, Germany

html generated using doxygen and Python
VIGRA 1.2.0 (7 Aug 2003)