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