PCL
Rectangle.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.7.0
6 // ----------------------------------------------------------------------------
7 // pcl/Rectangle.h - Released 2024-06-18T15:48:54Z
8 // ----------------------------------------------------------------------------
9 // This file is part of the PixInsight Class Library (PCL).
10 // PCL is a multiplatform C++ framework for development of PixInsight modules.
11 //
12 // Copyright (c) 2003-2024 Pleiades Astrophoto S.L. All Rights Reserved.
13 //
14 // Redistribution and use in both source and binary forms, with or without
15 // modification, is permitted provided that the following conditions are met:
16 //
17 // 1. All redistributions of source code must retain the above copyright
18 // notice, this list of conditions and the following disclaimer.
19 //
20 // 2. All redistributions in binary form must reproduce the above copyright
21 // notice, this list of conditions and the following disclaimer in the
22 // documentation and/or other materials provided with the distribution.
23 //
24 // 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
25 // of their contributors, may be used to endorse or promote products derived
26 // from this software without specific prior written permission. For written
27 // permission, please contact info@pixinsight.com.
28 //
29 // 4. All products derived from this software, in any form whatsoever, must
30 // reproduce the following acknowledgment in the end-user documentation
31 // and/or other materials provided with the product:
32 //
33 // "This product is based on software from the PixInsight project, developed
34 // by Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
35 //
36 // Alternatively, if that is where third-party acknowledgments normally
37 // appear, this acknowledgment must be reproduced in the product itself.
38 //
39 // THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
40 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
41 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
43 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
44 // EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
45 // INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
46 // DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49 // POSSIBILITY OF SUCH DAMAGE.
50 // ----------------------------------------------------------------------------
51 
52 #ifndef __PCL_Rectangle_h
53 #define __PCL_Rectangle_h
54 
56 
57 #include <pcl/Defs.h>
58 
59 #include <pcl/Flags.h>
60 #include <pcl/Math.h>
61 #include <pcl/Point.h>
62 #include <pcl/Relational.h>
63 
64 #ifdef __PCL_QT_INTERFACE
65 # include <QtCore/QRect>
66 # ifndef __PCL_QT_NO_RECT_DRAWING_HELPERS
67 # include <QtGui/QPainter>
68 # include <QtGui/QBrush>
69 # endif
70 #endif
71 
72 namespace pcl
73 {
74 
75 // ----------------------------------------------------------------------------
76 
90 namespace Clip
91 {
92  enum mask_type
93  {
94  Left = 0x01, // Clipped at the left side
95  Top = 0x02, // Clipped at the top side
96  Right = 0x04, // Clipped at the right side
97  Bottom = 0x08 // Clipped at the bottom side
98  };
99 }
100 
105 
106 // ----------------------------------------------------------------------------
107 
123 template <typename T> inline
124 bool IsPoint( T x0, T y0, T x1, T y1 ) noexcept
125 {
126  return x0 == x1 && y0 == y1;
127 }
128 
141 template <typename T> inline
142 bool IsLine( T x0, T y0, T x1, T y1 ) noexcept
143 {
144  return ((x0 == x1) ^ (y0 == y1)) != 0;
145 }
146 
158 template <typename T> inline
159 bool IsHorizontalLine( T x0, T y0, T x1, T y1 ) noexcept
160 {
161  return y0 == y1 && x0 != x1;
162 }
163 
175 template <typename T> inline
176 bool IsVerticalLine( T x0, T y0, T x1, T y1 ) noexcept
177 {
178  return x0 == x1 && y0 != y1;
179 }
180 
192 template <typename T> inline
193 bool IsPointOrLine( T x0, T y0, T x1, T y1 ) noexcept
194 {
195  return x0 == x1 || y0 == y1;
196 }
197 
209 template <typename T> inline
210 bool IsRect( T x0, T y0, T x1, T y1 ) noexcept
211 {
212  return x0 != x1 && y0 != y1;
213 }
214 
225 template <typename T> inline
226 bool IsNormalRect( T x0, T y0, T x1, T y1 ) noexcept
227 {
228  return x0 < x1 && y0 < y1;
229 }
230 
242 template <typename T> inline
243 bool IsOrderedRect( T x0, T y0, T x1, T y1 ) noexcept
244 {
245  return x0 <= x1 && y0 <= y1;
246 }
247 
259 template <typename T> inline
260 void OrderRect( T& x0, T& y0, T& x1, T& y1 ) noexcept
261 {
262  if ( x1 < x0 )
263  pcl::Swap( x0, x1 );
264  if ( y1 < y0 )
265  pcl::Swap( y0, y1 );
266 }
267 
268 // ----------------------------------------------------------------------------
269 
270 /*
271  * ### NB: Template class GenericRectangle cannot have virtual member
272  * functions. This is because internal PCL and core routines rely on
273  * GenericRectangle<int>, GenericRectangle<float> and
274  * GenericRectangle<double> to be directly castable to int*, float* and
275  * double*, respectively. See also the PCL_ASSERT_RECT_SIZE() macro.
276  */
277 
278 #define PCL_ASSERT_RECT_SIZE() \
279  static_assert( sizeof( *this ) == 4*sizeof( T ), "Invalid sizeof( GenericRectangle<> )" )
280 
312 template <typename T>
313 class PCL_CLASS GenericRectangle
314 {
315 public:
316 
320  using component = T;
321 
326 
327  /*
328  * Rectangle coordinates: x0=left, y0=top, x1=right, y1=bottom.
329  * The x1 (right) and y1 (bottom) coordinates are excluded from the
330  * rectangular area, so we always have: width=x1-x0 and height=y1-y0.
331  */
336 
341  constexpr GenericRectangle()
342  {
343  PCL_ASSERT_RECT_SIZE();
344  }
345 
356  template <typename T1>
357  constexpr GenericRectangle( T1 left, T1 top, T1 right, T1 bottom )
358  : x0( component( left ) )
359  , y0( component( top ) )
360  , x1( component( right ) )
361  , y1( component( bottom ) )
362  {
363  PCL_ASSERT_RECT_SIZE();
364  }
365 
391  template <typename T1>
392  GenericRectangle( std::initializer_list<T1> l )
393  {
394  PCL_ASSERT_RECT_SIZE();
395  switch ( l.size() )
396  {
397  default:
398  case 4: y1 = component( l.begin()[3] );
399  case 3: x1 = component( l.begin()[2] );
400  case 2: y0 = component( l.begin()[1] );
401  case 1: x0 = component( l.begin()[0] );
402  case 0: break;
403  }
404  switch ( l.size() )
405  {
406  case 0: x0 = component( 0 );
407  case 1: y0 = component( 0 );
408  case 2: x1 = component( 0 );
409  case 3: y1 = component( 0 );
410  default:
411  case 4: break;
412  }
413  }
414 
424  template <typename T1>
425  GenericRectangle( const pcl::GenericPoint<T1>& leftTop, const pcl::GenericPoint<T1>& rightBottom )
426  : GenericRectangle( component( leftTop.x ), component( leftTop.y ),
427  component( rightBottom.x ), component( rightBottom.y ) )
428  {
429  PCL_ASSERT_RECT_SIZE();
430  }
431 
440  constexpr GenericRectangle( component width, component height )
441  : GenericRectangle( component( 0 ), component( 0 ), width, height )
442  {
443  PCL_ASSERT_RECT_SIZE();
444  }
445 
454  : GenericRectangle( d, d, d, d )
455  {
456  PCL_ASSERT_RECT_SIZE();
457  }
458 
463  template <typename T1>
465  : GenericRectangle( component( r.x0 ), component( r.y0 ),
466  component( r.x1 ), component( r.y1 ) )
467  {
468  PCL_ASSERT_RECT_SIZE();
469  }
470 
471 #ifdef __PCL_QT_INTERFACE
472  GenericRectangle( const QRect& r )
473  : GenericRectangle( component( r.left() ), component( r.top() ),
474  component( r.right()+1 ), component( r.bottom()+1 ) )
475  {
476  PCL_ASSERT_RECT_SIZE();
477  }
478 
479  GenericRectangle( const QPoint& p0, const QPoint& p1 )
480  : GenericRectangle( component( p0.x() ), component( p0.y() ),
481  component( p1.x() ), component( p1.y() ) )
482  {
483  PCL_ASSERT_RECT_SIZE();
484  }
485 #endif
486 
491  component Left() const noexcept
492  {
493  return x0;
494  }
495 
500  component Top() const noexcept
501  {
502  return y0;
503  }
504 
509  component Right() const noexcept
510  {
511  return x1;
512  }
513 
518  component Bottom() const noexcept
519  {
520  return y1;
521  }
522 
527  point LeftTop() const noexcept
528  {
529  return point( pcl::Min( x0, x1 ), pcl::Min( y0, y1 ) );
530  }
531 
535  point TopLeft() const noexcept
536  {
537  return LeftTop();
538  }
539 
544  point RightTop() const noexcept
545  {
546  return point( pcl::Max( x0, x1 ), pcl::Min( y0, y1 ) );
547  }
548 
552  point TopRight() const noexcept
553  {
554  return RightTop();
555  }
556 
561  point LeftBottom() const noexcept
562  {
563  return point( pcl::Min( x0, x1 ), pcl::Max( y0, y1 ) );
564  }
565 
569  point BottomLeft() const noexcept
570  {
571  return LeftBottom();
572  }
573 
578  point RightBottom() const noexcept
579  {
580  return point( pcl::Max( x0, x1 ), pcl::Max( y0, y1 ) );
581  }
582 
586  point BottomRight() const noexcept
587  {
588  return RightBottom();
589  }
590 
594  point Center() const noexcept
595  {
596  return point( (x0 + x1)/2, (y0 + y1)/2 );
597  }
598 
602  point CenterTop() const noexcept
603  {
604  return point( (x0 + x1)/2, pcl::Min( y0, y1 ) );
605  }
606 
610  point CenterBottom() const noexcept
611  {
612  return point( (x0 + x1)/2, pcl::Min( y0, y1 ) );
613  }
614 
618  point CenterLeft() const noexcept
619  {
620  return point( pcl::Min( x0, x1 ), (y0 + y1)/2 );
621  }
622 
626  point CenterRight() const noexcept
627  {
628  return point( pcl::Min( x0, x1 ), (y0 + y1)/2 );
629  }
630 
635  component Width() const noexcept
636  {
637  return pcl::Abs( x1 - x0 );
638  }
639 
644  component Height() const noexcept
645  {
646  return pcl::Abs( y1 - y0 );
647  }
648 
653  component Perimeter() const noexcept
654  {
655  component w = Width(), h = Height();
656  return w+w+h+h;
657  }
658 
665  component ManhattanDistance() const noexcept
666  {
667  return Width() + Height();
668  }
669 
674  component Area() const noexcept
675  {
676  return pcl::Abs( (x1 - x0)*(y1 - y0) );
677  }
678 
683  double CenterX() const noexcept
684  {
685  return 0.5*(x0 + x1);
686  }
687 
692  double CenterY() const noexcept
693  {
694  return 0.5*(y0 + y1);
695  }
696 
703  double Hypot() const noexcept
704  {
705  double w = x1 - x0, h = y1 - y0;
706  return w*w + h*h;
707  }
708 
713  double Diagonal() const noexcept
714  {
715  return pcl::Sqrt( Hypot() );
716  }
717 
721  bool IsPoint() const noexcept
722  {
723  return pcl::IsPoint( x0, y0, x1, y1 );
724  }
725 
729  bool IsLine() const noexcept
730  {
731  return pcl::IsLine( x0, y0, x1, y1 );
732  }
733 
737  bool IsHorizontalLine() const noexcept
738  {
739  return pcl::IsHorizontalLine( x0, y0, x1, y1 );
740  }
741 
745  bool IsVerticalLine() const noexcept
746  {
747  return pcl::IsVerticalLine( x0, y0, x1, y1 );
748  }
749 
753  bool IsPointOrLine() const noexcept
754  {
755  return pcl::IsPointOrLine( x0, y0, x1, y1 );
756  }
757 
762  bool IsRect() const noexcept
763  {
764  return pcl::IsRect( x0, y0, x1, y1 );
765  }
766 
770  bool IsNormal() const noexcept
771  {
772  return pcl::IsNormalRect( x0, y0, x1, y1 );
773  }
774 
778  bool IsOrdered() const noexcept
779  {
780  return pcl::IsOrderedRect( x0, y0, x1, y1 );
781  }
782 
786  void Order() noexcept
787  {
788  pcl::OrderRect( x0, y0, x1, y1 );
789  }
790 
794  GenericRectangle Ordered() const noexcept
795  {
796  GenericRectangle r = *this;
797  r.Order();
798  return r;
799  }
800 
809  template <typename T1>
810  ClipFlags ClipCode( T1 x, T1 y ) const noexcept
811  {
812  ClipFlags clip; // defaults to zero
813 
814  if ( x0 <= x1 )
815  {
816  if ( x < x0 ) clip |= Clip::Left;
817  if ( x > x1 ) clip |= Clip::Right;
818  }
819  else
820  {
821  if ( x < x1 ) clip |= Clip::Left;
822  if ( x > x0 ) clip |= Clip::Right;
823  }
824 
825  if ( y0 <= y1 )
826  {
827  if ( y < y0 ) clip |= Clip::Top;
828  if ( y > y1 ) clip |= Clip::Bottom;
829  }
830  else
831  {
832  if ( y < y1 ) clip |= Clip::Top;
833  if ( y > y0 ) clip |= Clip::Bottom;
834  }
835 
836  return clip;
837  }
838 
846  template <typename T1>
847  ClipFlags ClipCode( const pcl::GenericPoint<T1>& p ) const noexcept
848  {
849  return ClipCode( p.x, p.y );
850  }
851 
856  template <typename T1>
857  bool Includes( T1 x, T1 y ) const noexcept
858  {
859  return ((x0 < x1) ? (x >= x0 && x <= x1) : (x >= x1 && x <= x0)) &&
860  ((y0 < y1) ? (y >= y0 && y <= y1) : (y >= y1 && y <= y0));
861  }
862 
866  template <typename T1>
867  bool Includes( const pcl::GenericPoint<T1>& p ) const noexcept
868  {
869  return Includes( p.x, p.y );
870  }
871 
875  template <typename T1>
876  bool Includes( const GenericRectangle<T1>& r ) const noexcept
877  {
878  return Includes( r.x0, r.y0 ) && Includes( r.x1, r.y1 );
879  }
880 
881 #ifdef __PCL_QT_INTERFACE
882  bool Includes( const QPoint& p ) const noexcept
883  {
884  return Includes( p.x(), p.y() );
885  }
886 
887  bool Includes( const QRect& r ) const noexcept
888  {
889  return Includes( r.left(), r.top() ) && Includes( r.right()+1, r.bottom()+1 );
890  }
891 #endif
892 
901  template <typename T1>
902  bool IncludesFast( T1 x, T1 y ) const noexcept
903  {
904  return x >= x0 && y >= y0 && x <= x1 && y <= y1;
905  }
906 
914  template <typename T1>
915  bool IncludesFast( const pcl::GenericPoint<T1>& p ) const noexcept
916  {
917  return IncludesFast( p.x, p.y );
918  }
919 
930  template <typename T1>
931  bool Intersects( T1 left, T1 top, T1 right, T1 bottom ) const noexcept
932  {
933  OrderRect( left, top, right, bottom );
934  return ((x0 < x1) ? (right >= x0 && left <= x1) : (right >= x1 && left <= x0)) &&
935  ((y0 < y1) ? (bottom >= y0 && top <= y1) : (bottom >= y1 && top <= y0));
936  }
937 
941  template <typename T1>
942  bool Intersects( const pcl::GenericRectangle<T1>& r ) const noexcept
943  {
944  return Intersects( r.x0, r.y0, r.x1, r.y1 );
945  }
946 
947 #ifdef __PCL_QT_INTERFACE
948  bool Intersects( const QRect& r ) const noexcept
949  {
950  return Intersects( r.left(), r.top(), r.right()+1, r.bottom()+1 );
951  }
952 #endif
953 
973  template <typename T1>
974  bool IntersectsFast( T1 left, T1 top, T1 right, T1 bottom ) const noexcept
975  {
976  return right >= x0 && left <= x1 && bottom >= y0 && top <= y1;
977  }
978 
985  template <typename T1>
986  bool IntersectsFast( const pcl::GenericRectangle<T1>& r ) const noexcept
987  {
988  return IntersectsFast( r.x0, r.y0, r.x1, r.y1 );
989  }
990 
995  template <typename T1>
996  void Unite( const GenericRectangle<T1>& r ) noexcept
997  {
998  Unite( r.x0, r.y0, r.x1, r.y1 );
999  }
1000 
1011  template <typename T1>
1012  void Unite( T1 left, T1 top, T1 right, T1 bottom ) noexcept
1013  {
1014  if ( right < left )
1015  Swap( left, right );
1016  if ( bottom < top )
1017  Swap( top, bottom );
1018 
1019  if ( x0 <= x1 )
1020  {
1021  x0 = pcl::Min( x0, component( left ) );
1022  x1 = pcl::Max( x1, component( right ) );
1023  }
1024  else
1025  {
1026  x0 = pcl::Max( x0, component( right ) );
1027  x1 = pcl::Min( x1, component( left ) );
1028  }
1029 
1030  if ( y0 <= y1 )
1031  {
1032  y0 = pcl::Min( y0, component( top ) );
1033  y1 = pcl::Max( y1, component( bottom ) );
1034  }
1035  else
1036  {
1037  y0 = pcl::Max( y0, component( bottom ) );
1038  y1 = pcl::Min( y1, component( top ) );
1039  }
1040  }
1041 
1049  template <typename T1>
1050  void UniteFast( const GenericRectangle<T1>& r ) noexcept
1051  {
1052  UniteFast( r.x0, r.y0, r.x1, r.y1 );
1053  }
1054 
1074  template <typename T1>
1075  void UniteFast( T1 left, T1 top, T1 right, T1 bottom ) noexcept
1076  {
1077  x0 = pcl::Min( x0, component( left ) );
1078  y0 = pcl::Min( y0, component( top ) );
1079  x1 = pcl::Max( x1, component( right ) );
1080  y1 = pcl::Max( y1, component( bottom ) );
1081  }
1082 
1086  template <typename T1>
1087  GenericRectangle Union( const GenericRectangle<T1>& r ) const noexcept
1088  {
1089  GenericRectangle r1 = *this;
1090  r1.Unite( r );
1091  return r1;
1092  }
1093 
1100  template <typename T1>
1102  {
1103  GenericRectangle r1 = *this;
1104  r1.UniteFast( r );
1105  return r1;
1106  }
1107 
1112  template <typename T1>
1113  GenericRectangle& operator |=( const GenericRectangle<T1>& r ) noexcept
1114  {
1115  Unite( r );
1116  return *this;
1117  }
1118 
1119 #ifdef __PCL_QT_INTERFACE
1120  void Unite( const QRect& r )
1121  {
1122  Unite( r.left(), r.top(), r.right()+1, r.bottom()+1 );
1123  }
1124 
1125  GenericRectangle Union( const QRect& r ) const noexcept
1126  {
1127  GenericRectangle r1 = *this;
1128  r1.Unite( r );
1129  return r1;
1130  }
1131 
1132  GenericRectangle& operator |=( const QRect& r ) noexcept
1133  {
1134  Unite( r );
1135  return *this;
1136  }
1137 #endif
1138 
1147  template <typename T1>
1148  bool Intersect( const GenericRectangle<T1>& r ) noexcept
1149  {
1150  return Intersect( r.x0, r.y0, r.x1, r.y1 );
1151  }
1152 
1167  template <typename T1>
1168  bool Intersect( T1 left, T1 top, T1 right, T1 bottom ) noexcept
1169  {
1170  if ( right < left )
1171  Swap( left, right );
1172  if ( bottom < top )
1173  Swap( top, bottom );
1174 
1175  if ( x0 <= x1 )
1176  {
1177  x0 = pcl::Max( x0, component( left ) );
1178  x1 = pcl::Min( x1, component( right ) );
1179  }
1180  else
1181  {
1182  x0 = pcl::Min( x0, component( right ) );
1183  x1 = pcl::Max( x1, component( left ) );
1184  }
1185 
1186  if ( y0 <= y1 )
1187  {
1188  y0 = pcl::Max( y0, component( top ) );
1189  y1 = pcl::Min( y1, component( bottom ) );
1190  }
1191  else
1192  {
1193  y0 = pcl::Min( y0, component( bottom ) );
1194  y1 = pcl::Max( y1, component( top ) );
1195  }
1196 
1197  return IsRect();
1198  }
1199 
1211  template <typename T1>
1212  bool IntersectFast( const GenericRectangle<T1>& r ) noexcept
1213  {
1214  return IntersectFast( r.x0, r.y0, r.x1, r.y1 );
1215  }
1216 
1240  template <typename T1>
1241  bool IntersectFast( T1 left, T1 top, T1 right, T1 bottom ) noexcept
1242  {
1243  x0 = pcl::Max( x0, component( left ) );
1244  y0 = pcl::Max( y0, component( top ) );
1245  x1 = pcl::Min( x1, component( right ) );
1246  y1 = pcl::Min( y1, component( bottom ) );
1247  return IsRect();
1248  }
1249 
1254  template <typename T1>
1256  {
1257  GenericRectangle r1 = *this;
1258  (void)r1.Intersect( r );
1259  return r1;
1260  }
1261 
1269  template <typename T1>
1271  {
1272  GenericRectangle r1 = *this;
1273  (void)r1.IntersectFast( r );
1274  return r1;
1275  }
1276 
1281  template <typename T1>
1282  GenericRectangle& operator &=( const GenericRectangle<T1>& r ) noexcept
1283  {
1284  Intersect( r );
1285  return *this;
1286  }
1287 
1288 #ifdef __PCL_QT_INTERFACE
1289  bool Intersect( const QRect& r ) noexcept
1290  {
1291  return Intersect( r.left(), r.top(), r.right()+1, r.bottom()+1 );
1292  }
1293 
1294  GenericRectangle Intersection( const QRect& r ) const noexcept
1295  {
1296  GenericRectangle r1 = *this;
1297  (void)r1.Intersect( r );
1298  return r1;
1299  }
1300 
1301  GenericRectangle& operator &=( const QRect& r ) noexcept
1302  {
1303  Intersect( r );
1304  return *this;
1305  }
1306 #endif
1307 
1314  template <typename T1>
1315  void Set( T1 left, T1 top, T1 right, T1 bottom ) noexcept
1316  {
1317  x0 = component( left );
1318  y0 = component( top );
1319  x1 = component( right );
1320  y1 = component( bottom );
1321  }
1322 
1330  template <typename T1>
1331  void MoveTo( const pcl::GenericPoint<T1>& p ) noexcept
1332  {
1333  MoveTo( p.x, p.y );
1334  }
1335 
1343  template <typename T1>
1344  void MoveTo( T1 x, T1 y ) noexcept
1345  {
1346  component dx = x1 - x0, dy = y1 - y0;
1347  x0 = component( x );
1348  y0 = component( y );
1349  x1 = x0 + dx;
1350  y1 = y0 + dy;
1351  }
1352 
1353 #ifdef __PCL_QT_INTERFACE
1354  void MoveTo( const QPoint& p ) noexcept
1355  {
1356  MoveTo( p.x(), p.y() );
1357  }
1358 #endif
1359 
1366  template <typename T1>
1368  {
1369  GenericRectangle r( *this );
1370  r.MoveTo( p );
1371  return r;
1372  }
1373 
1380  template <typename T1>
1381  GenericRectangle MovedTo( T1 x, T1 y ) const noexcept
1382  {
1383  GenericRectangle r( *this );
1384  r.MoveTo( x, y );
1385  return r;
1386  }
1387 
1392  template <typename T1>
1393  void MoveBy( const pcl::GenericPoint<T1>& d ) noexcept
1394  {
1395  MoveBy( d.x, d.y );
1396  }
1397 
1403  template <typename T1>
1404  void MoveBy( T1 dx, T1 dy ) noexcept
1405  {
1406  x0 += component( dx );
1407  y0 += component( dy );
1408  x1 += component( dx );
1409  y1 += component( dy );
1410  }
1411 
1421  template <typename T1>
1422  void MoveBy( T1 dxy ) noexcept
1423  {
1424  x0 += component( dxy );
1425  y0 += component( dxy );
1426  x1 += component( dxy );
1427  y1 += component( dxy );
1428  }
1429 
1430 #ifdef __PCL_QT_INTERFACE
1431  void MoveBy( const QPoint& p ) noexcept
1432  {
1433  MoveBy( p.x(), p.y() );
1434  }
1435 #endif
1436 
1443  template <typename T1>
1445  {
1446  GenericRectangle r( *this );
1447  r.MoveBy( d );
1448  return r;
1449  }
1450 
1457  template <typename T1>
1458  GenericRectangle MovedBy( T1 dx, T1 dy ) const noexcept
1459  {
1460  GenericRectangle r( *this );
1461  r.MoveBy( dx, dy );
1462  return r;
1463  }
1464 
1475  template <typename T1>
1476  void ResizeTo( T1 w, T1 h ) noexcept
1477  {
1478  if ( x0 <= x1 )
1479  x1 = x0 + component( w );
1480  else
1481  x0 = x1 + component( w );
1482 
1483  if ( y0 <= y1 )
1484  y1 = y0 + component( h );
1485  else
1486  y0 = y1 + component( h );
1487  }
1488 
1495  template <typename T1>
1496  GenericRectangle ResizedTo( T1 w, T1 h ) const noexcept
1497  {
1498  GenericRectangle r( *this );
1499  r.ResizeTo( w, h );
1500  return r;
1501  }
1502 
1514  template <typename T1>
1515  void ResizeBy( T1 dw, T1 dh ) noexcept
1516  {
1517  if ( x0 <= x1 )
1518  x1 += component( dw );
1519  else
1520  x0 += component( dw );
1521 
1522  if ( y0 <= y1 )
1523  y1 += component( dh );
1524  else
1525  y0 += component( dh );
1526  }
1527 
1534  template <typename T1>
1535  GenericRectangle ResizedBy( T1 dw, T1 dh ) const noexcept
1536  {
1537  GenericRectangle r( *this );
1538  r.ResizeBy( dw, dh );
1539  return r;
1540  }
1541 
1550  template <typename T1>
1551  void SetWidth( T1 w ) noexcept
1552  {
1553  if ( x0 <= x1 )
1554  x1 = x0 + component( w );
1555  else
1556  x0 = x1 + component( w );
1557  }
1558 
1567  template <typename T1>
1568  void SetHeight( T1 h ) noexcept
1569  {
1570  if ( y0 <= y1 )
1571  y1 = y0 + component( h );
1572  else
1573  y0 = y1 + component( h );
1574  }
1575 
1581  template <typename T1>
1582  void InflateBy( T1 dx, T1 dy ) noexcept
1583  {
1584  if ( x1 < x0 )
1585  dx = -dx;
1586  if ( y1 < y0 )
1587  dy = -dy;
1588  x0 -= dx;
1589  y0 -= dy;
1590  x1 += dx;
1591  y1 += dy;
1592  }
1593 
1599  template <typename T1>
1600  void InflateBy( T1 d ) noexcept
1601  {
1602  if ( x0 <= x1 )
1603  x0 -= d, x1 += d;
1604  else
1605  x0 += d, x1 -= d;
1606 
1607  if ( y0 <= y1 )
1608  y0 -= d, y1 += d;
1609  else
1610  y0 += d, y1 -= d;
1611  }
1612 
1617  template <typename T1>
1618  GenericRectangle InflatedBy( T1 dx, T1 dy ) const noexcept
1619  {
1620  GenericRectangle r( *this );
1621  r.InflateBy( dx, dy );
1622  return r;
1623  }
1624 
1629  template <typename T1>
1630  GenericRectangle InflatedBy( T1 d ) const noexcept
1631  {
1632  GenericRectangle r( *this );
1633  r.InflateBy( d );
1634  return r;
1635  }
1636 
1644  void InflateByFactors( double kx, double ky ) noexcept
1645  {
1646  InflateBy( kx*Width()/2, ky*Height()/2 );
1647  }
1648 
1655  void InflateByFactor( double k ) noexcept
1656  {
1657  InflateBy( k*Width()/2, k*Height()/2 );
1658  }
1659 
1665  GenericRectangle InflatedByFactors( double kx, double ky ) noexcept
1666  {
1667  GenericRectangle r( *this );
1668  r.InflateByFactors( kx, ky );
1669  return r;
1670  }
1671 
1677  GenericRectangle InflatedByFactor( double k ) noexcept
1678  {
1679  GenericRectangle r( *this );
1680  r.InflateByFactor( k );
1681  return r;
1682  }
1683 
1689  template <typename T1>
1690  void DeflateBy( T1 dx, T1 dy ) noexcept
1691  {
1692  if ( x1 < x0 )
1693  dx = -dx;
1694  if ( y1 < y0 )
1695  dy = -dy;
1696  x0 += dx;
1697  y0 += dy;
1698  x1 -= dx;
1699  y1 -= dy;
1700  }
1701 
1707  template <typename T1>
1708  void DeflateBy( T1 d ) noexcept
1709  {
1710  if ( x0 <= x1 )
1711  x0 += d, x1 -= d;
1712  else
1713  x0 -= d, x1 += d;
1714 
1715  if ( y0 <= y1 )
1716  y0 += d, y1 -= d;
1717  else
1718  y0 -= d, y1 += d;
1719  }
1720 
1725  template <typename T1>
1726  GenericRectangle DeflatedBy( T1 dx, T1 dy ) const noexcept
1727  {
1728  GenericRectangle r( *this );
1729  r.DeflateBy( dx, dy );
1730  return r;
1731  }
1732 
1737  template <typename T1>
1738  GenericRectangle DeflatedBy( T1 d ) const noexcept
1739  {
1740  GenericRectangle r( *this );
1741  r.DeflateBy( d );
1742  return r;
1743  }
1744 
1751  template <typename T1>
1752  GenericRectangle WidthSetTo( T1 w ) const noexcept
1753  {
1754  GenericRectangle r( *this );
1755  r.SetWidth( w );
1756  return r;
1757  }
1758 
1765  template <typename T1>
1766  GenericRectangle HeightSetTo( T1 h ) const noexcept
1767  {
1768  GenericRectangle r( *this );
1769  r.SetHeight( h );
1770  return r;
1771  }
1772 
1778  template <typename T1, typename T2>
1779  void Rotate( T1 angle, T2 xc, T2 yc ) noexcept
1780  {
1781  T1 sa, ca; pcl::SinCos( angle, sa, ca );
1782  pcl::Rotate( x0, y0, sa, ca, xc, yc );
1783  pcl::Rotate( x1, y1, sa, ca, xc, yc );
1784  }
1785 
1790  template <typename T1, typename T2>
1791  void Rotate( T1 angle, const GenericPoint<T2>& center ) noexcept
1792  {
1793  Rotate( angle, center.x, center.y );
1794  }
1795 
1801  template <typename T1, typename T2>
1802  void Rotate( T1 sa, T1 ca, T2 xc, T2 yc ) noexcept
1803  {
1804  pcl::Rotate( x0, y0, sa, ca, xc, yc );
1805  pcl::Rotate( x1, y1, sa, ca, xc, yc );
1806  }
1807 
1813  template <typename T1, typename T2>
1814  void Rotate( T1 sa, T1 ca, const GenericPoint<T2>& center ) noexcept
1815  {
1816  Rotate( sa, ca, center.x, center.y );
1817  }
1818 
1824  template <typename T1, typename T2>
1825  GenericRectangle Rotated( T1 angle, T2 xc, T2 yc ) const noexcept
1826  {
1827  GenericRectangle r( *this );
1828  r.Rotate( angle, xc, yc );
1829  return r;
1830  }
1831 
1837  template <typename T1, typename T2>
1838  GenericRectangle Rotated( T1 angle, const GenericPoint<T2>& center ) const noexcept
1839  {
1840  GenericRectangle r( *this );
1841  r.Rotate( angle, center );
1842  return r;
1843  }
1844 
1851  template <typename T1, typename T2>
1852  GenericRectangle Rotated( T1 sa, T1 ca, T2 xc, T2 yc ) const noexcept
1853  {
1854  GenericRectangle r( *this );
1855  r.Rotate( sa, ca, xc, yc );
1856  return r;
1857  }
1858 
1865  template <typename T1, typename T2>
1866  GenericRectangle Rotated( T1 sa, T1 ca, const GenericPoint<T2>& center ) const noexcept
1867  {
1868  GenericRectangle r( *this );
1869  r.Rotate( sa, ca, center );
1870  return r;
1871  }
1872 
1877  void Round() noexcept
1878  {
1879  x0 = component( pcl::Round( double( x0 ) ) );
1880  y0 = component( pcl::Round( double( y0 ) ) );
1881  x1 = component( pcl::Round( double( x1 ) ) );
1882  y1 = component( pcl::Round( double( y1 ) ) );
1883  }
1884 
1889  void Round( int n ) noexcept
1890  {
1891  PCL_PRECONDITION( n >= 0 )
1892  if ( n < 0 )
1893  n = 0;
1894  x0 = component( pcl::Round( double( x0 ), n ) );
1895  y0 = component( pcl::Round( double( y0 ), n ) );
1896  x1 = component( pcl::Round( double( x1 ), n ) );
1897  y1 = component( pcl::Round( double( y1 ), n ) );
1898  }
1899 
1904  GenericRectangle Rounded() const noexcept
1905  {
1906  return GenericRectangle( component( pcl::Round( double( x0 ) ) ), component( pcl::Round( double( y0 ) ) ),
1907  component( pcl::Round( double( x1 ) ) ), component( pcl::Round( double( y1 ) ) ) );
1908  }
1909 
1914  GenericRectangle Rounded( int n ) const noexcept
1915  {
1916  PCL_PRECONDITION( n >= 0 )
1917  return GenericRectangle( component( pcl::Round( double( x0 ), n ) ), component( pcl::Round( double( y0 ), n ) ),
1918  component( pcl::Round( double( x1 ), n ) ), component( pcl::Round( double( y1 ), n ) ) );
1919  }
1920 
1926  {
1927  return GenericRectangle<int>( pcl::RoundInt( double( x0 ) ), pcl::RoundInt( double( y0 ) ),
1928  pcl::RoundInt( double( x1 ) ), pcl::RoundInt( double( y1 ) ) );
1929  }
1930 
1936  void Truncate() noexcept
1937  {
1938  x0 = component( pcl::Trunc( double( x0 ) ) );
1939  y0 = component( pcl::Trunc( double( y0 ) ) );
1940  x1 = component( pcl::Trunc( double( x1 ) ) );
1941  y1 = component( pcl::Trunc( double( y1 ) ) );
1942  }
1943 
1950  GenericRectangle Truncated() const noexcept
1951  {
1952  return GenericRectangle( component( pcl::Trunc( double( x0 ) ) ), component( pcl::Trunc( double( y0 ) ) ),
1953  component( pcl::Trunc( double( x1 ) ) ), component( pcl::Trunc( double( y1 ) ) ) );
1954  }
1955 
1963  {
1964  return GenericRectangle<int>( pcl::TruncInt( double( x0 ) ), pcl::TruncInt( double( y0 ) ),
1965  pcl::TruncInt( double( x1 ) ), pcl::TruncInt( double( y1 ) ) );
1966  }
1967 
1972  template <typename T1>
1973  GenericRectangle& operator =( const GenericRectangle<T1>& r ) noexcept
1974  {
1975  x0 = component( r.x0 );
1976  y0 = component( r.y0 );
1977  x1 = component( r.x1 );
1978  y1 = component( r.y1 );
1979  return *this;
1980  }
1981 
1989  template <typename T1>
1990  GenericRectangle& operator =( const pcl::GenericPoint<T1>& p ) noexcept
1991  {
1992  x0 = x1 = component( p.x );
1993  y0 = y1 = component( p.y );
1994  return *this;
1995  }
1996 
2003  GenericRectangle& operator =( component d ) noexcept
2004  {
2005  x0 = y0 = x1 = y1 = d;
2006  return *this;
2007  }
2008 
2009 #ifdef __PCL_QT_INTERFACE
2010  GenericRectangle& operator =( const QRect& r ) noexcept
2011  {
2012  x0 = component( r.left() );
2013  y0 = component( r.top() );
2014  x1 = component( r.right()+1 );
2015  y1 = component( r.bottom()+1 );
2016  return *this;
2017  }
2018 #endif
2019 
2032  template <typename T1>
2033  GenericRectangle& operator +=( const GenericRectangle<T1>& r ) noexcept
2034  {
2035  x0 += component( r.x0 );
2036  y0 += component( r.y0 );
2037  x1 += component( r.x1 );
2038  y1 += component( r.y1 );
2039  return *this;
2040  }
2041 
2055  template <typename T1>
2056  GenericRectangle& operator +=( const pcl::GenericPoint<T1>& p ) noexcept
2057  {
2058  x0 += component( p.x );
2059  y0 += component( p.y );
2060  x1 += component( p.x );
2061  y1 += component( p.y );
2062  return *this;
2063  }
2064 
2079  GenericRectangle& operator +=( component d ) noexcept
2080  {
2081  x0 += d;
2082  y0 += d;
2083  x1 += d;
2084  y1 += d;
2085  return *this;
2086  }
2087 
2088 #ifdef __PCL_QT_INTERFACE
2089  GenericRectangle& operator +=( const QPoint& p ) noexcept
2090  {
2091  component dx = component( p.x() ), dy = component( p.y() );
2092  x0 += dx;
2093  y0 += dy;
2094  x1 += dx;
2095  y1 += dy;
2096  return *this;
2097  }
2098 #endif
2099 
2112  template <typename T1>
2113  GenericRectangle& operator -=( const GenericRectangle<T1>& r ) noexcept
2114  {
2115  x0 -= component( r.x0 );
2116  y0 -= component( r.y0 );
2117  x1 -= component( r.x1 );
2118  y1 -= component( r.y1 );
2119  return *this;
2120  }
2121 
2135  template <typename T1>
2136  GenericRectangle& operator -=( const pcl::GenericPoint<T1>& p ) noexcept
2137  {
2138  x0 -= component( p.x );
2139  y0 -= component( p.y );
2140  x1 -= component( p.x );
2141  y1 -= component( p.y );
2142  return *this;
2143  }
2144 
2159  GenericRectangle& operator -=( component d ) noexcept
2160  {
2161  x0 -= d;
2162  y0 -= d;
2163  x1 -= d;
2164  y1 -= d;
2165  return *this;
2166  }
2167 
2168 #ifdef __PCL_QT_INTERFACE
2169  GenericRectangle& operator -=( const QPoint& p ) noexcept
2170  {
2171  component dx = component( p.x() ), dy = component( p.y() );
2172  x0 -= dx;
2173  y0 -= dy;
2174  x1 -= dx;
2175  y1 -= dy;
2176  return *this;
2177  }
2178 #endif
2179 
2192  template <typename T1>
2193  GenericRectangle& operator *=( const GenericRectangle<T1>& r ) noexcept
2194  {
2195  x0 *= component( r.x0 );
2196  y0 *= component( r.y0 );
2197  x1 *= component( r.x1 );
2198  y1 *= component( r.y1 );
2199  return *this;
2200  }
2201 
2216  template <typename T1>
2217  GenericRectangle& operator *=( const pcl::GenericPoint<T1>& p ) noexcept
2218  {
2219  x0 *= component( p.x );
2220  y0 *= component( p.y );
2221  x1 *= component( p.x );
2222  y1 *= component( p.y );
2223  return *this;
2224  }
2225 
2240  GenericRectangle& operator *=( component d ) noexcept
2241  {
2242  x0 *= d;
2243  y0 *= d;
2244  x1 *= d;
2245  y1 *= d;
2246  return *this;
2247  }
2248 
2249 #ifdef __PCL_QT_INTERFACE
2250  GenericRectangle& operator *=( const QPoint& p ) noexcept
2251  {
2252  component dx = component( p.x() ), dy = component( p.y() );
2253  x0 *= dx; y0 *= dy; x1 *= dx; y1 *= dy;
2254  return *this;
2255  }
2256 #endif
2257 
2270  template <typename T1>
2271  GenericRectangle& operator /=( const GenericRectangle<T1>& r ) noexcept
2272  {
2273  PCL_PRECONDITION( component( r.x0 ) != component( 0 ) && component( r.y0 ) != component( 0 ) &&
2274  component( r.x1 ) != component( 0 ) && component( r.y1 ) != component( 0 ) )
2275  x0 /= component( r.x0 );
2276  y0 /= component( r.y0 );
2277  x1 /= component( r.x1 );
2278  y1 /= component( r.y1 );
2279  return *this;
2280  }
2281 
2296  template <typename T1>
2297  GenericRectangle& operator /=( const pcl::GenericPoint<T1>& p ) noexcept
2298  {
2299  PCL_PRECONDITION( component( p.x ) != component( 0 ) && component( p.y ) != component( 0 ) )
2300  x0 /= component( p.x );
2301  y0 /= component( p.y );
2302  x1 /= component( p.x );
2303  y1 /= component( p.y );
2304  return *this;
2305  }
2306 
2321  GenericRectangle& operator /=( component d ) noexcept
2322  {
2323  PCL_PRECONDITION( d != component( 0 ) )
2324  x0 /= d; y0 /= d; x1 /= d; y1 /= d;
2325  return *this;
2326  }
2327 
2328 #ifdef __PCL_QT_INTERFACE
2329  GenericRectangle& operator /=( const QPoint& p ) noexcept
2330  {
2331  PCL_PRECONDITION( component( p.x() ) != component( 0 ) && component( p.y() ) != component( 0 ) )
2332  component dx = component( p.x() ), dy = component( p.y() );
2333  x0 /= dx;
2334  y0 /= dy;
2335  x1 /= dx;
2336  y1 /= dy;
2337  return *this;
2338  }
2339 #endif
2340 
2344  GenericRectangle operator +() const noexcept
2345  {
2346  return *this;
2347  }
2348 
2355  GenericRectangle operator -() const noexcept
2356  {
2357  return GenericRectangle( -x0, -y0, -x1, -y1 );
2358  }
2359 
2360 #ifdef __PCL_QT_INTERFACE
2361  operator QRect() const noexcept
2362  {
2363  return QRect( int( x0 ), int( y0 ), int( x1-x0 ), int( y1-y0 ) );
2364  }
2365 #endif
2366 
2367 #ifdef __PCL_QT_INTERFACE
2368 # ifndef __PCL_QT_NO_RECT_DRAWING_HELPERS
2369 
2370  void Draw( QPainter& p, const QBrush* b ) const
2371  {
2372  int rx0, ry0, rx1, ry1;
2373 
2374  if ( x0 <= x1 )
2375  rx0 = x0, rx1 = x1;
2376  else
2377  rx0 = x1, rx1 = x0;
2378 
2379  if ( y0 <= y1 )
2380  ry0 = y0, ry1 = y1;
2381  else
2382  ry0 = y1, ry1 = y0;
2383 
2384  if ( rx1 - rx0 <= 1 )
2385  {
2386  if ( ry1 - ry0 <= 1 )
2387  p.drawPoint( rx0, ry0 );
2388  else
2389  p.drawLine( rx0, ry0, rx0, ry1-1 );
2390  }
2391  else if ( ry1 - ry0 <= 1 )
2392  {
2393  p.drawLine( rx0, ry0, rx1-1, ry0 );
2394  }
2395  else
2396  {
2397 # if ( QT_VERSION >= 0x040000 )
2398  int w = rx1-rx0-1, h = ry1-ry0-1;
2399 # else
2400  int w = rx1-rx0, h = ry1-ry0;
2401 # endif
2402  if ( b != 0 )
2403  p.fillRect( rx0, ry0, w, h, *b );
2404  p.drawRect( rx0, ry0, w, h );
2405  }
2406  }
2407 
2408  void Draw( QPainter& p ) const
2409  {
2410  Draw( p, 0 );
2411  }
2412 
2413  void Draw( QPainter& p, const QColor& c ) const
2414  {
2415  QBrush b( c );
2416  Draw( p, &b );
2417  }
2418 
2419 # endif // !__PCL_QT_NO_RECT_DRAWING_HELPERS
2420 #endif // __PCL_QT_INTERFACE
2421 
2422 }; // GenericRectangle<T>
2423 
2424 #undef PCL_ASSERT_RECT_SIZE
2425 
2426 // ----------------------------------------------------------------------------
2427 
2437 template <typename T1, typename T2> inline
2438 bool operator ==( const GenericRectangle<T1>& r1, const GenericRectangle<T2>& r2 ) noexcept
2439 {
2440  return r1.x0 == r2.x0 && r1.y0 == r2.y0 && r1.x1 == r2.x1 && r1.y1 == r2.y1;
2441 }
2442 
2448 template <typename T> inline
2449 bool operator ==( const GenericRectangle<T>& r1, T d2 ) noexcept
2450 {
2451  return r1.x0 == d2 && r1.y0 == d2 && r1.x1 == d2 && r1.y1 == d2;
2452 }
2453 
2460 template <typename T> inline
2461 bool operator ==( T d1, const GenericRectangle<T>& r2 ) noexcept
2462 {
2463  return d1 == r2.x0 && d1 == r2.y0 && d1 == r2.x1 && d1 == r2.y1;
2464 }
2465 
2472 template <typename T1, typename T2> inline
2473 bool operator <( const GenericRectangle<T1>& r1, const GenericRectangle<T2>& r2 ) noexcept
2474 {
2475  T1 x01 = Min( r1.x0, r1.x1 ); T1 y01 = Min( r1.y0, r1.y1 );
2476  T1 x11 = Max( r1.x0, r1.x1 ); T1 y11 = Max( r1.y0, r1.y1 );
2477  T2 x02 = Min( r2.x0, r2.x1 ); T2 y02 = Min( r2.y0, r2.y1 );
2478  T2 x12 = Max( r2.x0, r2.x1 ); T2 y12 = Max( r2.y0, r2.y1 );
2479  if ( y01 != y02 )
2480  return y01 < y02;
2481  if ( x01 != x02 )
2482  return x01 < x02;
2483  if ( y11 != y12 )
2484  return y11 < y12;
2485  return x11 < x12;
2486 }
2487 
2503 template <typename T1, typename T2> inline
2505 {
2506  return GenericRectangle<T1>( T1( r1.x0 + r2.x0 ), T1( r1.y0 + r2.y0 ),
2507  T1( r1.x1 + r2.x1 ), T1( r1.y1 + r2.y1 ) );
2508 }
2509 
2524 template <typename T1, typename T2> inline
2526 {
2527  return GenericRectangle<T1>( T1( r1.x0 + p2.x ), T1( r1.y0 + p2.y ),
2528  T1( r1.x1 + p2.x ), T1( r1.y1 + p2.y ) );
2529 }
2530 
2540 template <typename T1, typename T2> inline
2542 {
2543  return GenericRectangle<T2>( T2( p1.x + r2.x0 ), T2( p1.y + r2.y0 ),
2544  T2( p1.x + r2.x1 ), T2( p1.y + r2.y1 ) );
2545 }
2546 
2561 template <typename T> inline
2563 {
2564  return GenericRectangle<T>( r1.x0+d2, r1.y0+d2, r1.x1+d2, r1.y1+d2 );
2565 }
2566 
2576 template <typename T> inline
2578 {
2579  return GenericRectangle<T>( d1+r2.x0, d1+r2.y0, d1+r2.x1, d1+r2.y1 );
2580 }
2581 
2597 template <typename T1, typename T2> inline
2599 {
2600  return GenericRectangle<T1>( T1( r1.x0 - r2.x0 ), T1( r1.y0 - r2.y0 ),
2601  T1( r1.x1 - r2.x1 ), T1( r1.y1 - r2.y1 ) );
2602 }
2603 
2618 template <typename T1, typename T2> inline
2620 {
2621  return GenericRectangle<T1>( T1( r1.x0 - p2.x ), T1( r1.y0 - p2.y ),
2622  T1( r1.x1 - p2.x ), T1( r1.y1 - p2.y ) );
2623 }
2624 
2639 template <typename T1, typename T2> inline
2641 {
2642  return GenericRectangle<T2>( T2( p1.x - r2.x0 ), T2( p1.y - r2.y0 ),
2643  T2( p1.x - r2.x1 ), T2( p1.y - r2.y1 ) );
2644 }
2645 
2660 template <typename T> inline
2662 {
2663  return GenericRectangle<T>( r1.x0-d2, r1.y0-d2, r1.x1-d2, r1.y1-d2 );
2664 }
2665 
2680 template <typename T> inline
2682 {
2683  return GenericRectangle<T>( d1-r2.x0, d1-r2.y0, d1-r2.x1, d1-r2.y1 );
2684 }
2685 
2701 template <typename T1, typename T2> inline
2703 {
2704  return GenericRectangle<T1>( T1( r1.x0 * r2.x0 ), T1( r1.y0 * r2.y0 ),
2705  T1( r1.x1 * r2.x1 ), T1( r1.y1 * r2.y1 ) );
2706 }
2707 
2722 template <typename T1, typename T2> inline
2724 {
2725  return GenericRectangle<T1>( T1( r1.x0 * p2.x ), T1( r1.y0 * p2.y ),
2726  T1( r1.x1 * p2.x ), T1( r1.y1 * p2.y ) );
2727 }
2728 
2738 template <typename T1, typename T2> inline
2740 {
2741  return GenericRectangle<T2>( T2( p1.x * r2.x0 ), T2( p1.y * r2.y0 ),
2742  T2( p1.x * r2.x1 ), T2( p1.y * r2.y1 ) );
2743 }
2744 
2759 template <typename T> inline
2761 {
2762  return GenericRectangle<T>( r1.x0*d2, r1.y0*d2, r1.x1*d2, r1.y1*d2 );
2763 }
2764 
2774 template <typename T> inline
2776 {
2777  return GenericRectangle<T>( d1*r2.x0, d1*r2.y0, d1*r2.x1, d1*r2.y1 );
2778 }
2779 
2795 template <typename T1, typename T2> inline
2797 {
2798  PCL_PRECONDITION( r2.x0 != T2( 0 ) && r2.y0 != T2( 0 ) &&
2799  r2.x1 != T2( 0 ) && r2.y1 != T2( 0 ) )
2800  return GenericRectangle<T1>( T1( r1.x0 / r2.x0 ), T1( r1.y0 / r2.y0 ),
2801  T1( r1.x1 / r2.x1 ), T1( r1.y1 / r2.y1 ) );
2802 }
2803 
2818 template <typename T1, typename T2> inline
2820 {
2821  PCL_PRECONDITION( p2.x != T2( 0 ) && p2.y != T2( 0 ) )
2822  return GenericRectangle<T1>( T1( r1.x0 / p2.x ), T1( r1.y0 / p2.y ),
2823  T1( r1.x1 / p2.x ), T1( r1.y1 / p2.y ) );
2824 }
2825 
2840 template <typename T1, typename T2> inline
2842 {
2843  PCL_PRECONDITION( r2.x0 != T2( 0 ) && r2.y0 != T2( 0 ) &&
2844  r2.x1 != T2( 0 ) && r2.y1 != T2( 0 ) )
2845  return GenericRectangle<T2>( T2( p1.x / r2.x0 ), T2( p1.y / r2.y0 ),
2846  T2( p1.x / r2.x1 ), T2( p1.y / r2.y1 ) );
2847 }
2848 
2863 template <typename T> inline
2865 {
2866  PCL_PRECONDITION( d2 != T( 0 ) )
2867  return GenericRectangle<T>( r1.x0/d2, r1.y0/d2, r1.x1/d2, r1.y1/d2 );
2868 }
2869 
2884 template <typename T> inline
2886 {
2887  PCL_PRECONDITION( r2.x0 != T( 0 ) && r2.y0 != T( 0 ) &&
2888  r2.x1 != T( 0 ) && r2.y1 != T( 0 ) )
2889  return GenericRectangle<T>( d1/r2.x0, d1/r2.y0, d1/r2.x1, d1/r2.y1 );
2890 }
2891 
2907 template <typename T, typename T1, typename T2> inline
2908 void Rotate( GenericRectangle<T>& r, T1 a, T2 xc, T2 yc ) noexcept
2909 {
2910  T1 sa, ca; pcl::SinCos( a, sa, ca );
2911  pcl::Rotate( r.x0, r.y0, sa, ca, xc, yc );
2912  pcl::Rotate( r.x1, r.y1, sa, ca, xc, yc );
2913 }
2914 
2930 template <typename T, typename T1, typename T2> inline
2931 void Rotate( GenericRectangle<T>& r, T1 a, const GenericPoint<T2>& c ) noexcept
2932 {
2933  pcl::Rotate( r, a, c.x, c.y );
2934 }
2935 
2951 template <typename T, typename T1, typename T2> inline
2952 void Rotate( GenericRectangle<T>& r, T1 sa, T1 ca, T2 xc, T2 yc ) noexcept
2953 {
2954  pcl::Rotate( r.x0, r.y0, sa, ca, xc, yc );
2955  pcl::Rotate( r.x1, r.y1, sa, ca, xc, yc );
2956 }
2957 
2973 template <typename T, typename T1, typename T2> inline
2974 void Rotate( GenericRectangle<T>& r, T1 sa, T1 ca, const GenericPoint<T2>& c ) noexcept
2975 {
2976  pcl::Rotate( r, sa, ca, c.x, c.y );
2977 }
2978 
2990 template <typename T> inline
2992 {
2993  pcl::Swap( r1.x0, r2.x0 ); pcl::Swap( r1.y0, r2.y0 );
2994  pcl::Swap( r1.x1, r2.x1 ); pcl::Swap( r1.y1, r2.y1 );
2995 }
2996 
2997 // ----------------------------------------------------------------------------
2998 
2999 #ifndef __PCL_NO_RECT_INSTANTIATE
3000 
3012 using I32Rect = GenericRectangle<int32>;
3013 
3022 using Rect = I32Rect;
3023 
3031 using F32Rect = GenericRectangle<float>;
3032 
3041 using FRect = F32Rect;
3042 
3050 using F64Rect = GenericRectangle<double>;
3051 
3060 using DRect = F64Rect;
3061 
3062 #endif
3063 
3064 // ----------------------------------------------------------------------------
3065 
3066 } // pcl
3067 
3068 #endif // __PCL_Rectangle_h
3069 
3070 // ----------------------------------------------------------------------------
3071 // EOF pcl/Rectangle.h - Released 2024-06-18T15:48:54Z
64-bit floating-point rectangle in the R^2 space.
32-bit floating-point rectangle in the R^2 space.
64-bit floating-point rectangle in the R^2 space.
32-bit floating-point rectangle in the R^2 space.
A type-safe collection of enumerated flags.
Definition: Flags.h:85
A generic point in the two-dimensional space.
Definition: Point.h:100
A generic rectangle in the two-dimensional space.
Definition: Rectangle.h:314
point BottomRight() const noexcept
Definition: Rectangle.h:586
GenericRectangle Truncated() const noexcept
Definition: Rectangle.h:1950
GenericRectangle(const pcl::GenericPoint< T1 > &leftTop, const pcl::GenericPoint< T1 > &rightBottom)
Definition: Rectangle.h:425
bool IsPointOrLine() const noexcept
Definition: Rectangle.h:753
component Left() const noexcept
Definition: Rectangle.h:491
constexpr GenericRectangle(component d)
Definition: Rectangle.h:453
void MoveBy(const pcl::GenericPoint< T1 > &d) noexcept
Definition: Rectangle.h:1393
void SetWidth(T1 w) noexcept
Definition: Rectangle.h:1551
GenericRectangle Rotated(T1 angle, const GenericPoint< T2 > &center) const noexcept
Definition: Rectangle.h:1838
void Round() noexcept
Definition: Rectangle.h:1877
component Perimeter() const noexcept
Definition: Rectangle.h:653
double CenterY() const noexcept
Definition: Rectangle.h:692
constexpr GenericRectangle(T1 left, T1 top, T1 right, T1 bottom)
Definition: Rectangle.h:357
GenericRectangle IntersectionFast(const GenericRectangle< T1 > &r) const noexcept
Definition: Rectangle.h:1270
bool IntersectsFast(const pcl::GenericRectangle< T1 > &r) const noexcept
Definition: Rectangle.h:986
void Round(int n) noexcept
Definition: Rectangle.h:1889
point LeftTop() const noexcept
Definition: Rectangle.h:527
void UniteFast(T1 left, T1 top, T1 right, T1 bottom) noexcept
Definition: Rectangle.h:1075
component x1
Horizontal coordinate of the lower right corner.
Definition: Rectangle.h:334
void Unite(T1 left, T1 top, T1 right, T1 bottom) noexcept
Definition: Rectangle.h:1012
GenericRectangle Rounded(int n) const noexcept
Definition: Rectangle.h:1914
void MoveTo(T1 x, T1 y) noexcept
Definition: Rectangle.h:1344
GenericRectangle InflatedByFactors(double kx, double ky) noexcept
Definition: Rectangle.h:1665
point RightTop() const noexcept
Definition: Rectangle.h:544
bool Intersect(T1 left, T1 top, T1 right, T1 bottom) noexcept
Definition: Rectangle.h:1168
double CenterX() const noexcept
Definition: Rectangle.h:683
bool IsOrdered() const noexcept
Definition: Rectangle.h:778
component Area() const noexcept
Definition: Rectangle.h:674
void MoveBy(T1 dx, T1 dy) noexcept
Definition: Rectangle.h:1404
GenericRectangle InflatedBy(T1 dx, T1 dy) const noexcept
Definition: Rectangle.h:1618
component Bottom() const noexcept
Definition: Rectangle.h:518
GenericRectangle InflatedBy(T1 d) const noexcept
Definition: Rectangle.h:1630
point CenterLeft() const noexcept
Definition: Rectangle.h:618
void InflateBy(T1 d) noexcept
Definition: Rectangle.h:1600
constexpr GenericRectangle(component width, component height)
Definition: Rectangle.h:440
void DeflateBy(T1 d) noexcept
Definition: Rectangle.h:1708
component y1
Vertical coordinate of the lower right corner.
Definition: Rectangle.h:335
point TopLeft() const noexcept
Definition: Rectangle.h:535
point Center() const noexcept
Definition: Rectangle.h:594
point LeftBottom() const noexcept
Definition: Rectangle.h:561
void InflateBy(T1 dx, T1 dy) noexcept
Definition: Rectangle.h:1582
point CenterBottom() const noexcept
Definition: Rectangle.h:610
bool IsRect() const noexcept
Definition: Rectangle.h:762
GenericRectangle InflatedByFactor(double k) noexcept
Definition: Rectangle.h:1677
bool IsVerticalLine() const noexcept
Definition: Rectangle.h:745
GenericRectangle Rotated(T1 sa, T1 ca, const GenericPoint< T2 > &center) const noexcept
Definition: Rectangle.h:1866
void InflateByFactors(double kx, double ky) noexcept
Definition: Rectangle.h:1644
bool IsHorizontalLine() const noexcept
Definition: Rectangle.h:737
GenericRectangle Rotated(T1 sa, T1 ca, T2 xc, T2 yc) const noexcept
Definition: Rectangle.h:1852
GenericRectangle< int > RoundedToInt() const noexcept
Definition: Rectangle.h:1925
GenericRectangle< int > TruncatedToInt() const noexcept
Definition: Rectangle.h:1962
point RightBottom() const noexcept
Definition: Rectangle.h:578
void ResizeTo(T1 w, T1 h) noexcept
Definition: Rectangle.h:1476
bool IsNormal() const noexcept
Definition: Rectangle.h:770
component y0
Vertical coordinate of the upper left corner.
Definition: Rectangle.h:333
bool IntersectsFast(T1 left, T1 top, T1 right, T1 bottom) const noexcept
Definition: Rectangle.h:974
bool Includes(T1 x, T1 y) const noexcept
Definition: Rectangle.h:857
component x0
Horizontal coordinate of the upper left corner.
Definition: Rectangle.h:332
void Set(T1 left, T1 top, T1 right, T1 bottom) noexcept
Definition: Rectangle.h:1315
GenericRectangle Rotated(T1 angle, T2 xc, T2 yc) const noexcept
Definition: Rectangle.h:1825
GenericRectangle MovedTo(const pcl::GenericPoint< T1 > &p) const noexcept
Definition: Rectangle.h:1367
void DeflateBy(T1 dx, T1 dy) noexcept
Definition: Rectangle.h:1690
point CenterTop() const noexcept
Definition: Rectangle.h:602
GenericRectangle ResizedBy(T1 dw, T1 dh) const noexcept
Definition: Rectangle.h:1535
void UniteFast(const GenericRectangle< T1 > &r) noexcept
Definition: Rectangle.h:1050
void Rotate(T1 sa, T1 ca, T2 xc, T2 yc) noexcept
Definition: Rectangle.h:1802
void InflateByFactor(double k) noexcept
Definition: Rectangle.h:1655
GenericRectangle UnionFast(const GenericRectangle< T1 > &r) const noexcept
Definition: Rectangle.h:1101
bool Intersects(const pcl::GenericRectangle< T1 > &r) const noexcept
Definition: Rectangle.h:942
ClipFlags ClipCode(T1 x, T1 y) const noexcept
Definition: Rectangle.h:810
void Order() noexcept
Definition: Rectangle.h:786
GenericRectangle HeightSetTo(T1 h) const noexcept
Definition: Rectangle.h:1766
component Right() const noexcept
Definition: Rectangle.h:509
GenericRectangle MovedBy(T1 dx, T1 dy) const noexcept
Definition: Rectangle.h:1458
bool Includes(const GenericRectangle< T1 > &r) const noexcept
Definition: Rectangle.h:876
bool Includes(const pcl::GenericPoint< T1 > &p) const noexcept
Definition: Rectangle.h:867
point CenterRight() const noexcept
Definition: Rectangle.h:626
GenericRectangle ResizedTo(T1 w, T1 h) const noexcept
Definition: Rectangle.h:1496
bool IntersectFast(const GenericRectangle< T1 > &r) noexcept
Definition: Rectangle.h:1212
void Unite(const GenericRectangle< T1 > &r) noexcept
Definition: Rectangle.h:996
bool IncludesFast(const pcl::GenericPoint< T1 > &p) const noexcept
Definition: Rectangle.h:915
bool IntersectFast(T1 left, T1 top, T1 right, T1 bottom) noexcept
Definition: Rectangle.h:1241
void Rotate(T1 angle, T2 xc, T2 yc) noexcept
Definition: Rectangle.h:1779
void ResizeBy(T1 dw, T1 dh) noexcept
Definition: Rectangle.h:1515
double Hypot() const noexcept
Definition: Rectangle.h:703
bool IsPoint() const noexcept
Definition: Rectangle.h:721
void Rotate(T1 angle, const GenericPoint< T2 > &center) noexcept
Definition: Rectangle.h:1791
void MoveTo(const pcl::GenericPoint< T1 > &p) noexcept
Definition: Rectangle.h:1331
GenericRectangle DeflatedBy(T1 d) const noexcept
Definition: Rectangle.h:1738
bool Intersect(const GenericRectangle< T1 > &r) noexcept
Definition: Rectangle.h:1148
GenericRectangle DeflatedBy(T1 dx, T1 dy) const noexcept
Definition: Rectangle.h:1726
GenericRectangle(std::initializer_list< T1 > l)
Definition: Rectangle.h:392
point TopRight() const noexcept
Definition: Rectangle.h:552
point BottomLeft() const noexcept
Definition: Rectangle.h:569
ClipFlags ClipCode(const pcl::GenericPoint< T1 > &p) const noexcept
Definition: Rectangle.h:847
component ManhattanDistance() const noexcept
Definition: Rectangle.h:665
GenericRectangle(const GenericRectangle< T1 > &r)
Definition: Rectangle.h:464
constexpr GenericRectangle()
Definition: Rectangle.h:341
GenericRectangle Union(const GenericRectangle< T1 > &r) const noexcept
Definition: Rectangle.h:1087
GenericRectangle Ordered() const noexcept
Definition: Rectangle.h:794
component Top() const noexcept
Definition: Rectangle.h:500
component Width() const noexcept
Definition: Rectangle.h:635
bool IncludesFast(T1 x, T1 y) const noexcept
Definition: Rectangle.h:902
GenericRectangle MovedBy(const pcl::GenericPoint< T1 > &d) const noexcept
Definition: Rectangle.h:1444
GenericRectangle MovedTo(T1 x, T1 y) const noexcept
Definition: Rectangle.h:1381
component Height() const noexcept
Definition: Rectangle.h:644
void MoveBy(T1 dxy) noexcept
Definition: Rectangle.h:1422
void SetHeight(T1 h) noexcept
Definition: Rectangle.h:1568
double Diagonal() const noexcept
Definition: Rectangle.h:713
GenericRectangle Intersection(const GenericRectangle< T1 > &r) const noexcept
Definition: Rectangle.h:1255
void Truncate() noexcept
Definition: Rectangle.h:1936
GenericRectangle Rounded() const noexcept
Definition: Rectangle.h:1904
GenericRectangle WidthSetTo(T1 w) const noexcept
Definition: Rectangle.h:1752
void Rotate(T1 sa, T1 ca, const GenericPoint< T2 > &center) noexcept
Definition: Rectangle.h:1814
bool IsLine() const noexcept
Definition: Rectangle.h:729
bool Intersects(T1 left, T1 top, T1 right, T1 bottom) const noexcept
Definition: Rectangle.h:931
32-bit integer rectangle on the plane.
32-bit integer rectangle on the plane.
bool operator==(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
Definition: Array.h:2267
bool operator<(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
Definition: Array.h:2278
Complex< T1 > operator-(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:504
Complex< T1 > operator*(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:548
Complex< T1 > operator+(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:464
Complex< T1 > operator/(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:592
Complex< T > Sqrt(const Complex< T > &c) noexcept
Definition: Complex.h:674
T Abs(const Complex< T > &c) noexcept
Definition: Complex.h:429
Complex< T > Round(const Complex< T > &c) noexcept
Definition: Complex.h:938
void SinCos(T x, T &sx, T &cx) noexcept
Definition: Math.h:1030
void Rotate(T &x, T &y, T1 sa, T1 ca, T2 xc, T2 yc) noexcept
Definition: Math.h:2024
T Trunc(T x) noexcept
Definition: Math.h:1095
int RoundInt(T x) noexcept
Definition: Math.h:1503
int TruncInt(T x) noexcept
Definition: Math.h:1132
void Swap(GenericPoint< T > &p1, GenericPoint< T > &p2) noexcept
Definition: Point.h:1459
bool IsHorizontalLine(T x0, T y0, T x1, T y1) noexcept
Definition: Rectangle.h:159
bool IsNormalRect(T x0, T y0, T x1, T y1) noexcept
Definition: Rectangle.h:226
bool IsRect(T x0, T y0, T x1, T y1) noexcept
Definition: Rectangle.h:210
bool IsOrderedRect(T x0, T y0, T x1, T y1) noexcept
Definition: Rectangle.h:243
bool IsLine(T x0, T y0, T x1, T y1) noexcept
Definition: Rectangle.h:142
bool IsVerticalLine(T x0, T y0, T x1, T y1) noexcept
Definition: Rectangle.h:176
bool IsPointOrLine(T x0, T y0, T x1, T y1) noexcept
Definition: Rectangle.h:193
bool IsPoint(T x0, T y0, T x1, T y1) noexcept
Definition: Rectangle.h:124
void OrderRect(T &x0, T &y0, T &x1, T &y1) noexcept
Definition: Rectangle.h:260
constexpr const T & Min(const T &a, const T &b) noexcept
Definition: Utility.h:90
constexpr const T & Max(const T &a, const T &b) noexcept
Definition: Utility.h:119
PCL root namespace.
Definition: AbstractImage.h:77