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

html generated using doxygen and Python
VIGRA 1.3.3 (18 Aug 2005)