[ VIGRA Homepage | Class Index | Function Index | File Index | 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 /*    ( 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)