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