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

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
VIGRA 1.6.0 (5 Nov 2009)