[ 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 */
272 {
273 x += offset.x;
274 y += offset.y;
275 return *this;
276 }
277
278 /** Decrease coordinate by specified vector.
279 */
281 {
282 x -= offset.x;
283 y -= offset.y;
284 return *this;
285 }
286
287 /** Create vector by scaling by factor.
288 */
290 {
291 x *= factor;
292 y *= factor;
293 return *this;
294 }
295
296 /** Create vector by scaling by factor.
297 */
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 */
308 {
309 x /= factor;
310 y /= factor;
311 return *this;
312 }
313
314 /** Create vector by scaling by 1/factor.
315 */
317 {
318 x = (int)(x / factor);
319 y = (int)(y / factor);
320 return *this;
321 }
322
323 /** Create vector by scaling by factor.
324 */
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 */
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 */
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 */
488 {}
489
490 /** Construct point at given position.
491 */
494 {}
495
496 /** Copy Constructor.
497 */
498 Size2D(Size2D const & v)
499 : Diff2D(v)
500 {}
501
502 /** Explicit conversion Constructor.
503 */
504 explicit Size2D(Diff2D const & v)
505 : Diff2D(v)
506 {}
507
508 /** Query the width.
509 */
510 int width() const
511 {
512 return x;
513 }
514
515 /** Query the height.
516 */
517 int height() const
518 {
519 return y;
520 }
521
522 /** Change the width.
523 */
524 void setWidth(int w)
525 {
526 x = w;
527 }
528
529 /** Change the height.
530 */
531 void setHeight(int h)
532 {
533 y = h;
534 }
535
536 /** Returns width()*height(), the area of a rectangle of this size.
537 */
538 int area() const
539 {
540 return width()*height();
541 }
542
543 /** Copy Assigment.
544 */
546 {
547 return static_cast<Size2D &>(Diff2D::operator=(v));
548 }
549
550 /** Unary negation.
551 */
553 {
554 return Size2D(-x, -y);
555 }
556
557 /** Increase size by specified offset.
558 */
560 {
561 return static_cast<Size2D &>(Diff2D::operator+=(offset));
562 }
563
564 /** Decrease size by specified offset.
565 */
567 {
568 return static_cast<Size2D &>(Diff2D::operator-=(offset));
569 }
570};
571
572/********************************************************/
573/* */
574/* Point2D */
575/* */
576/********************************************************/
577
578/** \brief Two dimensional point or position.
579
580 Specializes \ref Diff2D for the specification of a 2-dimensional
581 point or position, in contrast to an extent (for the latter
582 use \ref Size2D).
583
584 \code
585 // access an image at a point
586 value = image[Point2D(10, 20)];
587 \endcode
588
589 <b>\#include</b> <vigra/diff2d.hxx><br>
590 Namespace: vigra
591*/
592class Point2D : public Diff2D
593{
594public:
595 /** The iterator's value type: a coordinate.
596 */
598
599 /** The iterator's value type: a coordinate.
600 */
602
603 /** the iterator's reference type (return type of <TT>*iter</TT>)
604 */
605 typedef Point2D const & reference;
606
607 /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
608 */
610
611 /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
612 */
613 typedef Point2D const * pointer;
614
615 /** Default Constructor. Init point at position (0,0)
616 */
618 {}
619
620 /** Construct point at given position.
621 */
622 Point2D(int x, int y)
623 : Diff2D(x, y)
624 {}
625
626 /** Copy Constructor.
627 */
628 Point2D(Point2D const & v)
629 : Diff2D(v)
630 {}
631
632 /** Explicit conversion Constructor.
633 */
634 explicit Point2D(Diff2D const & v)
635 : Diff2D(v)
636 {}
637
638 /** Query the points' x coordinate
639 */
640 int px() const
641 {
642 return x;
643 }
644
645 /** Query the points' y coordinate
646 */
647 int py() const
648 {
649 return y;
650 }
651
652 /** Copy Assigment.
653 */
655 {
656 return static_cast<Point2D &>(Diff2D::operator=(v));
657 }
658
659 /** Unary negation.
660 */
662 {
663 return Point2D(-x, -y);
664 }
665
666 /** Increase point coordinates by specified offset.
667 */
669 {
670 return static_cast<Point2D &>(Diff2D::operator+=(offset));
671 }
672
673 /** Decrease point coordinates by specified offset.
674 */
676 {
677 return static_cast<Point2D &>(Diff2D::operator-=(offset));
678 }
679
680 /** Access current point coordinate.
681 */
683 {
684 return *this;
685 }
686
687 /** Read point coordinate at an offset.
688 */
689 index_reference operator()(int const & dx, int const & dy) const
690 {
691 return Point2D(x + dx, y + dy);
692 }
693
694 /** Read point coordinate at an offset.
695 */
697 {
698 return Point2D(x + offset.x, y + offset.y);
699 }
700
701 /** Access current point coordinate.
702 */
704 {
705 return this;
706 }
707};
708
709/** Create vector by subtracting specified offset.
710 */
711inline Diff2D operator-(Diff2D const &a, Diff2D const &b)
712{
713 return Diff2D(a.x - b.x, a.y - b.y);
714}
715
716/** Create size by subtracting specified offset.
717 */
718inline Size2D operator-(Size2D const & s, Diff2D const &offset)
719{
720 return Size2D(s.x - offset.x, s.y - offset.y);
721}
722
723/** Calculate size of rect between two points.
724 */
725inline Point2D operator-(Point2D const & s, Diff2D const & offset)
726{
727 return Point2D(s.x - offset.x, s.y - offset.y);
728}
729
730/** The difference of two points is a size
731 */
732inline Size2D operator-(Point2D const & s, Point2D const & p)
733{
734 return Size2D(s.x - p.x, s.y - p.y);
735}
736
737/** Create vector by adding specified offset.
738 */
739inline Diff2D operator+(Diff2D const &a, Diff2D const &b)
740{
741 return Diff2D(a.x + b.x, a.y + b.y);
742}
743
744/** Create size by adding specified offset.
745 */
746inline Size2D operator+(Size2D const &a, Diff2D const &b)
747{
748 return Size2D(a.x + b.x, a.y + b.y);
749}
750
751/** Create point by adding specified offset.
752 */
753inline Point2D operator+(Point2D const &a, Diff2D const &b)
754{
755 return Point2D(a.x + b.x, a.y + b.y);
756}
757
758/** Add size and point
759 */
760inline Point2D operator+(Size2D const & s, Point2D const & p)
761{
762 return Point2D(s.x + p.x, s.y + p.y);
763}
764
765inline Point2D operator*(Point2D l, double r)
766{
767 l *= r;
768 return l;
769}
770
771inline Point2D operator*(double l, Point2D r)
772{
773 r *= l;
774 return r;
775}
776
777inline Size2D operator*(Size2D l, double r)
778{
779 l *= r;
780 return l;
781}
782
783inline Size2D operator*(double l, Size2D r)
784{
785 r *= l;
786 return r;
787}
788
789inline Point2D operator/(Point2D l, double r)
790{
791 l /= r;
792 return l;
793}
794
795inline Size2D operator/(Size2D l, double r)
796{
797 l /= r;
798 return l;
799}
800
801inline Point2D operator*(Point2D l, int r)
802{
803 l *= r;
804 return l;
805}
806
807inline Point2D operator*(int l, Point2D r)
808{
809 r *= l;
810 return r;
811}
812
813inline Size2D operator*(Size2D l, int r)
814{
815 l *= r;
816 return l;
817}
818
819inline Size2D operator*(int l, Size2D r)
820{
821 r *= l;
822 return r;
823}
824
825inline Point2D operator/(Point2D l, int r)
826{
827 l /= r;
828 return l;
829}
830
831inline Size2D operator/(Size2D l, int r)
832{
833 l /= r;
834 return l;
835}
836
837
838/********************************************************/
839/* */
840/* Rect2D */
841/* */
842/********************************************************/
843
844/** \brief Two dimensional rectangle.
845
846 This class stores a 2-dimensional rectangular range or region. Thus,
847 it follows the VIGRA convention that the upper left corner is inside
848 the rectangle, while the lower right is 1 pixel to the right and below the
849 last pixel in the rectangle.
850
851 A major advantage of this class is that it can be constructed from either
852 a pair of \ref Point2D, or from a \ref Point2D and an extend
853 (\ref Size2D). Rect2D overloads operators |=, &=, |, & to realize set
854 union (in the sense of a minimal bounding rectangle) and set intersection.
855
856 \code
857 Rect2D r1(Point2D(0,0), Point2D(10, 20)),
858 r2(Point2D(10, 15), Size2D(20, 20));
859 Point2D p(0,100);
860
861 Rect2D r3 = r1 | r2; // upper left is (0,0), lower right is (30, 35)
862 assert(r3.contains(r2));
863 assert(!r3.contains(p));
864
865 r3 |= p; // lower right now (30,101) so that p is inside r3
866 assert(r3.contains(p));
867 \endcode
868
869 <b>\#include</b> <vigra/diff2d.hxx><br>
870 Namespace: vigra
871*/
873{
874 Point2D upperLeft_, lowerRight_;
875
876public:
877 /** Construct a null rectangle (isEmpty() will return true)
878 */
880 {}
881
882 /** Construct a rectangle representing the given range
883 * (lowerRight is considered to be outside the rectangle as
884 * usual in the VIGRA)
885 */
887 : upperLeft_(upperLeft), lowerRight_(lowerRight)
888 {}
889
890 /** Construct a rectangle representing the given range
891 */
892 Rect2D(int left, int top, int right, int bottom)
893 : upperLeft_(left, top), lowerRight_(right, bottom)
894 {}
895
896 /** Construct a rectangle of given position and size
897 */
899 : upperLeft_(upperLeft), lowerRight_(upperLeft + size)
900 {}
901
902 /** Construct a rectangle of given size at position (0,0)
903 */
904 explicit Rect2D(Size2D const &size)
905 : lowerRight_(Point2D(size))
906 {}
907
908 /** Return the first point (scan-order wise) which is
909 * considered to be "in" the rectangle.
910 */
911 Point2D const & upperLeft() const
912 {
913 return upperLeft_;
914 }
915
916 /** Return the first point to the right and below the
917 * rectangle.
918 */
919 Point2D const & lowerRight() const
920 {
921 return lowerRight_;
922 }
923
924 /** Change upperLeft() without changing lowerRight(), which
925 * will change the size most probably.
926 */
928 {
929 upperLeft_ = ul;
930 }
931
932 /** Change lowerRight() without changing upperLeft(), which
933 * will change the size most probably.
934 */
936 {
937 lowerRight_ = lr;
938 }
939
940 /** Move the whole rectangle so that the given point will be
941 * upperLeft() afterwards.
942 */
944 {
945 lowerRight_ += newUpperLeft - upperLeft_;
946 upperLeft_ = newUpperLeft;
947 }
948
949 /** Move the whole rectangle so that upperLeft() will become
950 * Point2D(left, top) afterwards.
951 */
952 void moveTo(int left, int top)
953 {
955 }
956
957 /** Move the whole rectangle by the given 2D offset.
958 */
959 void moveBy(Diff2D const &offset)
960 {
961 upperLeft_ += offset;
962 lowerRight_ += offset;
963 }
964
965 /** Move the whole rectangle by the given x- and y-offsets.
966 */
967 void moveBy(int xOffset, int yOffset)
968 {
970 }
971
972 /** Return the left coordinate of this rectangle.
973 */
974 int left() const
975 {
976 return upperLeft_.x;
977 }
978
979 /** Return the top coordinate of this rectangle.
980 */
981 int top() const
982 {
983 return upperLeft_.y;
984 }
985
986 /** Return the right coordinate of this rectangle. That is the
987 * first column to the right of the rectangle.
988 */
989 int right() const
990 {
991 return lowerRight_.x;
992 }
993
994 /** Return the bottom coordinate of this rectangle. That is the
995 * first row below the rectangle.
996 */
997 int bottom() const
998 {
999 return lowerRight_.y;
1000 }
1001
1002 /** Determine and return the width of this rectangle. It might be
1003 * zero or even negative, and if so, isEmpty() will return true.
1004 */
1005 int width() const
1006 {
1007 return lowerRight_.x - upperLeft_.x;
1008 }
1009
1010 /** Determine and return the height of this rectangle. It might be
1011 * zero or even negative, and if so, isEmpty() will return true.
1012 */
1013 int height() const
1014 {
1015 return lowerRight_.y - upperLeft_.y;
1016 }
1017
1018 /** Determine and return the area of this rectangle. That is, if
1019 * this rect isEmpty(), returns zero, otherwise returns
1020 * width()*height().
1021 */
1022 int area() const
1023 {
1024 return isEmpty() ? 0 : width()*height();
1025 }
1026
1027 /** Determine and return the size of this rectangle. The width
1028 * and/or height might be zero or even negative, and if so,
1029 * isEmpty() will return true.
1030 */
1031 Size2D size() const
1032 {
1033 return lowerRight_ - upperLeft_;
1034 }
1035
1036 /** Resize this rectangle to the given extents. This will move
1037 * the lower right corner only.
1038 */
1039 void setSize(Size2D const &size)
1040 {
1041 lowerRight_ = upperLeft_ + size;
1042 }
1043
1044 /** Resize this rectangle to the given extents. This will move
1045 * the lower right corner only.
1046 */
1047 void setSize(int width, int height)
1048 {
1049 lowerRight_ = upperLeft_ + Size2D(width, height);
1050 }
1051
1052 /** Increase the size of the rectangle by the given offset. This
1053 * will move the lower right corner only. (If any of offset's
1054 * components is negative, the rectangle will get smaller
1055 * accordingly.)
1056 */
1057 void addSize(Size2D const &offset)
1058 {
1059 lowerRight_ += offset;
1060 }
1061
1062 /** Adds a border of the given width around the rectangle. That
1063 * means, upperLeft()'s components are moved by -borderWidth
1064 * and lowerRight()'s by borderWidth. (If borderWidth is
1065 * negative, the rectangle will get smaller accordingly.)
1066 */
1068 {
1069 upperLeft_ += Diff2D(-borderWidth, -borderWidth);
1070 lowerRight_ += Diff2D(borderWidth, borderWidth);
1071 }
1072
1073 /** Adds a border with possibly different widths in x- and
1074 * y-directions around the rectangle. That means, each x
1075 * component is moved borderWidth pixels and each y component
1076 * is moved borderHeight pixels to the outside. (If
1077 * borderWidth is negative, the rectangle will get smaller
1078 * accordingly.)
1079 */
1081 {
1082 upperLeft_ += Diff2D(-borderWidth, -borderHeight);
1083 lowerRight_ += Diff2D(borderWidth, borderHeight);
1084 }
1085
1086 /// equality check
1087 bool operator==(Rect2D const &r) const
1088 {
1089 return (upperLeft_ == r.upperLeft_) && (lowerRight_ == r.lowerRight_);
1090 }
1091
1092 /// inequality check
1093 bool operator!=(Rect2D const &r) const
1094 {
1095 return (upperLeft_ != r.upperLeft_) || (lowerRight_ != r.lowerRight_);
1096 }
1097
1098 /** Return whether this rectangle is considered empty. It is
1099 * non-empty if both coordinates of the lower right corner are
1100 * greater than the corresponding coordinate of the upper left
1101 * corner. Uniting an empty rectangle with something will return
1102 * the bounding rectangle of the 'something', intersecting with an
1103 * empty rectangle will yield again an empty rectangle.
1104 */
1105 bool isEmpty() const
1106 {
1107 return ((lowerRight_.x <= upperLeft_.x) ||
1108 (lowerRight_.y <= upperLeft_.y));
1109 }
1110
1111 /** Return whether this rectangle contains the given point. That
1112 * is, if the point lies within the valid range of an
1113 * ImageIterator walking from upperLeft() to lowerRight()
1114 * (excluding the latter).
1115 */
1116 bool contains(Point2D const &p) const
1117 {
1118 return ((upperLeft_.x <= p.x) &&
1119 (upperLeft_.y <= p.y) &&
1120 (p.x < lowerRight_.x) &&
1121 (p.y < lowerRight_.y));
1122 }
1123
1124 /** Return whether this rectangle contains the given
1125 * one. <tt>r1.contains(r2)</tt> returns the same as
1126 * <tt>r1 == (r1|r2)</tt> (but is of course more
1127 * efficient). That also means, a rectangle (even an empty one!)
1128 * contains() any empty rectangle.
1129 */
1130 bool contains(Rect2D const &r) const
1131 {
1132 return r.isEmpty() ||
1133 (contains(r.upperLeft()) && contains(r.lowerRight()-Diff2D(1,1)));
1134 }
1135
1136 /** Return whether this rectangle overlaps with the given
1137 * one. <tt>r1.intersects(r2)</tt> returns the same as
1138 * <tt>!(r1&r2).isEmpty()</tt> (but is of course much more
1139 * efficient).
1140 */
1141 bool intersects(Rect2D const &r) const
1142 {
1143 return ((r.upperLeft_.x < lowerRight_.x) &&
1144 (upperLeft_.x < r.lowerRight_.x) &&
1145 (r.upperLeft_.y < lowerRight_.y) &&
1146 (upperLeft_.y < r.lowerRight_.y))
1147 && !r.isEmpty();
1148 }
1149
1150 /** Modifies this rectangle by including the given point. The
1151 * result is the bounding rectangle of the rectangle and the
1152 * point. If isEmpty returns true, the union will be a
1153 * rectangle containing only the given point.
1154 */
1156 {
1157 if(isEmpty())
1158 {
1159 upperLeft_ = p;
1160 lowerRight_ = p + Diff2D(1, 1);
1161 }
1162 else
1163 {
1164 if(p.x < upperLeft_.x)
1165 upperLeft_.x = p.x;
1166 if(p.y < upperLeft_.y)
1167 upperLeft_.y = p.y;
1168 if(lowerRight_.x <= p.x)
1169 lowerRight_.x = p.x + 1;
1170 if(lowerRight_.y <= p.y)
1171 lowerRight_.y = p.y + 1;
1172 }
1173 return *this;
1174 }
1175
1176 /** Returns the union of this rectangle and the given
1177 * point. The result is the bounding rectangle of the
1178 * rectangle and the point. If isEmpty returns true, the union
1179 * will be a rectangle containing only the given point.
1180 */
1181 Rect2D operator|(Point2D const &p) const
1182 {
1183 Rect2D result(*this);
1184 result |= p;
1185 return result;
1186 }
1187
1188 /** Modifies this rectangle by uniting it with the given
1189 * one. The result is the bounding rectangle of both
1190 * rectangles. If one of the rectangles isEmpty(), the union
1191 * will be the other one.
1192 */
1194 {
1195 if(r.isEmpty())
1196 return *this;
1197 if(isEmpty())
1198 return operator=(r);
1199
1200 if(r.upperLeft_.x < upperLeft_.x)
1201 upperLeft_.x = r.upperLeft_.x;
1202 if(r.upperLeft_.y < upperLeft_.y)
1203 upperLeft_.y = r.upperLeft_.y;
1204 if(lowerRight_.x < r.lowerRight_.x)
1205 lowerRight_.x = r.lowerRight_.x;
1206 if(lowerRight_.y < r.lowerRight_.y)
1207 lowerRight_.y = r.lowerRight_.y;
1208 return *this;
1209 }
1210
1211 /** Returns the union of this rectangle and the given one. The
1212 * result is the bounding rectangle of both rectangles. If one
1213 * of the rectangles isEmpty(), the union will be the other
1214 * one.
1215 */
1216 Rect2D operator|(Rect2D const &r) const
1217 {
1218 Rect2D result(*this);
1219 result |= r;
1220 return result;
1221 }
1222
1223 /** Modifies this rectangle by intersecting it with the given
1224 * point. The result is the bounding rect of the point (with
1225 * width and height equal to 1) if it was contained in the
1226 * original rect, or an empty rect otherwise.
1227 */
1229 {
1230 if(contains(p))
1231 {
1232 upperLeft_ = p;
1233 lowerRight_ = p + Diff2D(1, 1);
1234 }
1235 else
1236 lowerRight_ = upperLeft_;
1237 return *this;
1238 }
1239
1240 /** Intersects this rectangle with the given point. The result
1241 * is the bounding rect of the point (with width and height
1242 * equal to 1) if it was contained in the original rect, or an
1243 * empty rect otherwise.
1244 */
1245 Rect2D operator&(Point2D const &p) const
1246 {
1247 Rect2D result(*this);
1248 result &= p;
1249 return result;
1250 }
1251
1252 /** Modifies this rectangle by intersecting it with the given
1253 * one. The result is the maximal rectangle contained in both
1254 * original ones. Intersecting with an empty rectangle will
1255 * yield again an empty rectangle.
1256 */
1258 {
1259 if(isEmpty())
1260 return *this;
1261 if(r.isEmpty())
1262 return operator=(r);
1263
1264 if(upperLeft_.x < r.upperLeft_.x)
1265 upperLeft_.x = r.upperLeft_.x;
1266 if(upperLeft_.y < r.upperLeft_.y)
1267 upperLeft_.y = r.upperLeft_.y;
1268 if(r.lowerRight_.x < lowerRight_.x)
1269 lowerRight_.x = r.lowerRight_.x;
1270 if(r.lowerRight_.y < lowerRight_.y)
1271 lowerRight_.y = r.lowerRight_.y;
1272 return *this;
1273 }
1274
1275 /** Scale this rectangle by the given factor.
1276 * To be specific, both upperLeft() and lowerRight() are
1277 * multiplied by `factor`.
1278 */
1280 {
1281 upperLeft_ *= factor;
1282 lowerRight_ *= factor;
1283 return *this;
1284 }
1285
1286 /** Scale this rectangle by the given factor.
1287 * To be specific, both upperLeft() and lowerRight() are
1288 * multiplied by `factor`.
1289 */
1291 {
1292 upperLeft_ *= factor;
1293 lowerRight_ *= factor;
1294 return *this;
1295 }
1296
1297 /** Return rectangle scaled by the given factor.
1298 * To be specific, both upperLeft() and lowerRight() are
1299 * multiplied by `factor`.
1300 */
1302 {
1303 return Rect2D(*this)*=factor;
1304 }
1305
1306 /** Return rectangle scaled by the given factor.
1307 * To be specific, both upperLeft() and lowerRight() are
1308 * multiplied by `factor`.
1309 */
1311 {
1312 return Rect2D(*this)*=factor;
1313 }
1314
1315 /** Intersects this rectangle with the given one. The result
1316 * is the maximal rectangle contained in both original ones.
1317 * Intersecting with an empty rectangle will yield again an
1318 * empty rectangle.
1319 */
1320 Rect2D operator&(Rect2D const &r) const
1321 {
1322 Rect2D result(*this);
1323 result &= r;
1324 return result;
1325 }
1326};
1327
1328
1329/********************************************************/
1330/* */
1331/* Dist2D */
1332/* */
1333/********************************************************/
1334
1335/** @deprecated use \ref vigra::Diff2D instead
1336*/
1338{
1339 public:
1340 Dist2D(int the_width, int the_height)
1341 : width(the_width),
1342 height(the_height)
1343 {}
1344
1345 Dist2D(Dist2D const & s)
1346 : width(s.width),
1347 height(s.height)
1348 {}
1349
1350 Dist2D & operator=(Dist2D const & s)
1351 {
1352 if(this != &s)
1353 {
1354 width = s.width;
1355 height = s.height;
1356 }
1357 return *this;
1358 }
1359
1360 Dist2D & operator+=(Dist2D const & s)
1361 {
1362 width += s.width;
1363 height += s.height;
1364
1365 return *this;
1366 }
1367
1368 Dist2D operator+(Dist2D const & s) const
1369 {
1370 Dist2D ret(*this);
1371 ret += s;
1372
1373 return ret;
1374 }
1375
1376 operator Diff2D()
1377 { return Diff2D(width, height); }
1378
1379 int width;
1380 int height;
1381 };
1382
1383//@}
1384
1385} // namespace vigra
1386
1387namespace std {
1388
1389/**
1390 * Output a \ref vigra::Diff2D as a tuple.
1391 * Example Diff2D(-12, 13) -> "(-12, 13)"
1392 */
1393inline
1394ostream & operator<<(ostream & o, vigra::Diff2D const & d)
1395{
1396 o << '(' << d.x << ", " << d.y << ')';
1397 return o;
1398}
1399
1400/**
1401 * Output a \ref vigra::Size2D.
1402 * Example Size2D(100, 200) -> "(100x200)"
1403 */
1404inline
1405ostream &operator <<(ostream &s, vigra::Size2D const &d)
1406{
1407 s << '(' << d.x << 'x' << d.y << ')';
1408 return s;
1409}
1410
1411/**
1412 * Output a description of a \ref vigra::Rect2D.
1413 * Example Rect2D(10, 10, 30, 20) -> "[(10, 10) to (30, 20) = (20x10)]"
1414 */
1415inline
1416ostream &operator <<(ostream &s, vigra::Rect2D const &r)
1417{
1418 s << "[" << r.upperLeft() << " to " << r.lowerRight()
1419 << " = " << r.size() << "]";
1420 return s;
1421}
1422
1423} // namespace std
1424
1425#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
Definition diff2d.hxx:1338
Two dimensional point or position.
Definition diff2d.hxx:593
Point2D operator-() const
Definition diff2d.hxx:661
Point2D & operator=(Diff2D const &v)
Definition diff2d.hxx:654
Point2D(Point2D const &v)
Definition diff2d.hxx:628
Point2D const * pointer
Definition diff2d.hxx:613
Point2D(int x, int y)
Definition diff2d.hxx:622
Point2D const & reference
Definition diff2d.hxx:605
index_reference operator()(int const &dx, int const &dy) const
Definition diff2d.hxx:689
Point2D(Diff2D const &v)
Definition diff2d.hxx:634
int py() const
Definition diff2d.hxx:647
index_reference operator[](Diff2D const &offset) const
Definition diff2d.hxx:696
Point2D & operator+=(Diff2D const &offset)
Definition diff2d.hxx:668
reference operator*() const
Definition diff2d.hxx:682
Point2D PixelType
Definition diff2d.hxx:597
Point2D index_reference
Definition diff2d.hxx:609
Point2D()
Definition diff2d.hxx:617
Point2D & operator-=(Diff2D const &offset)
Definition diff2d.hxx:675
pointer operator->() const
Definition diff2d.hxx:703
Point2D value_type
Definition diff2d.hxx:601
int px() const
Definition diff2d.hxx:640
Class for a single RGB value.
Definition rgbvalue.hxx:128
Two dimensional rectangle.
Definition diff2d.hxx:873
int top() const
Definition diff2d.hxx:981
void addBorder(int borderWidth, int borderHeight)
Definition diff2d.hxx:1080
bool contains(Rect2D const &r) const
Definition diff2d.hxx:1130
Rect2D()
Definition diff2d.hxx:879
void setSize(Size2D const &size)
Definition diff2d.hxx:1039
void addBorder(int borderWidth)
Definition diff2d.hxx:1067
Rect2D(Point2D const &upperLeft, Size2D const &size)
Definition diff2d.hxx:898
Rect2D operator|(Rect2D const &r) const
Definition diff2d.hxx:1216
void moveBy(Diff2D const &offset)
Definition diff2d.hxx:959
void setSize(int width, int height)
Definition diff2d.hxx:1047
Rect2D & operator&=(Point2D const &p)
Definition diff2d.hxx:1228
int right() const
Definition diff2d.hxx:989
Point2D const & upperLeft() const
Definition diff2d.hxx:911
int bottom() const
Definition diff2d.hxx:997
void moveBy(int xOffset, int yOffset)
Definition diff2d.hxx:967
Rect2D & operator*=(int factor)
Definition diff2d.hxx:1279
void setLowerRight(Point2D const &lr)
Definition diff2d.hxx:935
Rect2D operator*(double factor) const
Definition diff2d.hxx:1310
void setUpperLeft(Point2D const &ul)
Definition diff2d.hxx:927
Rect2D & operator*=(double factor)
Definition diff2d.hxx:1290
bool operator==(Rect2D const &r) const
equality check
Definition diff2d.hxx:1087
Rect2D & operator&=(Rect2D const &r)
Definition diff2d.hxx:1257
Rect2D operator&(Rect2D const &r) const
Definition diff2d.hxx:1320
Point2D const & lowerRight() const
Definition diff2d.hxx:919
bool intersects(Rect2D const &r) const
Definition diff2d.hxx:1141
void addSize(Size2D const &offset)
Definition diff2d.hxx:1057
Rect2D & operator|=(Point2D const &p)
Definition diff2d.hxx:1155
Rect2D(Point2D const &upperLeft, Point2D const &lowerRight)
Definition diff2d.hxx:886
bool contains(Point2D const &p) const
Definition diff2d.hxx:1116
void moveTo(Point2D const &newUpperLeft)
Definition diff2d.hxx:943
int left() const
Definition diff2d.hxx:974
bool operator!=(Rect2D const &r) const
inequality check
Definition diff2d.hxx:1093
Rect2D operator|(Point2D const &p) const
Definition diff2d.hxx:1181
bool isEmpty() const
Definition diff2d.hxx:1105
Rect2D & operator|=(Rect2D const &r)
Definition diff2d.hxx:1193
int height() const
Definition diff2d.hxx:1013
Rect2D(int left, int top, int right, int bottom)
Definition diff2d.hxx:892
int width() const
Definition diff2d.hxx:1005
void moveTo(int left, int top)
Definition diff2d.hxx:952
Rect2D operator&(Point2D const &p) const
Definition diff2d.hxx:1245
Rect2D operator*(int factor) const
Definition diff2d.hxx:1301
Size2D size() const
Definition diff2d.hxx:1031
Rect2D(Size2D const &size)
Definition diff2d.hxx:904
int area() const
Definition diff2d.hxx:1022
Two dimensional size object.
Definition diff2d.hxx:483
Size2D operator-() const
Definition diff2d.hxx:552
void setHeight(int h)
Definition diff2d.hxx:531
Size2D(Diff2D const &v)
Definition diff2d.hxx:504
Size2D()
Definition diff2d.hxx:487
Size2D & operator=(Diff2D const &v)
Definition diff2d.hxx:545
Size2D(int width, int height)
Definition diff2d.hxx:492
Size2D(Size2D const &v)
Definition diff2d.hxx:498
void setWidth(int w)
Definition diff2d.hxx:524
Size2D & operator-=(Diff2D const &offset)
Definition diff2d.hxx:566
Size2D & operator+=(Diff2D const &offset)
Definition diff2d.hxx:559
int height() const
Definition diff2d.hxx:517
int width() const
Definition diff2d.hxx:510
int area() const
Definition diff2d.hxx:538
Diff2D operator+(Diff2D const &a, Diff2D const &b)
Definition diff2d.hxx:739
Diff2D operator-(Diff2D const &a, Diff2D const &b)
Definition diff2d.hxx:711

© 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.11.1