[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

diff2d.hxx
1/************************************************************************/
2/* */
3/* Copyright 1998-2003 by Hans Meine */
4/* */
5/* This file is part of the VIGRA computer vision library. */
6/* The VIGRA Website is */
7/* http://hci.iwr.uni-heidelberg.de/vigra/ */
8/* Please direct questions, bug reports, and contributions to */
9/* ullrich.koethe@iwr.uni-heidelberg.de or */
10/* vigra@informatik.uni-hamburg.de */
11/* */
12/* Permission is hereby granted, free of charge, to any person */
13/* obtaining a copy of this software and associated documentation */
14/* files (the "Software"), to deal in the Software without */
15/* restriction, including without limitation the rights to use, */
16/* copy, modify, merge, publish, distribute, sublicense, and/or */
17/* sell copies of the Software, and to permit persons to whom the */
18/* Software is furnished to do so, subject to the following */
19/* conditions: */
20/* */
21/* The above copyright notice and this permission notice shall be */
22/* included in all copies or substantial portions of the */
23/* Software. */
24/* */
25/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27/* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28/* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29/* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31/* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32/* OTHER DEALINGS IN THE SOFTWARE. */
33/* */
34/************************************************************************/
35
36#ifndef VIGRA_DIFF2D_HXX
37#define VIGRA_DIFF2D_HXX
38
39#include <cmath> // for sqrt()
40#include <iosfwd>
41#include "config.hxx"
42#include "iteratortags.hxx"
43#include "iteratortraits.hxx"
44#include "iteratoradapter.hxx"
45#include "tuple.hxx"
46
47
48namespace vigra {
49
50
51template <class Diff>
52class Diff2DConstRowIteratorPolicy
53{
54 public:
55 typedef Diff BaseType;
56 typedef Diff value_type;
57 typedef typename Diff::MoveX difference_type;
58 typedef Diff const & reference;
59 typedef Diff index_reference;
60 typedef Diff const * pointer;
61 typedef std::random_access_iterator_tag iterator_category;
62
63 static void initialize(BaseType &) {}
64
65 static reference dereference(BaseType const & d)
66 { return d; }
67
68 static index_reference dereference(BaseType d, difference_type n)
69 {
70 d.x += n;
71 return d;
72 }
73
74 static bool equal(BaseType const & d1, BaseType const & d2)
75 { return d1.x == d2.x; }
76
77 static bool less(BaseType const & d1, BaseType const & d2)
78 { return d1.x < d2.x; }
79
80 static difference_type difference(BaseType const & d1, BaseType const & d2)
81 { return d1.x - d2.x; }
82
83 static void increment(BaseType & d)
84 { ++d.x; }
85
86 static void decrement(BaseType & d)
87 { --d.x; }
88
89 static void advance(BaseType & d, difference_type n)
90 { d.x += n; }
91};
92
93template <class Diff>
94class Diff2DConstColumnIteratorPolicy
95{
96 public:
97 typedef Diff BaseType;
98 typedef Diff value_type;
99 typedef typename Diff::MoveY difference_type;
100 typedef Diff const & reference;
101 typedef Diff index_reference;
102 typedef Diff const * pointer;
103 typedef std::random_access_iterator_tag iterator_category;
104
105 static void initialize(BaseType & /*d*/) {}
106
107 static reference dereference(BaseType const & d)
108 { return d; }
109
110 static index_reference dereference(BaseType d, difference_type n)
111 {
112 d.y += n;
113 return d;
114 }
115
116 static bool equal(BaseType const & d1, BaseType const & d2)
117 { return d1.y == d2.y; }
118
119 static bool less(BaseType const & d1, BaseType const & d2)
120 { return d1.y < d2.y; }
121
122 static difference_type difference(BaseType const & d1, BaseType const & d2)
123 { return d1.y - d2.y; }
124
125 static void increment(BaseType & d)
126 { ++d.y; }
127
128 static void decrement(BaseType & d)
129 { --d.y; }
130
131 static void advance(BaseType & d, difference_type n)
132 { d.y += n; }
133};
134
135/** \addtogroup RangesAndPoints Ranges and Points
136
137 Specify 2-D and N-D positions, extents, and boxes.
138*/
139//@{
140
141/********************************************************/
142/* */
143/* Diff2D */
144/* */
145/********************************************************/
146
147/** \brief Two dimensional difference vector.
148
149 This class acts primarily as a difference vector for specifying
150 pixel coordinates and region sizes. In addition, Diff2D fulfills
151 the requirements of an \ref ImageIterator, so that it can be used to
152 simulate an image whose pixels' values equal their coordinates. This
153 secondary usage is explained on page \ref CoordinateIterator.
154
155 Standard usage as a difference vector is mainly needed in the context
156 of images. For example, Diff2D may be used as an index for <TT>operator[]</TT>:
157
158 \code
159 vigra::Diff2D location(...);
160
161 value = image[location];
162 \endcode
163
164 This is especially important in connection with accessors, where the
165 offset variant of <TT>operator()</TT> takes only one offset object:
166
167 \code
168 // accessor(iterator, dx, dy); is not allowed
169 value = accessor(iterator, vigra::Diff2D(dx, dy));
170 \endcode
171
172
173 Diff2D is also returned by <TT>image.size()</TT>, so that we can create
174 new images by calculating their size using Diff2D's arithmetic
175 functions:
176
177 \code
178 // create an image that is 10 pixels smaller in each direction
179 Image new_image(old_image.size() - Diff2D(10,10));
180 \endcode
181
182 <b>\#include</b> <vigra/diff2d.hxx><br>
183 Namespace: vigra
184*/
186{
187 public:
188 /** The iterator's value type: a coordinate.
189 */
191
192 /** The iterator's value type: a coordinate.
193 */
195
196 /** the iterator's reference type (return type of <TT>*iter</TT>)
197 */
198 typedef Diff2D const & reference;
199
200 /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
201 */
203
204 /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
205 */
206 typedef Diff2D const * pointer;
207
208 /** the iterator's difference type (argument type of <TT>iter[diff]</TT>)
209 */
211
212 /** the iterator tag (image traverser)
213 */
214 typedef image_traverser_tag iterator_category;
215
216 /** The associated row iterator.
217 */
219
220 /** The associated column iterator.
221 */
223
224 /** type of the iterator's x-navigator
225 */
226 typedef int MoveX;
227 /** type of the iterator's y-navigator
228 */
229 typedef int MoveY;
230
231
232 /** Default Constructor. Init iterator at position (0,0)
233 */
235 : x(0), y(0)
236 {}
237
238 /** Construct at given position.
239 */
240 Diff2D(int ax, int ay)
241 : x(ax), y(ay)
242 {}
243
244 /** Copy Constructor.
245 */
246 Diff2D(Diff2D const & v)
247 : x(v.x), y(v.y)
248 {}
249
250 /** Copy Assigment.
251 */
253 {
254 if(this != &v)
255 {
256 x = v.x;
257 y = v.y;
258 }
259 return *this;
260 }
261
262 /** Unary negation.
263 */
265 {
266 return Diff2D(-x, -y);
267 }
268
269 /** Increase coordinate by specified offset.
270 */
271 Diff2D & operator+=(Diff2D const & offset)
272 {
273 x += offset.x;
274 y += offset.y;
275 return *this;
276 }
277
278 /** Decrease coordinate by specified vector.
279 */
280 Diff2D & operator-=(Diff2D const & offset)
281 {
282 x -= offset.x;
283 y -= offset.y;
284 return *this;
285 }
286
287 /** Create vector by scaling by factor.
288 */
289 Diff2D & operator*=(int factor)
290 {
291 x *= factor;
292 y *= factor;
293 return *this;
294 }
295
296 /** Create vector by scaling by factor.
297 */
298 Diff2D & operator*=(double factor)
299 {
300 x = (int)(x * factor);
301 y = (int)(y * factor);
302 return *this;
303 }
304
305 /** Create vector by scaling by 1/factor.
306 */
307 Diff2D & operator/=(int factor)
308 {
309 x /= factor;
310 y /= factor;
311 return *this;
312 }
313
314 /** Create vector by scaling by 1/factor.
315 */
316 Diff2D & operator/=(double factor)
317 {
318 x = (int)(x / factor);
319 y = (int)(y / factor);
320 return *this;
321 }
322
323 /** Create vector by scaling by factor.
324 */
325 Diff2D operator*(int factor) const
326 {
327 return Diff2D(x * factor, y * factor);
328 }
329
330 /** Create vector by scaling by factor.
331 */
332 Diff2D operator*(double factor) const
333 {
334 return Diff2D((int)(x * factor), (int)(y * factor));
335 }
336
337 /** Create vector by scaling by 1/factor.
338 */
339 Diff2D operator/(int factor) const
340 {
341 return Diff2D(x / factor, y / factor);
342 }
343
344 /** Create vector by scaling by 1/factor.
345 */
346 Diff2D operator/(double factor) const
347 {
348 return Diff2D((int)(x / factor), (int)(y / factor));
349 }
350
351 /** Calculate length of difference vector.
352 */
354 {
355 return x*x + y*y;
356 }
357
358 /** Calculate length of difference vector.
359 */
360 double magnitude() const
361 {
362 return VIGRA_CSTD::sqrt((double)squaredMagnitude());
363 }
364
365 /** Equality.
366 */
367 bool operator==(Diff2D const & r) const
368 {
369 return (x == r.x) && (y == r.y);
370 }
371
372 /** Inequality.
373 */
374 bool operator!=(Diff2D const & r) const
375 {
376 return (x != r.x) || (y != r.y);
377 }
378
379 /** Used for both access to the current x-coordinate \em and
380 to specify that an iterator navigation command is to be
381 applied in x-direction. <br>
382 usage: <TT> x = diff2d.x </TT> (use \p Diff2D::x as component of difference vector) <br>
383 or <TT>&nbsp; ++diff.x &nbsp; </TT> (use Diff2D as iterator, move right)
384 */
385 int x;
386 /** Used for both access to the current y-coordinate \em and
387 to specify that an iterator navigation command is to be
388 applied in y-direction. <br>
389 usage: <TT> y = diff2d.y </TT> (use \p Diff2D::y as component of difference vector) <br>
390 or <TT>&nbsp; ++diff.y &nbsp; </TT> (use Diff2D as iterator, move right)
391 */
392 int y;
393
394 /** Access current coordinate.
395 */
397 {
398 return *this;
399 }
400
401 /** Read coordinate at an offset.
402 */
403 index_reference operator()(int const & dx, int const & dy) const
404 {
405 return Diff2D(x + dx, y + dy);
406 }
407
408 /** Read coordinate at an offset.
409 */
410 index_reference operator[](Diff2D const & offset) const
411 {
412 return Diff2D(x + offset.x, y + offset.y);
413 }
414
415 /** Read vector components.
416 */
417 int operator[](int index) const
418 {
419 return (&x)[index];
420 }
421
422 /** Access current coordinate.
423 */
425 {
426 return this;
427 }
428
429 /** Get a row iterator at the current position.
430 */
432 { return row_iterator(*this); }
433
434 /** Get a column iterator at the current position.
435 */
437 { return column_iterator(*this); }
438};
439
440
441template <>
442struct IteratorTraits<Diff2D >
443{
444 typedef Diff2D Iterator;
445 typedef Iterator iterator;
446 typedef Iterator const_iterator;
447 // typedef multable_iterator; undefined
448 typedef iterator::iterator_category iterator_category;
449 typedef iterator::value_type value_type;
450 typedef iterator::reference reference;
451 typedef iterator::index_reference index_reference;
452 typedef iterator::pointer pointer;
453 typedef iterator::difference_type difference_type;
454 typedef iterator::row_iterator row_iterator;
455 typedef iterator::column_iterator column_iterator;
456 typedef StandardConstValueAccessor<Diff2D> DefaultAccessor;
457 typedef StandardConstValueAccessor<Diff2D> default_accessor;
458 typedef VigraTrueType hasConstantStrides;
459
460};
461
462/********************************************************/
463/* */
464/* Size2D */
465/* */
466/********************************************************/
467
468/** \brief Two dimensional size object.
469
470 Specializes \ref Diff2D for the specification of a 2-dimensional
471 extent, in contrast to a point or position (for the latter
472 use \ref Point2D).
473
474 \code
475 // create an image that is 10 pixels squared
476 Image new_image(Size2D(10,10));
477 \endcode
478
479 <b>\#include</b> <vigra/diff2d.hxx><br>
480 Namespace: vigra
481*/
482class Size2D : public Diff2D
483{
484public:
485 /** Default Constructor. Init point at position (0,0)
486 */
487 Size2D() = default;
488
489 /** Construct point at given position.
490 */
493 {}
494
495 /** Explicit conversion Constructor.
496 */
497 explicit Size2D(Diff2D const & v)
498 : Diff2D(v)
499 {}
500
501 /** Query the width.
502 */
503 int width() const
504 {
505 return x;
506 }
507
508 /** Query the height.
509 */
510 int height() const
511 {
512 return y;
513 }
514
515 /** Change the width.
516 */
517 void setWidth(int w)
518 {
519 x = w;
520 }
521
522 /** Change the height.
523 */
524 void setHeight(int h)
525 {
526 y = h;
527 }
528
529 /** Returns width()*height(), the area of a rectangle of this size.
530 */
531 int area() const
532 {
533 return width()*height();
534 }
535
536 /** Copy Assigment.
537 */
539 {
540 return static_cast<Size2D &>(Diff2D::operator=(v));
541 }
542
543 /** Unary negation.
544 */
546 {
547 return Size2D(-x, -y);
548 }
549
550 /** Increase size by specified offset.
551 */
552 Size2D & operator+=(Diff2D const & offset)
553 {
554 return static_cast<Size2D &>(Diff2D::operator+=(offset));
555 }
556
557 /** Decrease size by specified offset.
558 */
559 Size2D & operator-=(Diff2D const & offset)
560 {
561 return static_cast<Size2D &>(Diff2D::operator-=(offset));
562 }
563};
564
565/********************************************************/
566/* */
567/* Point2D */
568/* */
569/********************************************************/
570
571/** \brief Two dimensional point or position.
572
573 Specializes \ref Diff2D for the specification of a 2-dimensional
574 point or position, in contrast to an extent (for the latter
575 use \ref Size2D).
576
577 \code
578 // access an image at a point
579 value = image[Point2D(10, 20)];
580 \endcode
581
582 <b>\#include</b> <vigra/diff2d.hxx><br>
583 Namespace: vigra
584*/
585class Point2D : public Diff2D
586{
587public:
588 /** The iterator's value type: a coordinate.
589 */
591
592 /** The iterator's value type: a coordinate.
593 */
595
596 /** the iterator's reference type (return type of <TT>*iter</TT>)
597 */
598 typedef Point2D const & reference;
599
600 /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
601 */
603
604 /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
605 */
606 typedef Point2D const * pointer;
607
608 /** Default Constructor. Init point at position (0,0)
609 */
610 Point2D() = default;
611
612 /** Construct point at given position.
613 */
614 Point2D(int x, int y)
615 : Diff2D(x, y)
616 {}
617
618 /** Explicit conversion Constructor.
619 */
620 explicit Point2D(Diff2D const & v)
621 : Diff2D(v)
622 {}
623
624 /** Query the points' x coordinate
625 */
626 int px() const
627 {
628 return x;
629 }
630
631 /** Query the points' y coordinate
632 */
633 int py() const
634 {
635 return y;
636 }
637
638 /** Copy Assigment.
639 */
641 {
642 return static_cast<Point2D &>(Diff2D::operator=(v));
643 }
644
645 /** Unary negation.
646 */
648 {
649 return Point2D(-x, -y);
650 }
651
652 /** Increase point coordinates by specified offset.
653 */
654 Point2D & operator+=(Diff2D const & offset)
655 {
656 return static_cast<Point2D &>(Diff2D::operator+=(offset));
657 }
658
659 /** Decrease point coordinates by specified offset.
660 */
661 Point2D & operator-=(Diff2D const & offset)
662 {
663 return static_cast<Point2D &>(Diff2D::operator-=(offset));
664 }
665
666 /** Access current point coordinate.
667 */
669 {
670 return *this;
671 }
672
673 /** Read point coordinate at an offset.
674 */
675 index_reference operator()(int const & dx, int const & dy) const
676 {
677 return Point2D(x + dx, y + dy);
678 }
679
680 /** Read point coordinate at an offset.
681 */
682 index_reference operator[](Diff2D const & offset) const
683 {
684 return Point2D(x + offset.x, y + offset.y);
685 }
686
687 /** Access current point coordinate.
688 */
690 {
691 return this;
692 }
693};
694
695/** Create vector by subtracting specified offset.
696 */
697inline Diff2D operator-(Diff2D const &a, Diff2D const &b)
698{
699 return Diff2D(a.x - b.x, a.y - b.y);
700}
701
702/** Create size by subtracting specified offset.
703 */
704inline Size2D operator-(Size2D const & s, Diff2D const &offset)
705{
706 return Size2D(s.x - offset.x, s.y - offset.y);
707}
708
709/** Calculate size of rect between two points.
710 */
711inline Point2D operator-(Point2D const & s, Diff2D const & offset)
712{
713 return Point2D(s.x - offset.x, s.y - offset.y);
714}
715
716/** The difference of two points is a size
717 */
718inline Size2D operator-(Point2D const & s, Point2D const & p)
719{
720 return Size2D(s.x - p.x, s.y - p.y);
721}
722
723/** Create vector by adding specified offset.
724 */
725inline Diff2D operator+(Diff2D const &a, Diff2D const &b)
726{
727 return Diff2D(a.x + b.x, a.y + b.y);
728}
729
730/** Create size by adding specified offset.
731 */
732inline Size2D operator+(Size2D const &a, Diff2D const &b)
733{
734 return Size2D(a.x + b.x, a.y + b.y);
735}
736
737/** Create point by adding specified offset.
738 */
739inline Point2D operator+(Point2D const &a, Diff2D const &b)
740{
741 return Point2D(a.x + b.x, a.y + b.y);
742}
743
744/** Add size and point
745 */
746inline Point2D operator+(Size2D const & s, Point2D const & p)
747{
748 return Point2D(s.x + p.x, s.y + p.y);
749}
750
751inline Point2D operator*(Point2D l, double r)
752{
753 l *= r;
754 return l;
755}
756
757inline Point2D operator*(double l, Point2D r)
758{
759 r *= l;
760 return r;
761}
762
763inline Size2D operator*(Size2D l, double r)
764{
765 l *= r;
766 return l;
767}
768
769inline Size2D operator*(double l, Size2D r)
770{
771 r *= l;
772 return r;
773}
774
775inline Point2D operator/(Point2D l, double r)
776{
777 l /= r;
778 return l;
779}
780
781inline Size2D operator/(Size2D l, double r)
782{
783 l /= r;
784 return l;
785}
786
787inline Point2D operator*(Point2D l, int r)
788{
789 l *= r;
790 return l;
791}
792
793inline Point2D operator*(int l, Point2D r)
794{
795 r *= l;
796 return r;
797}
798
799inline Size2D operator*(Size2D l, int r)
800{
801 l *= r;
802 return l;
803}
804
805inline Size2D operator*(int l, Size2D r)
806{
807 r *= l;
808 return r;
809}
810
811inline Point2D operator/(Point2D l, int r)
812{
813 l /= r;
814 return l;
815}
816
817inline Size2D operator/(Size2D l, int r)
818{
819 l /= r;
820 return l;
821}
822
823
824/********************************************************/
825/* */
826/* Rect2D */
827/* */
828/********************************************************/
829
830/** \brief Two dimensional rectangle.
831
832 This class stores a 2-dimensional rectangular range or region. Thus,
833 it follows the VIGRA convention that the upper left corner is inside
834 the rectangle, while the lower right is 1 pixel to the right and below the
835 last pixel in the rectangle.
836
837 A major advantage of this class is that it can be constructed from either
838 a pair of \ref Point2D, or from a \ref Point2D and an extend
839 (\ref Size2D). Rect2D overloads operators |=, &=, |, & to realize set
840 union (in the sense of a minimal bounding rectangle) and set intersection.
841
842 \code
843 Rect2D r1(Point2D(0,0), Point2D(10, 20)),
844 r2(Point2D(10, 15), Size2D(20, 20));
845 Point2D p(0,100);
846
847 Rect2D r3 = r1 | r2; // upper left is (0,0), lower right is (30, 35)
848 assert(r3.contains(r2));
849 assert(!r3.contains(p));
850
851 r3 |= p; // lower right now (30,101) so that p is inside r3
852 assert(r3.contains(p));
853 \endcode
854
855 <b>\#include</b> <vigra/diff2d.hxx><br>
856 Namespace: vigra
857*/
859{
860 Point2D upperLeft_, lowerRight_;
861
862public:
863 /** Construct a null rectangle (isEmpty() will return true)
864 */
866 {}
867
868 /** Construct a rectangle representing the given range
869 * (lowerRight is considered to be outside the rectangle as
870 * usual in the VIGRA)
871 */
873 : upperLeft_(upperLeft), lowerRight_(lowerRight)
874 {}
875
876 /** Construct a rectangle representing the given range
877 */
878 Rect2D(int left, int top, int right, int bottom)
879 : upperLeft_(left, top), lowerRight_(right, bottom)
880 {}
881
882 /** Construct a rectangle of given position and size
883 */
885 : upperLeft_(upperLeft), lowerRight_(upperLeft + size)
886 {}
887
888 /** Construct a rectangle of given size at position (0,0)
889 */
890 explicit Rect2D(Size2D const &size)
891 : lowerRight_(Point2D(size))
892 {}
893
894 /** Return the first point (scan-order wise) which is
895 * considered to be "in" the rectangle.
896 */
897 Point2D const & upperLeft() const
898 {
899 return upperLeft_;
900 }
901
902 /** Return the first point to the right and below the
903 * rectangle.
904 */
905 Point2D const & lowerRight() const
906 {
907 return lowerRight_;
908 }
909
910 /** Change upperLeft() without changing lowerRight(), which
911 * will change the size most probably.
912 */
913 void setUpperLeft(Point2D const &ul)
914 {
915 upperLeft_ = ul;
916 }
917
918 /** Change lowerRight() without changing upperLeft(), which
919 * will change the size most probably.
920 */
921 void setLowerRight(Point2D const &lr)
922 {
923 lowerRight_ = lr;
924 }
925
926 /** Move the whole rectangle so that the given point will be
927 * upperLeft() afterwards.
928 */
929 void moveTo(Point2D const &newUpperLeft)
930 {
931 lowerRight_ += newUpperLeft - upperLeft_;
932 upperLeft_ = newUpperLeft;
933 }
934
935 /** Move the whole rectangle so that upperLeft() will become
936 * Point2D(left, top) afterwards.
937 */
938 void moveTo(int left, int top)
939 {
941 }
942
943 /** Move the whole rectangle by the given 2D offset.
944 */
945 void moveBy(Diff2D const &offset)
946 {
947 upperLeft_ += offset;
948 lowerRight_ += offset;
949 }
950
951 /** Move the whole rectangle by the given x- and y-offsets.
952 */
953 void moveBy(int xOffset, int yOffset)
954 {
955 moveBy(Diff2D(xOffset, yOffset));
956 }
957
958 /** Return the left coordinate of this rectangle.
959 */
960 int left() const
961 {
962 return upperLeft_.x;
963 }
964
965 /** Return the top coordinate of this rectangle.
966 */
967 int top() const
968 {
969 return upperLeft_.y;
970 }
971
972 /** Return the right coordinate of this rectangle. That is the
973 * first column to the right of the rectangle.
974 */
975 int right() const
976 {
977 return lowerRight_.x;
978 }
979
980 /** Return the bottom coordinate of this rectangle. That is the
981 * first row below the rectangle.
982 */
983 int bottom() const
984 {
985 return lowerRight_.y;
986 }
987
988 /** Determine and return the width of this rectangle. It might be
989 * zero or even negative, and if so, isEmpty() will return true.
990 */
991 int width() const
992 {
993 return lowerRight_.x - upperLeft_.x;
994 }
995
996 /** Determine and return the height of this rectangle. It might be
997 * zero or even negative, and if so, isEmpty() will return true.
998 */
999 int height() const
1000 {
1001 return lowerRight_.y - upperLeft_.y;
1002 }
1003
1004 /** Determine and return the area of this rectangle. That is, if
1005 * this rect isEmpty(), returns zero, otherwise returns
1006 * width()*height().
1007 */
1008 int area() const
1009 {
1010 return isEmpty() ? 0 : width()*height();
1011 }
1012
1013 /** Determine and return the size of this rectangle. The width
1014 * and/or height might be zero or even negative, and if so,
1015 * isEmpty() will return true.
1016 */
1017 Size2D size() const
1018 {
1019 return lowerRight_ - upperLeft_;
1020 }
1021
1022 /** Resize this rectangle to the given extents. This will move
1023 * the lower right corner only.
1024 */
1025 void setSize(Size2D const &size)
1026 {
1027 lowerRight_ = upperLeft_ + size;
1028 }
1029
1030 /** Resize this rectangle to the given extents. This will move
1031 * the lower right corner only.
1032 */
1033 void setSize(int width, int height)
1034 {
1035 lowerRight_ = upperLeft_ + Size2D(width, height);
1036 }
1037
1038 /** Increase the size of the rectangle by the given offset. This
1039 * will move the lower right corner only. (If any of offset's
1040 * components is negative, the rectangle will get smaller
1041 * accordingly.)
1042 */
1043 void addSize(Size2D const &offset)
1044 {
1045 lowerRight_ += offset;
1046 }
1047
1048 /** Adds a border of the given width around the rectangle. That
1049 * means, upperLeft()'s components are moved by -borderWidth
1050 * and lowerRight()'s by borderWidth. (If borderWidth is
1051 * negative, the rectangle will get smaller accordingly.)
1052 */
1053 void addBorder(int borderWidth)
1054 {
1055 upperLeft_ += Diff2D(-borderWidth, -borderWidth);
1056 lowerRight_ += Diff2D(borderWidth, borderWidth);
1057 }
1058
1059 /** Adds a border with possibly different widths in x- and
1060 * y-directions around the rectangle. That means, each x
1061 * component is moved borderWidth pixels and each y component
1062 * is moved borderHeight pixels to the outside. (If
1063 * borderWidth is negative, the rectangle will get smaller
1064 * accordingly.)
1065 */
1066 void addBorder(int borderWidth, int borderHeight)
1067 {
1068 upperLeft_ += Diff2D(-borderWidth, -borderHeight);
1069 lowerRight_ += Diff2D(borderWidth, borderHeight);
1070 }
1071
1072 /// equality check
1073 bool operator==(Rect2D const &r) const
1074 {
1075 return (upperLeft_ == r.upperLeft_) && (lowerRight_ == r.lowerRight_);
1076 }
1077
1078 /// inequality check
1079 bool operator!=(Rect2D const &r) const
1080 {
1081 return (upperLeft_ != r.upperLeft_) || (lowerRight_ != r.lowerRight_);
1082 }
1083
1084 /** Return whether this rectangle is considered empty. It is
1085 * non-empty if both coordinates of the lower right corner are
1086 * greater than the corresponding coordinate of the upper left
1087 * corner. Uniting an empty rectangle with something will return
1088 * the bounding rectangle of the 'something', intersecting with an
1089 * empty rectangle will yield again an empty rectangle.
1090 */
1091 bool isEmpty() const
1092 {
1093 return ((lowerRight_.x <= upperLeft_.x) ||
1094 (lowerRight_.y <= upperLeft_.y));
1095 }
1096
1097 /** Return whether this rectangle contains the given point. That
1098 * is, if the point lies within the valid range of an
1099 * ImageIterator walking from upperLeft() to lowerRight()
1100 * (excluding the latter).
1101 */
1102 bool contains(Point2D const &p) const
1103 {
1104 return ((upperLeft_.x <= p.x) &&
1105 (upperLeft_.y <= p.y) &&
1106 (p.x < lowerRight_.x) &&
1107 (p.y < lowerRight_.y));
1108 }
1109
1110 /** Return whether this rectangle contains the given
1111 * one. <tt>r1.contains(r2)</tt> returns the same as
1112 * <tt>r1 == (r1|r2)</tt> (but is of course more
1113 * efficient). That also means, a rectangle (even an empty one!)
1114 * contains() any empty rectangle.
1115 */
1116 bool contains(Rect2D const &r) const
1117 {
1118 return r.isEmpty() ||
1119 (contains(r.upperLeft()) && contains(r.lowerRight()-Diff2D(1,1)));
1120 }
1121
1122 /** Return whether this rectangle overlaps with the given
1123 * one. <tt>r1.intersects(r2)</tt> returns the same as
1124 * <tt>!(r1&r2).isEmpty()</tt> (but is of course much more
1125 * efficient).
1126 */
1127 bool intersects(Rect2D const &r) const
1128 {
1129 return ((r.upperLeft_.x < lowerRight_.x) &&
1130 (upperLeft_.x < r.lowerRight_.x) &&
1131 (r.upperLeft_.y < lowerRight_.y) &&
1132 (upperLeft_.y < r.lowerRight_.y))
1133 && !r.isEmpty();
1134 }
1135
1136 /** Modifies this rectangle by including the given point. The
1137 * result is the bounding rectangle of the rectangle and the
1138 * point. If isEmpty returns true, the union will be a
1139 * rectangle containing only the given point.
1140 */
1142 {
1143 if(isEmpty())
1144 {
1145 upperLeft_ = p;
1146 lowerRight_ = p + Diff2D(1, 1);
1147 }
1148 else
1149 {
1150 if(p.x < upperLeft_.x)
1151 upperLeft_.x = p.x;
1152 if(p.y < upperLeft_.y)
1153 upperLeft_.y = p.y;
1154 if(lowerRight_.x <= p.x)
1155 lowerRight_.x = p.x + 1;
1156 if(lowerRight_.y <= p.y)
1157 lowerRight_.y = p.y + 1;
1158 }
1159 return *this;
1160 }
1161
1162 /** Returns the union of this rectangle and the given
1163 * point. The result is the bounding rectangle of the
1164 * rectangle and the point. If isEmpty returns true, the union
1165 * will be a rectangle containing only the given point.
1166 */
1167 Rect2D operator|(Point2D const &p) const
1168 {
1169 Rect2D result(*this);
1170 result |= p;
1171 return result;
1172 }
1173
1174 /** Modifies this rectangle by uniting it with the given
1175 * one. The result is the bounding rectangle of both
1176 * rectangles. If one of the rectangles isEmpty(), the union
1177 * will be the other one.
1178 */
1180 {
1181 if(r.isEmpty())
1182 return *this;
1183 if(isEmpty())
1184 return operator=(r);
1185
1186 if(r.upperLeft_.x < upperLeft_.x)
1187 upperLeft_.x = r.upperLeft_.x;
1188 if(r.upperLeft_.y < upperLeft_.y)
1189 upperLeft_.y = r.upperLeft_.y;
1190 if(lowerRight_.x < r.lowerRight_.x)
1191 lowerRight_.x = r.lowerRight_.x;
1192 if(lowerRight_.y < r.lowerRight_.y)
1193 lowerRight_.y = r.lowerRight_.y;
1194 return *this;
1195 }
1196
1197 /** Returns the union of this rectangle and the given one. The
1198 * result is the bounding rectangle of both rectangles. If one
1199 * of the rectangles isEmpty(), the union will be the other
1200 * one.
1201 */
1202 Rect2D operator|(Rect2D const &r) const
1203 {
1204 Rect2D result(*this);
1205 result |= r;
1206 return result;
1207 }
1208
1209 /** Modifies this rectangle by intersecting it with the given
1210 * point. The result is the bounding rect of the point (with
1211 * width and height equal to 1) if it was contained in the
1212 * original rect, or an empty rect otherwise.
1213 */
1215 {
1216 if(contains(p))
1217 {
1218 upperLeft_ = p;
1219 lowerRight_ = p + Diff2D(1, 1);
1220 }
1221 else
1222 lowerRight_ = upperLeft_;
1223 return *this;
1224 }
1225
1226 /** Intersects this rectangle with the given point. The result
1227 * is the bounding rect of the point (with width and height
1228 * equal to 1) if it was contained in the original rect, or an
1229 * empty rect otherwise.
1230 */
1231 Rect2D operator&(Point2D const &p) const
1232 {
1233 Rect2D result(*this);
1234 result &= p;
1235 return result;
1236 }
1237
1238 /** Modifies this rectangle by intersecting it with the given
1239 * one. The result is the maximal rectangle contained in both
1240 * original ones. Intersecting with an empty rectangle will
1241 * yield again an empty rectangle.
1242 */
1244 {
1245 if(isEmpty())
1246 return *this;
1247 if(r.isEmpty())
1248 return operator=(r);
1249
1250 if(upperLeft_.x < r.upperLeft_.x)
1251 upperLeft_.x = r.upperLeft_.x;
1252 if(upperLeft_.y < r.upperLeft_.y)
1253 upperLeft_.y = r.upperLeft_.y;
1254 if(r.lowerRight_.x < lowerRight_.x)
1255 lowerRight_.x = r.lowerRight_.x;
1256 if(r.lowerRight_.y < lowerRight_.y)
1257 lowerRight_.y = r.lowerRight_.y;
1258 return *this;
1259 }
1260
1261 /** Scale this rectangle by the given factor.
1262 * To be specific, both upperLeft() and lowerRight() are
1263 * multiplied by `factor`.
1264 */
1265 Rect2D & operator*=(int factor)
1266 {
1267 upperLeft_ *= factor;
1268 lowerRight_ *= factor;
1269 return *this;
1270 }
1271
1272 /** Scale this rectangle by the given factor.
1273 * To be specific, both upperLeft() and lowerRight() are
1274 * multiplied by `factor`.
1275 */
1276 Rect2D & operator*=(double factor)
1277 {
1278 upperLeft_ *= factor;
1279 lowerRight_ *= factor;
1280 return *this;
1281 }
1282
1283 /** Return rectangle scaled by the given factor.
1284 * To be specific, both upperLeft() and lowerRight() are
1285 * multiplied by `factor`.
1286 */
1287 Rect2D operator*(int factor) const
1288 {
1289 return Rect2D(*this)*=factor;
1290 }
1291
1292 /** Return rectangle scaled by the given factor.
1293 * To be specific, both upperLeft() and lowerRight() are
1294 * multiplied by `factor`.
1295 */
1296 Rect2D operator*(double factor) const
1297 {
1298 return Rect2D(*this)*=factor;
1299 }
1300
1301 /** Intersects this rectangle with the given one. The result
1302 * is the maximal rectangle contained in both original ones.
1303 * Intersecting with an empty rectangle will yield again an
1304 * empty rectangle.
1305 */
1306 Rect2D operator&(Rect2D const &r) const
1307 {
1308 Rect2D result(*this);
1309 result &= r;
1310 return result;
1311 }
1312};
1313
1314
1315/********************************************************/
1316/* */
1317/* Dist2D */
1318/* */
1319/********************************************************/
1320
1321/** @deprecated use \ref vigra::Diff2D instead
1322*/
1323class Dist2D
1324{
1325 public:
1326 Dist2D(int the_width, int the_height)
1327 : width(the_width),
1328 height(the_height)
1329 {}
1330
1331 Dist2D(Dist2D const & s)
1332 : width(s.width),
1333 height(s.height)
1334 {}
1335
1336 Dist2D & operator=(Dist2D const & s)
1337 {
1338 if(this != &s)
1339 {
1340 width = s.width;
1341 height = s.height;
1342 }
1343 return *this;
1344 }
1345
1346 Dist2D & operator+=(Dist2D const & s)
1347 {
1348 width += s.width;
1349 height += s.height;
1350
1351 return *this;
1352 }
1353
1354 Dist2D operator+(Dist2D const & s) const
1355 {
1356 Dist2D ret(*this);
1357 ret += s;
1358
1359 return ret;
1360 }
1361
1362 operator Diff2D()
1363 { return Diff2D(width, height); }
1364
1365 int width;
1366 int height;
1367 };
1368
1369//@}
1370
1371} // namespace vigra
1372
1373namespace std {
1374
1375/**
1376 * Output a \ref vigra::Diff2D as a tuple.
1377 * Example Diff2D(-12, 13) -> "(-12, 13)"
1378 */
1379inline
1380ostream & operator<<(ostream & o, vigra::Diff2D const & d)
1381{
1382 o << '(' << d.x << ", " << d.y << ')';
1383 return o;
1384}
1385
1386/**
1387 * Output a \ref vigra::Size2D.
1388 * Example Size2D(100, 200) -> "(100x200)"
1389 */
1390inline
1391ostream &operator <<(ostream &s, vigra::Size2D const &d)
1392{
1393 s << '(' << d.x << 'x' << d.y << ')';
1394 return s;
1395}
1396
1397/**
1398 * Output a description of a \ref vigra::Rect2D.
1399 * Example Rect2D(10, 10, 30, 20) -> "[(10, 10) to (30, 20) = (20x10)]"
1400 */
1401inline
1402ostream &operator <<(ostream &s, vigra::Rect2D const &r)
1403{
1404 s << "[" << r.upperLeft() << " to " << r.lowerRight()
1405 << " = " << r.size() << "]";
1406 return s;
1407}
1408
1409} // namespace std
1410
1411#endif // VIGRA_DIFF2D_HXX
Two dimensional difference vector.
Definition diff2d.hxx:186
bool operator==(Diff2D const &r) const
Definition diff2d.hxx:367
int squaredMagnitude() const
Definition diff2d.hxx:353
int y
Definition diff2d.hxx:392
Diff2D operator*(double factor) const
Definition diff2d.hxx:332
int MoveY
Definition diff2d.hxx:229
Diff2D & operator=(Diff2D const &v)
Definition diff2d.hxx:252
int operator[](int index) const
Definition diff2d.hxx:417
Diff2D operator/(double factor) const
Definition diff2d.hxx:346
IteratorAdaptor< Diff2DConstRowIteratorPolicy< Diff2D > > row_iterator
Definition diff2d.hxx:218
int x
Definition diff2d.hxx:385
Diff2D(Diff2D const &v)
Definition diff2d.hxx:246
Diff2D & operator-=(Diff2D const &offset)
Definition diff2d.hxx:280
Diff2D index_reference
Definition diff2d.hxx:202
Diff2D & operator*=(double factor)
Definition diff2d.hxx:298
index_reference operator()(int const &dx, int const &dy) const
Definition diff2d.hxx:403
Diff2D & operator+=(Diff2D const &offset)
Definition diff2d.hxx:271
bool operator!=(Diff2D const &r) const
Definition diff2d.hxx:374
row_iterator rowIterator() const
Definition diff2d.hxx:431
Diff2D const * pointer
Definition diff2d.hxx:206
image_traverser_tag iterator_category
Definition diff2d.hxx:214
int MoveX
Definition diff2d.hxx:226
index_reference operator[](Diff2D const &offset) const
Definition diff2d.hxx:410
Diff2D()
Definition diff2d.hxx:234
Diff2D PixelType
Definition diff2d.hxx:190
Diff2D & operator*=(int factor)
Definition diff2d.hxx:289
reference operator*() const
Definition diff2d.hxx:396
Diff2D operator-() const
Definition diff2d.hxx:264
Diff2D & operator/=(double factor)
Definition diff2d.hxx:316
Diff2D const & reference
Definition diff2d.hxx:198
IteratorAdaptor< Diff2DConstColumnIteratorPolicy< Diff2D > > column_iterator
Definition diff2d.hxx:222
Diff2D operator*(int factor) const
Definition diff2d.hxx:325
Diff2D value_type
Definition diff2d.hxx:194
Diff2D & operator/=(int factor)
Definition diff2d.hxx:307
column_iterator columnIterator() const
Definition diff2d.hxx:436
pointer operator->() const
Definition diff2d.hxx:424
Diff2D(int ax, int ay)
Definition diff2d.hxx:240
double magnitude() const
Definition diff2d.hxx:360
Diff2D difference_type
Definition diff2d.hxx:210
Diff2D operator/(int factor) const
Definition diff2d.hxx:339
Quickly create 1-dimensional iterator adapters.
Definition iteratoradapter.hxx:148
Two dimensional point or position.
Definition diff2d.hxx:586
Point2D operator-() const
Definition diff2d.hxx:647
Point2D & operator=(Diff2D const &v)
Definition diff2d.hxx:640
Point2D const * pointer
Definition diff2d.hxx:606
Point2D(int x, int y)
Definition diff2d.hxx:614
Point2D const & reference
Definition diff2d.hxx:598
Point2D()=default
index_reference operator()(int const &dx, int const &dy) const
Definition diff2d.hxx:675
Point2D(Diff2D const &v)
Definition diff2d.hxx:620
int py() const
Definition diff2d.hxx:633
index_reference operator[](Diff2D const &offset) const
Definition diff2d.hxx:682
Point2D & operator+=(Diff2D const &offset)
Definition diff2d.hxx:654
reference operator*() const
Definition diff2d.hxx:668
Point2D PixelType
Definition diff2d.hxx:590
Point2D index_reference
Definition diff2d.hxx:602
Point2D & operator-=(Diff2D const &offset)
Definition diff2d.hxx:661
pointer operator->() const
Definition diff2d.hxx:689
Point2D value_type
Definition diff2d.hxx:594
int px() const
Definition diff2d.hxx:626
int top() const
Definition diff2d.hxx:967
void addBorder(int borderWidth, int borderHeight)
Definition diff2d.hxx:1066
bool contains(Rect2D const &r) const
Definition diff2d.hxx:1116
Rect2D()
Definition diff2d.hxx:865
void setSize(Size2D const &size)
Definition diff2d.hxx:1025
void addBorder(int borderWidth)
Definition diff2d.hxx:1053
Rect2D(Point2D const &upperLeft, Size2D const &size)
Definition diff2d.hxx:884
Rect2D operator|(Rect2D const &r) const
Definition diff2d.hxx:1202
void moveBy(Diff2D const &offset)
Definition diff2d.hxx:945
void setSize(int width, int height)
Definition diff2d.hxx:1033
Rect2D & operator&=(Point2D const &p)
Definition diff2d.hxx:1214
int right() const
Definition diff2d.hxx:975
Point2D const & upperLeft() const
Definition diff2d.hxx:897
int bottom() const
Definition diff2d.hxx:983
void moveBy(int xOffset, int yOffset)
Definition diff2d.hxx:953
Rect2D & operator*=(int factor)
Definition diff2d.hxx:1265
void setLowerRight(Point2D const &lr)
Definition diff2d.hxx:921
Rect2D operator*(double factor) const
Definition diff2d.hxx:1296
void setUpperLeft(Point2D const &ul)
Definition diff2d.hxx:913
Rect2D & operator*=(double factor)
Definition diff2d.hxx:1276
bool operator==(Rect2D const &r) const
equality check
Definition diff2d.hxx:1073
Rect2D & operator&=(Rect2D const &r)
Definition diff2d.hxx:1243
Rect2D operator&(Rect2D const &r) const
Definition diff2d.hxx:1306
Point2D const & lowerRight() const
Definition diff2d.hxx:905
bool intersects(Rect2D const &r) const
Definition diff2d.hxx:1127
void addSize(Size2D const &offset)
Definition diff2d.hxx:1043
Rect2D & operator|=(Point2D const &p)
Definition diff2d.hxx:1141
Rect2D(Point2D const &upperLeft, Point2D const &lowerRight)
Definition diff2d.hxx:872
bool contains(Point2D const &p) const
Definition diff2d.hxx:1102
void moveTo(Point2D const &newUpperLeft)
Definition diff2d.hxx:929
int left() const
Definition diff2d.hxx:960
bool operator!=(Rect2D const &r) const
inequality check
Definition diff2d.hxx:1079
Rect2D operator|(Point2D const &p) const
Definition diff2d.hxx:1167
bool isEmpty() const
Definition diff2d.hxx:1091
Rect2D & operator|=(Rect2D const &r)
Definition diff2d.hxx:1179
int height() const
Definition diff2d.hxx:999
Rect2D(int left, int top, int right, int bottom)
Definition diff2d.hxx:878
int width() const
Definition diff2d.hxx:991
void moveTo(int left, int top)
Definition diff2d.hxx:938
Rect2D operator&(Point2D const &p) const
Definition diff2d.hxx:1231
Rect2D operator*(int factor) const
Definition diff2d.hxx:1287
Size2D size() const
Definition diff2d.hxx:1017
Rect2D(Size2D const &size)
Definition diff2d.hxx:890
int area() const
Definition diff2d.hxx:1008
Two dimensional size object.
Definition diff2d.hxx:483
Size2D operator-() const
Definition diff2d.hxx:545
void setHeight(int h)
Definition diff2d.hxx:524
Size2D(Diff2D const &v)
Definition diff2d.hxx:497
Size2D()=default
Size2D & operator=(Diff2D const &v)
Definition diff2d.hxx:538
Size2D(int width, int height)
Definition diff2d.hxx:491
void setWidth(int w)
Definition diff2d.hxx:517
Size2D & operator-=(Diff2D const &offset)
Definition diff2d.hxx:559
Size2D & operator+=(Diff2D const &offset)
Definition diff2d.hxx:552
int height() const
Definition diff2d.hxx:510
int width() const
Definition diff2d.hxx:503
int area() const
Definition diff2d.hxx:531
Diff2D operator+(Diff2D const &a, Diff2D const &b)
Definition diff2d.hxx:725
Diff2D operator-(Diff2D const &a, Diff2D const &b)
Definition diff2d.hxx:697

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

html generated using doxygen and Python
vigra 1.12.2 (Mon Apr 14 2025)