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