// ____ ______ __ // / __ \ / ____// / // / /_/ // / / / // / ____// /___ / /___ PixInsight Class Library // /_/ \____//_____/ PCL 2.4.23 // ---------------------------------------------------------------------------- // pcl/Rectangle.h - Released 2022-03-12T18:59:29Z // ---------------------------------------------------------------------------- // This file is part of the PixInsight Class Library (PCL). // PCL is a multiplatform C++ framework for development of PixInsight modules. // // Copyright (c) 2003-2022 Pleiades Astrophoto S.L. All Rights Reserved. // // Redistribution and use in both source and binary forms, with or without // modification, is permitted provided that the following conditions are met: // // 1. All redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 2. All redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names // of their contributors, may be used to endorse or promote products derived // from this software without specific prior written permission. For written // permission, please contact info@pixinsight.com. // // 4. All products derived from this software, in any form whatsoever, must // reproduce the following acknowledgment in the end-user documentation // and/or other materials provided with the product: // // "This product is based on software from the PixInsight project, developed // by Pleiades Astrophoto and its contributors (https://pixinsight.com/)." // // Alternatively, if that is where third-party acknowledgments normally // appear, this acknowledgment must be reproduced in the product itself. // // THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS // INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE, // DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // ---------------------------------------------------------------------------- #ifndef __PCL_Rectangle_h #define __PCL_Rectangle_h /// \file pcl/Rectangle.h #include #include #include #include #include #ifdef __PCL_QT_INTERFACE # include # ifndef __PCL_QT_NO_RECT_DRAWING_HELPERS # include # include # endif #endif namespace pcl { // ---------------------------------------------------------------------------- /*! * \namespace pcl::Clip * \brief %Clip codes used by the Sutherland-Cohen line clipping algorithm. * * Sutherland-Cohen clip codes: * * * * * * *
Clip::Left Clipping occurs at the left side of the clipping rectangle
Clip::Top Clipping occurs at the top side of the clipping rectangle
Clip::Right Clipping occurs at the right side of the clipping rectangle
Clip::Bottom Clipping occurs at the bottom side of the clipping rectangle
*/ namespace Clip { enum mask_type { Left = 0x01, // Clipped at the left side Top = 0x02, // Clipped at the top side Right = 0x04, // Clipped at the right side Bottom = 0x08 // Clipped at the bottom side }; } /*! * A collection of Sutherland-Cohen clip code flags. */ typedef Flags ClipFlags; // ---------------------------------------------------------------------------- /*! * \defgroup rect_classification_2d Rectangle Classification Functions */ /*! * Returns true iff a set of rectangle coordinates correspond to a point. * * \param x0,y0 Upper left corner coordinates. * \param x1,y1 Lower right corner coordinates. * * The specified coordinates define a point if and only if * \a x0 = \a x1 and \a y0 = \a y1. * * \ingroup rect_classification_2d */ template inline bool IsPoint( T x0, T y0, T x1, T y1 ) noexcept { return x0 == x1 && y0 == y1; } /*! * Returns true iff a set of rectangle coordinates define a line. * * \param x0,y0 Upper left corner coordinates. * \param x1,y1 Lower right corner coordinates. * * The specified coordinates define a line if any of two conditions hold: * \a x0 = \a x1 or \a y0 = \a y1, but not both conditions, that is, if * the coordinates don't define a point. * * \ingroup rect_classification_2d */ template inline bool IsLine( T x0, T y0, T x1, T y1 ) noexcept { return ((x0 == x1) ^ (y0 == y1)) != 0; } /*! * Returns true iff a set of rectangle coordinates define a horizontal line. * * \param x0,y0 Upper left corner coordinates. * \param x1,y1 Lower right corner coordinates. * * The specified coordinates define a horizontal line if and only if * \a y0 = \a y1 and \a x0 != \a x1. * * \ingroup rect_classification_2d */ template inline bool IsHorizontalLine( T x0, T y0, T x1, T y1 ) noexcept { return y0 == y1 && x0 != x1; } /*! * Returns true iff a set of rectangle coordinates define a vertical line. * * \param x0,y0 Upper left corner coordinates. * \param x1,y1 Lower right corner coordinates. * * The specified coordinates define a vertical line if and only if * \a x0 = \a x1 and \a y0 != \a y1. * * \ingroup rect_classification_2d */ template inline bool IsVerticalLine( T x0, T y0, T x1, T y1 ) noexcept { return x0 == x1 && y0 != y1; } /*! * Returns true iff a set of rectangle coordinates define a point or a line. * * \param x0,y0 Upper left corner coordinates. * \param x1,y1 Lower right corner coordinates. * * The specified coordinates define a point or line if either * \a x0 = \a x1 or \a y0 = \a y1. * * \ingroup rect_classification_2d */ template inline bool IsPointOrLine( T x0, T y0, T x1, T y1 ) noexcept { return x0 == x1 || y0 == y1; } /*! * Returns true iff a set of rectangle coordinates define a rectangle. * * \param x0,y0 Upper left corner coordinates. * \param x1,y1 Lower right corner coordinates. * * The specified coordinates define a rectangle if and only if * \a x0 != \a x1 and \a y0 != \a y1. * * \ingroup rect_classification_2d */ template inline bool IsRect( T x0, T y0, T x1, T y1 ) noexcept { return x0 != x1 && y0 != y1; } /*! * Returns true iff a set of rectangle coordinates define a normal rectangle. * * \param x0,y0 Upper left corner coordinates. * \param x1,y1 Lower right corner coordinates. * * A normal rectangle requires that \a x0 < \a x1 and \a y0 < \a y1. * * \ingroup rect_classification_2d */ template inline bool IsNormalRect( T x0, T y0, T x1, T y1 ) noexcept { return x0 < x1 && y0 < y1; } /*! * Returns true iff a set of rectangle coordinates define an ordered rectangle. * * \param x0,y0 Upper left corner coordinates. * \param x1,y1 Lower right corner coordinates. * * An ordered rectangle requires that \a x0 <= \a x1 and \a y0 <= \a y1, that * is, it can be a normal rectangle, a line, or a point. * * \ingroup rect_classification_2d */ template inline bool IsOrderedRect( T x0, T y0, T x1, T y1 ) noexcept { return x0 <= x1 && y0 <= y1; } /*! * Orders a set of rectangle coordinates to define an ordered rectangle. * * \param[out] x0,y0 References to the upper left corner coordinates. * \param[out] x1,y1 References to the lower right corner coordinates. * * This function ensures that \a x0 <= \a x1 and \a y0 <= \a y1, by exchanging * coordinates if necessary. * * \ingroup rect_classification_2d */ template inline void OrderRect( T& x0, T& y0, T& x1, T& y1 ) noexcept { if ( x1 < x0 ) pcl::Swap( x0, x1 ); if ( y1 < y0 ) pcl::Swap( y0, y1 ); } // ---------------------------------------------------------------------------- /* * ### NB: Template class GenericRectangle cannot have virtual member * functions. This is because internal PCL and core routines rely on * GenericRectangle, GenericRectangle and * GenericRectangle to be directly castable to int*, float* and * double*, respectively. See also the PCL_ASSERT_RECT_SIZE() macro. */ #define PCL_ASSERT_RECT_SIZE() \ static_assert( sizeof( *this ) == 4*sizeof( T ), "Invalid sizeof( GenericRectangle<> )" ) /*! * \class GenericRectangle * \brief A generic rectangle in the two-dimensional space. * * %GenericRectangle implements a rectangle in the plane, specified by the \a x * and \a y coordinates of two of its corners. The type T represents scalar * rectangle coordinates and can be any real or integer numerical type. * * The coordinates of %GenericRectangle are directly accessed by its x0, y0, x1 * and y1 data members. If the rectangle is \e ordered, x0 and y0 are the * coordinates of its upper left corner, and x1, y1 are the coordinates of its * lower right corner. Given a %GenericRectangle instance \a r, you can use * \a r.x0, \a r.y0, \a r.x1 and \a r.y1 directly to get or set coordinate * values. * * \b Important - In PCL, the right and bottom coordinates of a rectangle (that * is, the values of its x1 and y1 members) are \e excluded from the * corresponding rectangular area. The following holds for any rectangle \a r * in PCL: * * \a r.Width() = \a r.x1 - \a r.x0 \n * \a r.Height() = \a r.y1 - \a r.y0 * * This is particularly relevant with template instantiations for integer * types, as GenericRectangle\. * * \sa \ref rect_types_2d "2-D Rectangle Types", * \ref rect_functions_2d "2-D Rectangle Operators and Functions", * \ref rect_classification_2d "2-D Rectangle Classification Functions", * GenericPoint */ template class PCL_CLASS GenericRectangle { public: /*! * Represents the type of a point or rectangle component. */ typedef T component; /*! * Represents a point on the plane. */ typedef GenericPoint point; /* * Rectangle coordinates: x0=left, y0=top, x1=right, y1=bottom. * The x1 (right) and y1 (bottom) coordinates are excluded from the * rectangular area, so we always have: width=x1-x0 and height=y1-y0. */ component x0; //!< Horizontal coordinate of the upper left corner. component y0; //!< Vertical coordinate of the upper left corner. component x1; //!< Horizontal coordinate of the lower right corner. component y1; //!< Vertical coordinate of the lower right corner. /*! * Constructs a default %GenericRectangle instance. Rectangle coordinates * are not initialized, so they'll have unpredictable garbage values. */ constexpr GenericRectangle() { PCL_ASSERT_RECT_SIZE(); } /*! * Constructs a %GenericRectangle instance given by its coordinates in the * plane. * * \param left,top Coordinates of the upper left corner. * \param right,bottom Coordinates of the lower right corner. * * The type T1 can be any suitable real or integer numerical type, or a * type with numeric conversion semantics. */ template constexpr GenericRectangle( T1 left, T1 top, T1 right, T1 bottom ) : x0( component( left ) ) , y0( component( top ) ) , x1( component( right ) ) , y1( component( bottom ) ) { PCL_ASSERT_RECT_SIZE(); } /*! * Constructs a %GenericRectangle instance from coordinates taken from the * specified initializer list \a l. * * This constructor will copy 4, 3, 2, 1 or zero rectangle coordinates, * depending on the number of values in the initializer list. Coordinates * that cannot be initialized from list values will be set to zero. For * example, the following code: * * \code * Rect r1 = {}; * Rect r2 = { 1, 2 }; * Rect r3 = { 1, 2, 3 }; * Rect r4 = { 1, 2, 3, 4 }; * \endcode * * is functionally equivalent to: * * \code * Rect r1( 0, 0, 0, 0 ); * Rect r2( 1, 2, 0, 0 ); * Rect r3( 1, 2, 3, 0 }; * Rect r4( 1, 2, 3, 4 }; * \endcode */ template GenericRectangle( std::initializer_list l ) { PCL_ASSERT_RECT_SIZE(); switch ( l.size() ) { default: case 4: y1 = component( l.begin()[3] ); case 3: x1 = component( l.begin()[2] ); case 2: y0 = component( l.begin()[1] ); case 1: x0 = component( l.begin()[0] ); case 0: break; } switch ( l.size() ) { case 0: x0 = component( 0 ); case 1: y0 = component( 0 ); case 2: x1 = component( 0 ); case 3: y1 = component( 0 ); default: case 4: break; } } /*! * Constructs a %GenericRectangle instance given two points in the plane. * * \param leftTop Position of the upper left corner. * \param rightBottom Position of the lower right corner. * * The type T1 can be any suitable real or integer numerical type, or a * type with numeric conversion semantics. */ template GenericRectangle( const pcl::GenericPoint& leftTop, const pcl::GenericPoint& rightBottom ) : GenericRectangle( component( leftTop.x ), component( leftTop.y ), component( rightBottom.x ), component( rightBottom.y ) ) { PCL_ASSERT_RECT_SIZE(); } /*! * Constructs a %GenericRectangle instance given its \a width and \a height. * The coordinates of the constructed rectangle will be as follows: * * x0 = y0 = 0 \n * x1 = width \n * y1 = height */ constexpr GenericRectangle( component width, component height ) : GenericRectangle( component( 0 ), component( 0 ), width, height ) { PCL_ASSERT_RECT_SIZE(); } /*! * Constructs a %GenericRectangle instance corresponding to a point located * at the coordinates specified by a scalar \a d. * * The constructed rectangle will have all of its coordinates equal to the * scalar \a d. */ constexpr GenericRectangle( component d ) : GenericRectangle( d, d, d, d ) { PCL_ASSERT_RECT_SIZE(); } /*! * Nontrivial copy constructor. Constructs a %GenericRectangle instance as a * copy of the specified rectangle \a r. */ template GenericRectangle( const GenericRectangle& r ) : GenericRectangle( component( r.x0 ), component( r.y0 ), component( r.x1 ), component( r.y1 ) ) { PCL_ASSERT_RECT_SIZE(); } #ifdef __PCL_QT_INTERFACE GenericRectangle( const QRect& r ) : GenericRectangle( component( r.left() ), component( r.top() ), component( r.right()+1 ), component( r.bottom()+1 ) ) { PCL_ASSERT_RECT_SIZE(); } GenericRectangle( const QPoint& p0, const QPoint& p1 ) : GenericRectangle( component( p0.x() ), component( p0.y() ), component( p1.x() ), component( p1.y() ) ) { PCL_ASSERT_RECT_SIZE(); } #endif /*! * Returns the left coordinate of this rectangle. This function returns the * value of the x0 data member. */ component Left() const noexcept { return x0; } /*! * Returns the top coordinate of this rectangle. This function returns the * value of the y0 data member. */ component Top() const noexcept { return y0; } /*! * Returns the right coordinate of this rectangle. This function returns the * value of the x1 data member. */ component Right() const noexcept { return x1; } /*! * Returns the bottom coordinate of this rectangle. This function returns * the value of the y1 data member. */ component Bottom() const noexcept { return y1; } /*! * Returns a point with the coordinates of the upper left (left-top) corner * of this rectangle. */ point LeftTop() const noexcept { return point( pcl::Min( x0, x1 ), pcl::Min( y0, y1 ) ); } /*! * A synonym for LeftTop(). */ point TopLeft() const noexcept { return LeftTop(); } /*! * Returns a point with the coordinates of the upper right (right-top) * corner of this rectangle. */ point RightTop() const noexcept { return point( pcl::Max( x0, x1 ), pcl::Min( y0, y1 ) ); } /*! * A synonym for RightTop(). */ point TopRight() const noexcept { return RightTop(); } /*! * Returns a point with the coordinates of the lower left (left-bottom) * corner of this rectangle. */ point LeftBottom() const noexcept { return point( pcl::Min( x0, x1 ), pcl::Max( y0, y1 ) ); } /*! * A synonym for LeftBottom(). */ point BottomLeft() const noexcept { return LeftBottom(); } /*! * Returns a point with the coordinates of the lower right (right-bottom) * corner of this rectangle. */ point RightBottom() const noexcept { return point( pcl::Max( x0, x1 ), pcl::Max( y0, y1 ) ); } /*! * A synonym for RightBottom(). */ point BottomRight() const noexcept { return RightBottom(); } /*! * Returns a point with the coordinates of the center of this rectangle. */ point Center() const noexcept { return point( (x0 + x1)/2, (y0 + y1)/2 ); } /*! * Returns the upper middle (center-top) point of this rectangle. */ point CenterTop() const noexcept { return point( (x0 + x1)/2, pcl::Min( y0, y1 ) ); } /*! * Returns the lower middle (center-bottom) point of this rectangle. */ point CenterBottom() const noexcept { return point( (x0 + x1)/2, pcl::Min( y0, y1 ) ); } /*! * Returns the left middle (center-left) point of this rectangle. */ point CenterLeft() const noexcept { return point( pcl::Min( x0, x1 ), (y0 + y1)/2 ); } /*! * Returns the right middle (center-right) point of this rectangle. */ point CenterRight() const noexcept { return point( pcl::Min( x0, x1 ), (y0 + y1)/2 ); } /*! * Returns the width of this rectangle. The returned value is the absolute * difference between the x1 and x0 data members. */ component Width() const noexcept { return pcl::Abs( x1 - x0 ); } /*! * Returns the height of this rectangle. The returned value is the absolute * difference between the y1 and y0 data members. */ component Height() const noexcept { return pcl::Abs( y1 - y0 ); } /*! * Returns the perimeter of this rectangle. The returned value is equal to * twice the width plus twice the height. */ component Perimeter() const noexcept { component w = Width(), h = Height(); return w+w+h+h; } /*! * Returns the Manhattan distance between two opposite corners of this * rectangle. * * The returned value is equal to the width plus the height. */ component ManhattanDistance() const noexcept { return Width() + Height(); } /*! * Returns the area of this rectangle. The returned value is equal to the * width multiplied by the height. */ component Area() const noexcept { return pcl::Abs( (x1 - x0)*(y1 - y0) ); } /*! * Returns the x coordinate of the central point of this rectangle. The * returned value is a \c double real value equal to 0.5*(x0 + x1). */ double CenterX() const noexcept { return 0.5*(x0 + x1); } /*! * Returns the y coordinate of the central point of this rectangle. The * returned value is a \c double real value equal to 0.5*(y0 + y1). */ double CenterY() const noexcept { return 0.5*(y0 + y1); } /*! * Returns the square of the diagonal of this rectangle. This is also the * square of the hypotenuse of the half-triangle defined by this rectangle. * The returned value is equal to the square of the width multiplied by the * square of the height. */ double Hypot() const noexcept { double w = x1 - x0, h = y1 - y0; return w*w + h*h; } /*! * Returns the length of the diagonal of this rectangle, equal to the square * root of the Hypot() function. */ double Diagonal() const noexcept { return pcl::Sqrt( Hypot() ); } /*! * Returns true iff this rectangle defines a point in the plane. */ bool IsPoint() const noexcept { return pcl::IsPoint( x0, y0, x1, y1 ); } /*! * Returns true iff this rectangle defines a line. */ bool IsLine() const noexcept { return pcl::IsLine( x0, y0, x1, y1 ); } /*! * Returns true iff this rectangle defines a horizontal line. */ bool IsHorizontalLine() const noexcept { return pcl::IsHorizontalLine( x0, y0, x1, y1 ); } /*! * Returns true iff this rectangle defines a vertical line. */ bool IsVerticalLine() const noexcept { return pcl::IsVerticalLine( x0, y0, x1, y1 ); } /*! * Returns true iff this rectangle defines a point or a line. */ bool IsPointOrLine() const noexcept { return pcl::IsPointOrLine( x0, y0, x1, y1 ); } /*! * Returns true iff the coordinates of this object define a rectangle, * instead of a point or a line. */ bool IsRect() const noexcept { return pcl::IsRect( x0, y0, x1, y1 ); } /*! * Returns true iff this is a normal rectangle. */ bool IsNormal() const noexcept { return pcl::IsNormalRect( x0, y0, x1, y1 ); } /*! * Returns true iff this is an ordered rectangle. */ bool IsOrdered() const noexcept { return pcl::IsOrderedRect( x0, y0, x1, y1 ); } /*! * Orders the coordinates of this rectangle. */ void Order() noexcept { pcl::OrderRect( x0, y0, x1, y1 ); } /*! * Returns an ordered rectangle equivalent to this. */ GenericRectangle Ordered() const noexcept { GenericRectangle r = *this; r.Order(); return r; } /*! * Given the coordinates \a x and \a y of a point in the plane, this * function returns a clip code for the Sutherland-Cohen line clipping * algorithm. * * The returned value is a combination of flags defined in the Clip * namespace. */ template ClipFlags ClipCode( T1 x, T1 y ) const noexcept { ClipFlags clip; // defaults to zero if ( x0 <= x1 ) { if ( x < x0 ) clip |= Clip::Left; if ( x > x1 ) clip |= Clip::Right; } else { if ( x < x1 ) clip |= Clip::Left; if ( x > x0 ) clip |= Clip::Right; } if ( y0 <= y1 ) { if ( y < y0 ) clip |= Clip::Top; if ( y > y1 ) clip |= Clip::Bottom; } else { if ( y < y1 ) clip |= Clip::Top; if ( y > y0 ) clip |= Clip::Bottom; } return clip; } /*! * Given a point \a p in the plane, this function returns a clip code for * the Sutherland-Cohen line clipping algorithm. * * The returned value is a combination of flags defined in the Clip * namespace. */ template ClipFlags ClipCode( const pcl::GenericPoint& p ) const noexcept { return ClipCode( p.x, p.y ); } /*! * Returns true iff this rectangle includes a point specified by its * separate \a x and \a y coordinates. */ template bool Includes( T1 x, T1 y ) const noexcept { return ((x0 < x1) ? (x >= x0 && x <= x1) : (x >= x1 && x <= x0)) && ((y0 < y1) ? (y >= y0 && y <= y1) : (y >= y1 && y <= y0)); } /*! * Returns true iff this rectangle includes a point \a p. */ template bool Includes( const pcl::GenericPoint& p ) const noexcept { return Includes( p.x, p.y ); } /*! * Returns true iff this rectangle completely includes a rectangle \a r. */ template bool Includes( const GenericRectangle& r ) const noexcept { return Includes( r.x0, r.y0 ) && Includes( r.x1, r.y1 ); } #ifdef __PCL_QT_INTERFACE bool Includes( const QPoint& p ) const noexcept { return Includes( p.x(), p.y() ); } bool Includes( const QRect& r ) const noexcept { return Includes( r.left(), r.top() ) && Includes( r.right()+1, r.bottom()+1 ); } #endif /*! * Returns true iff this rectangle includes a point specified by its * separate \a x and \a y coordinates. * * This function assumes an ordered rectangle, that is, it requires that the * conditions x0 ≤ x1 and y0 ≤ y1 hold. Otherwise this function will * return a wrong result. */ template bool IncludesFast( T1 x, T1 y ) const noexcept { return x >= x0 && y >= y0 && x <= x1 && y <= y1; } /*! * Returns true iff this rectangle includes a point \a p. * * This function assumes an ordered rectangle, that is, it requires that the * conditions x0 ≤ x1 and y0 ≤ y1 hold. Otherwise this function will * return a wrong result. */ template bool IncludesFast( const pcl::GenericPoint& p ) const noexcept { return IncludesFast( p.x, p.y ); } /*! * Returns true iff this rectangle intersects a rectangle specified by its * individual coordinates. * * \param left,top Upper left corner coordinates of a rectangle to test * for intersection. * * \param right,bottom Lower right corner coordinates of a rectangle to test * for intersection. */ template bool Intersects( T1 left, T1 top, T1 right, T1 bottom ) const noexcept { OrderRect( left, top, right, bottom ); return ((x0 < x1) ? (right >= x0 && left <= x1) : (right >= x1 && left <= x0)) && ((y0 < y1) ? (bottom >= y0 && top <= y1) : (bottom >= y1 && top <= y0)); } /*! * Returns true iff this rectangle intersects a rectangle \a r. */ template bool Intersects( const pcl::GenericRectangle& r ) const noexcept { return Intersects( r.x0, r.y0, r.x1, r.y1 ); } #ifdef __PCL_QT_INTERFACE bool Intersects( const QRect& r ) const noexcept { return Intersects( r.left(), r.top(), r.right()+1, r.bottom()+1 ); } #endif /*! * Returns true iff this rectangle intersects a rectangle specified by its * individual coordinates. * * \param left,top Upper left corner coordinates of a rectangle to test * for intersection. * * \param right,bottom Lower right corner coordinates of a rectangle to test * for intersection. * * For a valid result, this function assumes the following conditions: * * \li The specified set \a left, \a top, \a right and \a bottom must define * an ordered rectangle, that is, the conditions \a left ≤ \a right and * \a top ≤ \a bottom must hold. * * \li This rectangle must be ordered, that is, the conditions x0 ≤ x1 * and y0 ≤ y1 must hold. */ template bool IntersectsFast( T1 left, T1 top, T1 right, T1 bottom ) const noexcept { return right >= x0 && left <= x1 && bottom >= y0 && top <= y1; } /*! * Returns true iff this rectangle intersects a rectangle \a r. * * To give a valid result, this function assumes that both this and the * specified object \a r are ordered rectangles. */ template bool IntersectsFast( const pcl::GenericRectangle& r ) const noexcept { return IntersectsFast( r.x0, r.y0, r.x1, r.y1 ); } /*! * Causes this rectangle to include a given rectangle \a r, by adjusting its * coordinates as necessary. */ template void Unite( const GenericRectangle& r ) noexcept { Unite( r.x0, r.y0, r.x1, r.y1 ); } /*! * Causes this rectangle to include a rectangle specified by its individual * coordinates. * * \param left,top Upper left corner coordinates of a rectangle that * will be included by this rectangle. * * \param right,bottom Lower right corner coordinates of a rectangle that * will be included by this rectangle. */ template void Unite( T1 left, T1 top, T1 right, T1 bottom ) noexcept { if ( right < left ) Swap( left, right ); if ( bottom < top ) Swap( top, bottom ); if ( x0 <= x1 ) { x0 = pcl::Min( x0, component( left ) ); x1 = pcl::Max( x1, component( right ) ); } else { x0 = pcl::Max( x0, component( right ) ); x1 = pcl::Min( x1, component( left ) ); } if ( y0 <= y1 ) { y0 = pcl::Min( y0, component( top ) ); y1 = pcl::Max( y1, component( bottom ) ); } else { y0 = pcl::Max( y0, component( bottom ) ); y1 = pcl::Min( y1, component( top ) ); } } /*! * Causes this rectangle to include a given rectangle \a r, by adjusting its * coordinates as necessary. * * To produce a valid result, this function assumes that both this and the * specified object \a r are ordered rectangles. */ template void UniteFast( const GenericRectangle& r ) noexcept { UniteFast( r.x0, r.y0, r.x1, r.y1 ); } /*! * Causes this rectangle to include a rectangle specified by its individual * coordinates. * * \param left,top Upper left corner coordinates of a rectangle that * will be included by this rectangle. * * \param right,bottom Lower right corner coordinates of a rectangle that * will be included by this rectangle. * * For a valid result, this function assumes the following conditions: * * \li The specified set \a left, \a top, \a right and \a bottom must define * an ordered rectangle, that is, the conditions \a left ≤ \a right and * \a top ≤ \a bottom must hold. * * \li This rectangle must be ordered, that is, the conditions x0 ≤ x1 * and y0 ≤ y1 must hold. */ template void UniteFast( T1 left, T1 top, T1 right, T1 bottom ) noexcept { x0 = pcl::Min( x0, component( left ) ); y0 = pcl::Min( y0, component( top ) ); x1 = pcl::Max( x1, component( right ) ); y1 = pcl::Max( y1, component( bottom ) ); } /*! * Returns a rectangle that includes this one and another rectangle \a r. */ template GenericRectangle Union( const GenericRectangle& r ) const noexcept { GenericRectangle r1 = *this; r1.Unite( r ); return r1; } /*! * Returns a rectangle that includes this one and another rectangle \a r. * * To give a valid result, this function assumes that both this and the * specified object \a r are ordered rectangles. */ template GenericRectangle UnionFast( const GenericRectangle& r ) const noexcept { GenericRectangle r1 = *this; r1.UniteFast( r ); return r1; } /*! * Causes this rectangle to include a given rectangle \a r, by adjusting * coordinates as necessary. Returns a reference to this rectangle. */ template GenericRectangle& operator |=( const GenericRectangle& r ) noexcept { Unite( r ); return *this; } #ifdef __PCL_QT_INTERFACE void Unite( const QRect& r ) { Unite( r.left(), r.top(), r.right()+1, r.bottom()+1 ); } GenericRectangle Union( const QRect& r ) const noexcept { GenericRectangle r1 = *this; r1.Unite( r ); return r1; } GenericRectangle& operator |=( const QRect& r ) noexcept { Unite( r ); return *this; } #endif /*! * Causes this rectangle to be equal to its intersection with a given * rectangle \a r. * * Returns true iff the resulting intersection is a nonempty rectangle, i.e. * iff this->x0 != this->x1 and this->y0 != this->y1 after calling this * function. */ template bool Intersect( const GenericRectangle& r ) noexcept { return Intersect( r.x0, r.y0, r.x1, r.y1 ); } /*! * Causes this rectangle to be equal to its intersection with a rectangle * specified by its individual coordinates. * * \param left,top Upper left corner coordinates of a rectangle that * will intersect this rectangle. * * \param right,bottom Lower right corner coordinates of a rectangle that will * intersect this rectangle. * * Returns true iff the resulting intersection is a nonempty rectangle, i.e. * iff this->x0 != this->x1 and this->y0 != this->y1 after calling this * function. */ template bool Intersect( T1 left, T1 top, T1 right, T1 bottom ) noexcept { if ( right < left ) Swap( left, right ); if ( bottom < top ) Swap( top, bottom ); if ( x0 <= x1 ) { x0 = pcl::Max( x0, component( left ) ); x1 = pcl::Min( x1, component( right ) ); } else { x0 = pcl::Min( x0, component( right ) ); x1 = pcl::Max( x1, component( left ) ); } if ( y0 <= y1 ) { y0 = pcl::Max( y0, component( top ) ); y1 = pcl::Min( y1, component( bottom ) ); } else { y0 = pcl::Min( y0, component( bottom ) ); y1 = pcl::Max( y1, component( top ) ); } return IsRect(); } /*! * Causes this rectangle to be equal to its intersection with a given * rectangle \a r. * * Returns true iff the resulting intersection is a nonempty rectangle, i.e. * iff this->x0 != this->x1 and this->y0 != this->y1 after calling this * function. * * To produce a valid result, this function assumes that both this and the * specified object \a r are ordered rectangles. */ template bool IntersectFast( const GenericRectangle& r ) noexcept { return IntersectFast( r.x0, r.y0, r.x1, r.y1 ); } /*! * Causes this rectangle to be equal to its intersection with a rectangle * specified by its individual coordinates. * * \param left,top Upper left corner coordinates of a rectangle that * will intersect this rectangle. * * \param right,bottom Lower right corner coordinates of a rectangle that will * intersect this rectangle. * * Returns true iff the resulting intersection is a nonempty rectangle, i.e. * iff this->x0 != this->x1 and this->y0 != this->y1 after calling this * function. * * For a valid result, this function assumes the following conditions: * * \li The specified set \a left, \a top, \a right and \a bottom must define * an ordered rectangle, that is, the conditions \a left ≤ \a right and * \a top ≤ \a bottom must hold. * * \li This rectangle must be ordered, that is, the conditions x0 ≤ x1 * and y0 ≤ y1 must hold. */ template bool IntersectFast( T1 left, T1 top, T1 right, T1 bottom ) noexcept { x0 = pcl::Max( x0, component( left ) ); y0 = pcl::Max( y0, component( top ) ); x1 = pcl::Min( x1, component( right ) ); y1 = pcl::Min( y1, component( bottom ) ); return IsRect(); } /*! * Returns a rectangle equal to the intersection of this rectangle and * another rectangle \a r. */ template GenericRectangle Intersection( const GenericRectangle& r ) const noexcept { GenericRectangle r1 = *this; (void)r1.Intersect( r ); return r1; } /*! * Returns a rectangle equal to the intersection of this rectangle and * another rectangle \a r. * * To give a valid result, this function assumes that both this and the * specified object \a r are ordered rectangles. */ template GenericRectangle IntersectionFast( const GenericRectangle& r ) const noexcept { GenericRectangle r1 = *this; (void)r1.IntersectFast( r ); return r1; } /*! * Causes this rectangle to be equal to its intersection with another * rectangle \a r. Returns a reference to this rectangle. */ template GenericRectangle& operator &=( const GenericRectangle& r ) noexcept { Intersect( r ); return *this; } #ifdef __PCL_QT_INTERFACE bool Intersect( const QRect& r ) noexcept { return Intersect( r.left(), r.top(), r.right()+1, r.bottom()+1 ); } GenericRectangle Intersection( const QRect& r ) const noexcept { GenericRectangle r1 = *this; (void)r1.Intersect( r ); return r1; } GenericRectangle& operator &=( const QRect& r ) noexcept { Intersect( r ); return *this; } #endif /*! * Sets the four coordinates of this rectangle to the specified values. * * \param left,top New upper left corner coordinates. * \param right,bottom New lower right corner coordinates. */ template void Set( T1 left, T1 top, T1 right, T1 bottom ) noexcept { x0 = component( left ); y0 = component( top ); x1 = component( right ); y1 = component( bottom ); } /*! * Moves this rectangle to the specified location, by setting its upper left * corner coordinates to those of a given point \a p. * * The coordinates of the lower right corner of this rectangle are * readjusted to keep its width and height unmodified. */ template void MoveTo( const pcl::GenericPoint& p ) noexcept { MoveTo( p.x, p.y ); } /*! * Moves this rectangle to the specified location, by setting its upper left * corner coordinates equal to the given \a x and \a y coordinates. * * The coordinates of the lower right corner of this rectangle are * readjusted to keep its width and height unmodified. */ template void MoveTo( T1 x, T1 y ) noexcept { component dx = x1 - x0, dy = y1 - y0; x0 = component( x ); y0 = component( y ); x1 = x0 + dx; y1 = y0 + dy; } #ifdef __PCL_QT_INTERFACE void MoveTo( const QPoint& p ) noexcept { MoveTo( p.x(), p.y() ); } #endif /*! * Returns a rectangle \a r equal to this rectangle moved to the specified * location: * * \code GenericRectangle r( *this ); r.MoveTo( p ); \endcode */ template GenericRectangle MovedTo( const pcl::GenericPoint& p ) const noexcept { GenericRectangle r( *this ); r.MoveTo( p ); return r; } /*! * Returns a rectangle \a r equal to this rectangle moved to the specified * location: * * \code GenericRectangle r( *this ); r.MoveTo( x, y ); \endcode */ template GenericRectangle MovedTo( T1 x, T1 y ) const noexcept { GenericRectangle r( *this ); r.MoveTo( x, y ); return r; } /*! * Moves this rectangle relative to its current position, by applying the * coordinates of a point \a d as increments in the X and Y directions. */ template void MoveBy( const pcl::GenericPoint& d ) noexcept { MoveBy( d.x, d.y ); } /*! * Moves this rectangle relative to its current position, by applying the * specified \a dx and \a dy increments to its coordinates in the X and Y * directions, respectively. */ template void MoveBy( T1 dx, T1 dy ) noexcept { x0 += component( dx ); y0 += component( dy ); x1 += component( dx ); y1 += component( dy ); } /*! * Moves this rectangle relative to its current position, by applying the * specified \a dxy increment to its four coordinates in the X and Y * directions. * * This function is functionally equivalent to: * * \code MoveBy( dxy, dxy ); \endcode */ template void MoveBy( T1 dxy ) noexcept { x0 += component( dxy ); y0 += component( dxy ); x1 += component( dxy ); y1 += component( dxy ); } #ifdef __PCL_QT_INTERFACE void MoveBy( const QPoint& p ) noexcept { MoveBy( p.x(), p.y() ); } #endif /*! * Returns a rectangle \a r equal to this rectangle moved relative to its * current position: * * \code GenericRectangle r( *this ); r.MoveBy( d ); \endcode */ template GenericRectangle MovedBy( const pcl::GenericPoint& d ) const noexcept { GenericRectangle r( *this ); r.MoveBy( d ); return r; } /*! * Returns a rectangle \a r equal to this rectangle moved relative to its * current position: * * \code GenericRectangle r( *this ); r.MoveBy( dx, dy ); \endcode */ template GenericRectangle MovedBy( T1 dx, T1 dy ) const noexcept { GenericRectangle r( *this ); r.MoveBy( dx, dy ); return r; } /*! * Changes the size of this rectangle to the specified width \a w and height * \a h, respectively. * * This function does not vary the current order of rectangle coordinates. * If a coordinate of the upper left corner is less than or equal to its * bottom right counterpart, the bottom right coordinate is modified. * Inversely, if the bottom right coordinate is less than the upper left * one, the upper left coordinate is modified. */ template void ResizeTo( T1 w, T1 h ) noexcept { if ( x0 <= x1 ) x1 = x0 + component( w ); else x0 = x1 + component( w ); if ( y0 <= y1 ) y1 = y0 + component( h ); else y0 = y1 + component( h ); } /*! * Returns a rectangle \a r equal to this rectangle resized to the specified * dimensions: * * \code GenericRectangle r( *this ); r.ResizeTo( w, h ); \endcode */ template GenericRectangle ResizedTo( T1 w, T1 h ) const noexcept { GenericRectangle r( *this ); r.ResizeTo( w, h ); return r; } /*! * Changes the size of this rectangle relative to its current dimensions, by * applying the specified \a dw and \a dh increments to its width and * height, respectively. * * This function does not vary the current order of rectangle coordinates. * If a coordinate of the upper left corner is less than or equal to its * bottom right counterpart, the bottom right coordinate is modified. * Inversely, if the bottom right coordinate is less than the upper left * one, the upper left coordinate is modified. */ template void ResizeBy( T1 dw, T1 dh ) noexcept { if ( x0 <= x1 ) x1 += component( dw ); else x0 += component( dw ); if ( y0 <= y1 ) y1 += component( dh ); else y0 += component( dh ); } /*! * Returns a rectangle \a r equal to this rectangle resized relative to its * current dimensions: * * \code GenericRectangle r( *this ); r.ResizeBy( dw, dh ); \endcode */ template GenericRectangle ResizedBy( T1 dw, T1 dh ) const noexcept { GenericRectangle r( *this ); r.ResizeBy( dw, dh ); return r; } /*! * Sets the width of this rectangle to the specified value \a w. * * This function does not vary the current order of horizontal rectangle * coordinates. If the x0 rectangle coordinate is less than or equal to x1, * the x1 coordinate is modified. Inversely, if the x1 coordinate is less * than x0, then x0 is modified. */ template void SetWidth( T1 w ) noexcept { if ( x0 <= x1 ) x1 = x0 + component( w ); else x0 = x1 + component( w ); } /*! * Sets the height of this rectangle to the specified value \a h. * * This function does not vary the current order of vertical rectangle * coordinates. If the y0 rectangle coordinate is less than or equal to y1, * the y1 coordinate is modified. Inversely, if the y1 coordinate is less * than y0, then y0 is modified. */ template void SetHeight( T1 h ) noexcept { if ( y0 <= y1 ) y1 = y0 + component( h ); else y0 = y1 + component( h ); } /*! * Inflates this rectangle by the specified \a dx and \a dy increments on * the X and Y axes respectively. Subtracts \a dx and \a dy to the upper * left corner, and adds them to the bottom right corner. */ template void InflateBy( T1 dx, T1 dy ) noexcept { if ( x1 < x0 ) dx = -dx; if ( y1 < y0 ) dy = -dy; x0 -= dx; y0 -= dy; x1 += dx; y1 += dy; } /*! * Inflates this rectangle by the specified \a d increment on both axes. * Subtracts \a d to the upper left corner, and adds it to the bottom right * corner. */ template void InflateBy( T1 d ) noexcept { if ( x0 <= x1 ) x0 -= d, x1 += d; else x0 += d, x1 -= d; if ( y0 <= y1 ) y0 -= d, y1 += d; else y0 += d, y1 -= d; } /*! * Returns a rectangle equivalent to this rectangle inflated by the * specified \a dx and \a dy increments. */ template GenericRectangle InflatedBy( T1 dx, T1 dy ) const noexcept { GenericRectangle r( *this ); r.InflateBy( dx, dy ); return r; } /*! * Returns a rectangle equivalent to this rectangle inflated by the * specified \a d increments on both axes. */ template GenericRectangle InflatedBy( T1 d ) const noexcept { GenericRectangle r( *this ); r.InflateBy( d ); return r; } /*! * Shrinks this rectangle by the specified \a dx and \a dy increments on the * X and Y axes respectively. Adds \a dx and \a dy to the upper left corner, * and subtracts them to the bottom right corner. */ template void DeflateBy( T1 dx, T1 dy ) noexcept { if ( x1 < x0 ) dx = -dx; if ( y1 < y0 ) dy = -dy; x0 += dx; y0 += dy; x1 -= dx; y1 -= dy; } /*! * Shrinks this rectangle by the specified \a d increment on both axes. Adds * \a d to the upper left corner, and subtracts it to the bottom right * corner. */ template void DeflateBy( T1 d ) noexcept { if ( x0 <= x1 ) x0 += d, x1 -= d; else x0 -= d, x1 += d; if ( y0 <= y1 ) y0 += d, y1 -= d; else y0 -= d, y1 += d; } /*! * Returns a rectangle equivalent to this rectangle shrunk by the specified * \a dx and \a dy increments. */ template GenericRectangle DeflatedBy( T1 dx, T1 dy ) const noexcept { GenericRectangle r( *this ); r.DeflateBy( dx, dy ); return r; } /*! * Returns a rectangle equivalent to this rectangle shrunk by the specified * \a d increment on both axes. */ template GenericRectangle DeflatedBy( T1 d ) const noexcept { GenericRectangle r( *this ); r.DeflateBy( d ); return r; } /*! * Returns a rectangle \a r equal to this rectangle resized horizontally to * the specified width \a w: * * \code GenericRectangle r( *this ); r.SetWidth( w ); \endcode */ template GenericRectangle WidthSetTo( T1 w ) const noexcept { GenericRectangle r( *this ); r.SetWidth( w ); return r; } /*! * Returns a rectangle \a r equal to this rectangle resized vertically to * the specified height \a h: * * \code GenericRectangle r( *this ); r.SetHeight( h ); \endcode */ template GenericRectangle HeightSetTo( T1 h ) const noexcept { GenericRectangle r( *this ); r.SetHeight( h ); return r; } /*! * Rotates this rectangle in the plane by the specified \a angle in radians, * with respect to a center of rotation given by its coordinates \a xc and * \a yc. */ template void Rotate( T1 angle, T2 xc, T2 yc ) noexcept { T1 sa, ca; pcl::SinCos( angle, sa, ca ); pcl::Rotate( x0, y0, sa, ca, xc, yc ); pcl::Rotate( x1, y1, sa, ca, xc, yc ); } /*! * Rotates this rectangle in the plane by the specified \a angle in radians, * with respect to the specified \a center of rotation. */ template void Rotate( T1 angle, const GenericPoint& center ) noexcept { Rotate( angle, center.x, center.y ); } /*! * Rotates this rectangle in the plane by the specified angle, given by its * sine and cosine, \a sa and \a ca respectively, with respect to a center * of rotation given by its coordinates \a xc and \a yc. */ template void Rotate( T1 sa, T1 ca, T2 xc, T2 yc ) noexcept { pcl::Rotate( x0, y0, sa, ca, xc, yc ); pcl::Rotate( x1, y1, sa, ca, xc, yc ); } /*! * Rotates this rectangle in the plane by the specified angle, given by its * sine and cosine, \a sa and \a ca respectively, with respect to the * specified \a center of rotation. */ template void Rotate( T1 sa, T1 ca, const GenericPoint& center ) noexcept { Rotate( sa, ca, center.x, center.y ); } /*! * Returns a rectangle whose coordinates are the coordinates of this object * rotated in the plane by the specified \a angle in radians, with respect * to a center of rotation given by its coordinates \a xc and \a yc. */ template GenericRectangle Rotated( T1 angle, T2 xc, T2 yc ) const noexcept { GenericRectangle r( *this ); r.Rotate( angle, xc, yc ); return r; } /*! * Returns a rectangle whose coordinates are the coordinates of this object * rotated in the plane by the specified \a angle in radians, with respect * to the specified \a center of rotation. */ template GenericRectangle Rotated( T1 angle, const GenericPoint& center ) const noexcept { GenericRectangle r( *this ); r.Rotate( angle, center ); return r; } /*! * Returns a rectangle whose coordinates are the coordinates of this object * rotated in the plane by the specified angle given by its sine and cosine, * \a sa and \a ca respectively, with respect to a center of rotation given * by its coordinates \a xc and \a yc. */ template GenericRectangle Rotated( T1 sa, T1 ca, T2 xc, T2 yc ) const noexcept { GenericRectangle r( *this ); r.Rotate( sa, ca, xc, yc ); return r; } /*! * Returns a rectangle whose coordinates are the coordinates of this object * rotated in the plane by the specified angle given by its sine and cosine, * \a sa and \a ca respectively, with respect to the specified \a center of * rotation. */ template GenericRectangle Rotated( T1 sa, T1 ca, const GenericPoint& center ) const noexcept { GenericRectangle r( *this ); r.Rotate( sa, ca, center ); return r; } /*! * Rounds the coordinates of this rectangle to their corresponding nearest * integer coordinates. */ void Round() noexcept { x0 = component( pcl::Round( double( x0 ) ) ); y0 = component( pcl::Round( double( y0 ) ) ); x1 = component( pcl::Round( double( x1 ) ) ); y1 = component( pcl::Round( double( y1 ) ) ); } /*! * Rounds the coordinates of this rectangle to \a n fractional digits * (\a n >= 0). */ void Round( int n ) noexcept { PCL_PRECONDITION( n >= 0 ) if ( n < 0 ) n = 0; x0 = component( pcl::Round( double( x0 ), n ) ); y0 = component( pcl::Round( double( y0 ), n ) ); x1 = component( pcl::Round( double( x1 ), n ) ); y1 = component( pcl::Round( double( y1 ), n ) ); } /*! * Returns a rectangle whose coordinates are the coordinates of this object * rounded to their nearest integers. */ GenericRectangle Rounded() const noexcept { return GenericRectangle( component( pcl::Round( double( x0 ) ) ), component( pcl::Round( double( y0 ) ) ), component( pcl::Round( double( x1 ) ) ), component( pcl::Round( double( y1 ) ) ) ); } /*! * Returns a rectangle whose coordinates are the coordinates of this object * rounded to \a n fractional digits (\a n >= 0). */ GenericRectangle Rounded( int n ) const noexcept { PCL_PRECONDITION( n >= 0 ) return GenericRectangle( component( pcl::Round( double( x0 ), n ) ), component( pcl::Round( double( y0 ), n ) ), component( pcl::Round( double( x1 ), n ) ), component( pcl::Round( double( y1 ), n ) ) ); } /*! * Returns a rectangle of integer template type whose coordinates are the * coordinates of this object rounded to their nearest integers. */ GenericRectangle RoundedToInt() const noexcept { return GenericRectangle( pcl::RoundInt( double( x0 ) ), pcl::RoundInt( double( y0 ) ), pcl::RoundInt( double( x1 ) ), pcl::RoundInt( double( y1 ) ) ); } /*! * Integer truncation of coordinates. Sets the coordinates x0, y0, x1, y1 of * this rectangle to the nearest integer coordinates a, b, c, d such that * a <= x0, b <= y0, c <= x1, d <= y1. */ void Truncate() noexcept { x0 = component( pcl::Trunc( double( x0 ) ) ); y0 = component( pcl::Trunc( double( y0 ) ) ); x1 = component( pcl::Trunc( double( x1 ) ) ); y1 = component( pcl::Trunc( double( y1 ) ) ); } /*! * Integer truncation of coordinates. Returns a rectangle whose coordinates * are the coordinates x0, y0, x1, y1 of this rectangle, truncated to their * nearest integer coordinates a, b, c, d such that a <= x0, b <= y0, * c <= x1, d <= y1. */ GenericRectangle Truncated() const noexcept { return GenericRectangle( component( pcl::Trunc( double( x0 ) ) ), component( pcl::Trunc( double( y0 ) ) ), component( pcl::Trunc( double( x1 ) ) ), component( pcl::Trunc( double( y1 ) ) ) ); } /*! * Integer truncation of coordinates. Returns a rectangle of integer * template type whose coordinates are the coordinates x0, y0, x1, y1 of * this rectangle truncated to the nearest integer coordinates a, b, c, d * such that a <= x0, b <= y0, c <= x1, d <= y1. */ GenericRectangle TruncatedToInt() const noexcept { return GenericRectangle( pcl::TruncInt( double( x0 ) ), pcl::TruncInt( double( y0 ) ), pcl::TruncInt( double( x1 ) ), pcl::TruncInt( double( y1 ) ) ); } /*! * Assigns a rectangle \a r to this rectangle. Returns a reference to this * rectangle. */ template GenericRectangle& operator =( const GenericRectangle& r ) noexcept { x0 = component( r.x0 ); y0 = component( r.y0 ); x1 = component( r.x1 ); y1 = component( r.y1 ); return *this; } /*! * Assigns a point \a p to this rectangle. Returns a reference to this * rectangle. * * The \a p.x and \a p.y coordinates are assigned, respectively, to the * horizontal and vertical coordinates of this rectangle. */ template GenericRectangle& operator =( const pcl::GenericPoint& p ) noexcept { x0 = x1 = component( p.x ); y0 = y1 = component( p.y ); return *this; } /*! * Assigns a scalar \a d to this rectangle. Returns a reference to this * rectangle. * * The scalar \a d is assigned to the four coordinates of this rectangle. */ GenericRectangle& operator =( component d ) noexcept { x0 = y0 = x1 = y1 = d; return *this; } #ifdef __PCL_QT_INTERFACE GenericRectangle& operator =( const QRect& r ) noexcept { x0 = component( r.left() ); y0 = component( r.top() ); x1 = component( r.right()+1 ); y1 = component( r.bottom()+1 ); return *this; } #endif /*! * Adds a rectangle \a r to this rectangle. Returns a reference to this * rectangle. * * This function adds homonym coordinates. Given two rectangles \a r1 and * \a r2, the sum rectangle \a s = \a r1 + \a r2 is given by: * * \a s.x0 = \a r1.x0 + \a r2.x0 \n * \a s.y0 = \a r1.y0 + \a r2.y0 \n * \a s.x1 = \a r1.x1 + \a r2.x1 \n * \a s.y1 = \a r1.y1 + \a r2.y1 */ template GenericRectangle& operator +=( const GenericRectangle& r ) noexcept { x0 += component( r.x0 ); y0 += component( r.y0 ); x1 += component( r.x1 ); y1 += component( r.y1 ); return *this; } /*! * Adds a point \a p to this rectangle. Returns a reference to this * rectangle. * * This function is equivalent to a translation relative to the current * position. Given a rectangle \a r and a point \a p, the sum rectangle * \a s = \a r + \a p is given by: * * \a s.x0 = \a r.x0 + \a p.x \n * \a s.y0 = \a r.y0 + \a p.y \n * \a s.x1 = \a r.x1 + \a p.x \n * \a s.y1 = \a r.y1 + \a p.y */ template GenericRectangle& operator +=( const pcl::GenericPoint& p ) noexcept { x0 += component( p.x ); y0 += component( p.y ); x1 += component( p.x ); y1 += component( p.y ); return *this; } /*! * Adds a scalar \a d to this rectangle. Returns a reference to this * rectangle. * * This function adds the specified scalar to the four rectangle * coordinates. This is equivalent to a translation relative to the current * position. Given a rectangle \a r and a scalar \a d, the sum rectangle * \a s = \a r + \a d is given by: * * \a s.x0 = \a r.x0 + \a d \n * \a s.y0 = \a r.y0 + \a d \n * \a s.x1 = \a r.x1 + \a d \n * \a s.y1 = \a r.y1 + \a d */ GenericRectangle& operator +=( component d ) noexcept { x0 += d; y0 += d; x1 += d; y1 += d; return *this; } #ifdef __PCL_QT_INTERFACE GenericRectangle& operator +=( const QPoint& p ) noexcept { component dx = component( p.x() ), dy = component( p.y() ); x0 += dx; y0 += dy; x1 += dx; y1 += dy; return *this; } #endif /*! * Subtracts a rectangle \a r from this rectangle. Returns a reference to * this rectangle. * * This function subtracts homonym coordinates. Given two rectangles \a r1 * and \a r2, the difference rectangle \a s = \a r1 - \a r2 is given by: * * \a s.x0 = \a r1.x0 - \a r2.x0 \n * \a s.y0 = \a r1.y0 - \a r2.y0 \n * \a s.x1 = \a r1.x1 - \a r2.x1 \n * \a s.y1 = \a r1.y1 - \a r2.y1 */ template GenericRectangle& operator -=( const GenericRectangle& r ) noexcept { x0 -= component( r.x0 ); y0 -= component( r.y0 ); x1 -= component( r.x1 ); y1 -= component( r.y1 ); return *this; } /*! * Subtracts a point \a p from this rectangle. Returns a reference to this * rectangle. * * This function is equivalent to a translation relative to the current * position. Given a rectangle \a r and a point \a p, the difference * rectangle \a s = \a r - \a p is given by: * * \a s.x0 = \a r.x0 - \a p.x \n * \a s.y0 = \a r.y0 - \a p.y \n * \a s.x1 = \a r.x1 - \a p.x \n * \a s.y1 = \a r.y1 - \a p.y */ template GenericRectangle& operator -=( const pcl::GenericPoint& p ) noexcept { x0 -= component( p.x ); y0 -= component( p.y ); x1 -= component( p.x ); y1 -= component( p.y ); return *this; } /*! * Subtracts a scalar \a d from this rectangle. Returns a reference to this * rectangle. * * This function subtracts the specified scalar from the four rectangle * coordinates. This is equivalent to a translation relative to the current * position. Given a rectangle \a r and a scalar \a d, the difference * rectangle \a s = \a r - \a d is given by: * * \a s.x0 = \a r.x0 - \a d \n * \a s.y0 = \a r.y0 - \a d \n * \a s.x1 = \a r.x1 - \a d \n * \a s.y1 = \a r.y1 - \a d */ GenericRectangle& operator -=( component d ) noexcept { x0 -= d; y0 -= d; x1 -= d; y1 -= d; return *this; } #ifdef __PCL_QT_INTERFACE GenericRectangle& operator -=( const QPoint& p ) noexcept { component dx = component( p.x() ), dy = component( p.y() ); x0 -= dx; y0 -= dy; x1 -= dx; y1 -= dy; return *this; } #endif /*! * Multiplies this rectangle by a rectangle \a r. Returns a reference to * this rectangle. * * This function multiplies homonym coordinates. Given two rectangles \a r1 * and \a r2, the product rectangle \a P = \a r1 * \a r2 is given by: * * \a P.x0 = \a r1.x0 * \a r2.x0 \n * \a P.y0 = \a r1.y0 * \a r2.y0 \n * \a P.x1 = \a r1.x1 * \a r2.x1 \n * \a P.y1 = \a r1.y1 * \a r2.y1 */ template GenericRectangle& operator *=( const GenericRectangle& r ) noexcept { x0 *= component( r.x0 ); y0 *= component( r.y0 ); x1 *= component( r.x1 ); y1 *= component( r.y1 ); return *this; } /*! * Multiplies this rectangle by a point \a p. Returns a reference to this * rectangle. * * This function is equivalent to a translation relative to the current * position, plus a scaling factor applied to both sides of the rectangle. * Given a rectangle \a r and a point \a p, the product rectangle * \a P = \a r * \a p is given by: * * \a P.x0 = \a r.x0 * \a p.x \n * \a P.y0 = \a r.y0 * \a p.y \n * \a P.x1 = \a r.x1 * \a p.x \n * \a P.y1 = \a r.y1 * \a p.y */ template GenericRectangle& operator *=( const pcl::GenericPoint& p ) noexcept { x0 *= component( p.x ); y0 *= component( p.y ); x1 *= component( p.x ); y1 *= component( p.y ); return *this; } /*! * Multiplies this rectangle by a scalar \a d. Returns a reference to this * rectangle. * * This function is equivalent to a translation relative to the current * position, plus a scaling factor applied to both sides of the rectangle. * Given a rectangle \a r and a scalar \a d, the product rectangle * \a P = \a r * \a d is given by: * * \a P.x0 = \a r.x0 * \a d \n * \a P.y0 = \a r.y0 * \a d \n * \a P.x1 = \a r.x1 * \a d \n * \a P.y1 = \a r.y1 * \a d */ GenericRectangle& operator *=( component d ) noexcept { x0 *= d; y0 *= d; x1 *= d; y1 *= d; return *this; } #ifdef __PCL_QT_INTERFACE GenericRectangle& operator *=( const QPoint& p ) noexcept { component dx = component( p.x() ), dy = component( p.y() ); x0 *= dx; y0 *= dy; x1 *= dx; y1 *= dy; return *this; } #endif /*! * Divides this rectangle by a rectangle \a r. Returns a reference to this * rectangle. * * This function divides homonym coordinates. Given two rectangles \a r1 * and \a r2, the quotient rectangle \a Q = \a r1 / \a r2 is given by: * * \a Q.x0 = \a r1.x0 / \a r2.x0 \n * \a Q.y0 = \a r1.y0 / \a r2.y0 \n * \a Q.x1 = \a r1.x1 / \a r2.x1 \n * \a Q.y1 = \a r1.y1 / \a r2.y1 */ template GenericRectangle& operator /=( const GenericRectangle& r ) noexcept { PCL_PRECONDITION( component( r.x0 ) != component( 0 ) && component( r.y0 ) != component( 0 ) && component( r.x1 ) != component( 0 ) && component( r.y1 ) != component( 0 ) ) x0 /= component( r.x0 ); y0 /= component( r.y0 ); x1 /= component( r.x1 ); y1 /= component( r.y1 ); return *this; } /*! * Divides this rectangle by a point \a p. Returns a reference to this * rectangle. * * This function is equivalent to a translation relative to the current * position, plus a scaling factor applied to both sides of the rectangle. * Given a rectangle \a r and a point \a p, the quotient rectangle * \a Q = \a r / \a p is given by: * * \a Q.x0 = \a r.x0 / \a p.x \n * \a Q.y0 = \a r.y0 / \a p.y \n * \a Q.x1 = \a r.x1 / \a p.x \n * \a Q.y1 = \a r.y1 / \a p.y */ template GenericRectangle& operator /=( const pcl::GenericPoint& p ) noexcept { PCL_PRECONDITION( component( p.x ) != component( 0 ) && component( p.y ) != component( 0 ) ) x0 /= component( p.x ); y0 /= component( p.y ); x1 /= component( p.x ); y1 /= component( p.y ); return *this; } /*! * Divides this rectangle by a scalar \a d. Returns a reference to this * rectangle. * * This function is equivalent to a translation relative to the current * position, plus a scaling factor applied to both sides of the rectangle. * Given a rectangle \a r and a scalar \a d, the quotient rectangle * \a Q = \a r / \a d is given by: * * \a Q.x0 = \a r.x0 / \a d \n * \a Q.y0 = \a r.y0 / \a d \n * \a Q.x1 = \a r.x1 / \a d \n * \a Q.y1 = \a r.y1 / \a d */ GenericRectangle& operator /=( component d ) noexcept { PCL_PRECONDITION( d != component( 0 ) ) x0 /= d; y0 /= d; x1 /= d; y1 /= d; return *this; } #ifdef __PCL_QT_INTERFACE GenericRectangle& operator /=( const QPoint& p ) noexcept { PCL_PRECONDITION( component( p.x() ) != component( 0 ) && component( p.y() ) != component( 0 ) ) component dx = component( p.x() ), dy = component( p.y() ); x0 /= dx; y0 /= dy; x1 /= dx; y1 /= dy; return *this; } #endif /*! * Returns a copy of this rectangle. */ GenericRectangle operator +() const noexcept { return *this; } /*! * Returns a rectangle whose coordinates have the same magnitudes as the * coordinates of this rectangle, but opposite signs. The returned rectangle * so defined is symmetric to this rectangle with respect to the origin of * coordinates. */ GenericRectangle operator -() const noexcept { return GenericRectangle( -x0, -y0, -x1, -y1 ); } #ifdef __PCL_QT_INTERFACE operator QRect() const noexcept { return QRect( int( x0 ), int( y0 ), int( x1-x0 ), int( y1-y0 ) ); } #endif #ifdef __PCL_QT_INTERFACE # ifndef __PCL_QT_NO_RECT_DRAWING_HELPERS void Draw( QPainter& p, const QBrush* b ) const { int rx0, ry0, rx1, ry1; if ( x0 <= x1 ) rx0 = x0, rx1 = x1; else rx0 = x1, rx1 = x0; if ( y0 <= y1 ) ry0 = y0, ry1 = y1; else ry0 = y1, ry1 = y0; if ( rx1 - rx0 <= 1 ) { if ( ry1 - ry0 <= 1 ) p.drawPoint( rx0, ry0 ); else p.drawLine( rx0, ry0, rx0, ry1-1 ); } else if ( ry1 - ry0 <= 1 ) { p.drawLine( rx0, ry0, rx1-1, ry0 ); } else { # if ( QT_VERSION >= 0x040000 ) int w = rx1-rx0-1, h = ry1-ry0-1; # else int w = rx1-rx0, h = ry1-ry0; # endif if ( b != 0 ) p.fillRect( rx0, ry0, w, h, *b ); p.drawRect( rx0, ry0, w, h ); } } void Draw( QPainter& p ) const { Draw( p, 0 ); } void Draw( QPainter& p, const QColor& c ) const { QBrush b( c ); Draw( p, &b ); } # endif // !__PCL_QT_NO_RECT_DRAWING_HELPERS #endif // __PCL_QT_INTERFACE }; // GenericRectangle #undef PCL_ASSERT_RECT_SIZE // ---------------------------------------------------------------------------- /*! * \defgroup rect_functions_2d Rectangle Operators and Functions */ /*! * Returns true iff two rectangles \a r1 and \a r2 are equal. Two rectangles * are equal if their homonym coordinates are equal. * \ingroup rect_functions_2d */ template inline bool operator ==( const GenericRectangle& r1, const GenericRectangle& r2 ) noexcept { return r1.x0 == r2.x0 && r1.y0 == r2.y0 && r1.x1 == r2.x1 && r1.y1 == r2.y1; } /*! * Returns true iff a rectangle \a r1 is equal to a scalar \a d2. A rectangle * is equal to a scalar \a d if the four coordinates of \a r are equal to \a d. * \ingroup rect_functions_2d */ template inline bool operator ==( const GenericRectangle& r1, T d2 ) noexcept { return r1.x0 == d2 && r1.y0 == d2 && r1.x1 == d2 && r1.y1 == d2; } /*! * Returns true iff a scalar \a d1 is equal to a rectangle \a r2. A scalar \a d * is equal to a rectangle \a r if the four coordinates of \a r are equal to * \a d. * \ingroup rect_functions_2d */ template inline bool operator ==( T d1, const GenericRectangle& r2 ) noexcept { return d1 == r2.x0 && d1 == r2.y0 && d1 == r2.x1 && d1 == r2.y1; } /*! * Returns true iff a rectangle \a r1 is less than another rectangle \a r2. * For rectangle comparisons, vertical coordinates have precedence over * horizontal coordinates. * \ingroup rect_functions_2d */ template inline bool operator <( const GenericRectangle& r1, const GenericRectangle& r2 ) noexcept { T1 x01 = Min( r1.x0, r1.x1 ); T1 y01 = Min( r1.y0, r1.y1 ); T1 x11 = Max( r1.x0, r1.x1 ); T1 y11 = Max( r1.y0, r1.y1 ); T2 x02 = Min( r2.x0, r2.x1 ); T2 y02 = Min( r2.y0, r2.y1 ); T2 x12 = Max( r2.x0, r2.x1 ); T2 y12 = Max( r2.y0, r2.y1 ); if ( y01 != y02 ) return y01 < y02; if ( x01 != x02 ) return x01 < x02; if ( y11 != y12 ) return y11 < y12; return x11 < x12; } /*! * Adds two rectangles \a r1 and \a r2, and returns the resulting sum * rectangle. * * Rectangle addition consists in adding homonym coordinates. Given two * rectangles \a r1 and \a r2, the sum rectangle \a s = \a r1 + \a r2 is * given by: * * \a s.x0 = \a r1.x0 + \a r2.x0 \n * \a s.y0 = \a r1.y0 + \a r2.y0 \n * \a s.x1 = \a r1.x1 + \a r2.x1 \n * \a s.y1 = \a r1.y1 + \a r2.y1 * * \ingroup rect_functions_2d */ template inline GenericRectangle operator +( const GenericRectangle& r1, const GenericRectangle& r2 ) noexcept { return GenericRectangle( T1( r1.x0 + r2.x0 ), T1( r1.y0 + r2.y0 ), T1( r1.x1 + r2.x1 ), T1( r1.y1 + r2.y1 ) ); } /*! * Adds a rectangle \a r1 and a point \a p2, and returns the resulting sum * rectangle. * * Given a rectangle \a r and a point \a p, the sum rectangle * \a s = \a r + \a p is given by: * * \a s.x0 = \a r.x0 + \a p.x \n * \a s.y0 = \a r.y0 + \a p.y \n * \a s.x1 = \a r.x1 + \a p.x \n * \a s.y1 = \a r.y1 + \a p.y * * \ingroup rect_functions_2d */ template inline GenericRectangle operator +( const GenericRectangle& r1, const GenericPoint& p2 ) noexcept { return GenericRectangle( T1( r1.x0 + p2.x ), T1( r1.y0 + p2.y ), T1( r1.x1 + p2.x ), T1( r1.y1 + p2.y ) ); } /*! * Adds a point \a p1 and a rectangle \a r2, and returns the resulting sum * rectangle. * * Rectangle addition is a commutative operation, thus see * pcl::operator +( const GenericRectangle&, const GenericPoint& ). * * \ingroup rect_functions_2d */ template inline GenericRectangle operator +( const GenericPoint& p1, const GenericRectangle& r2 ) noexcept { return GenericRectangle( T2( p1.x + r2.x0 ), T2( p1.y + r2.y0 ), T2( p1.x + r2.x1 ), T2( p1.y + r2.y1 ) ); } /*! * Adds a rectangle \a r1 and a scalar \a d2, and returns the resulting sum * rectangle. * * Given a rectangle \a r and a scalar \a d, the sum rectangle * \a s = \a r + \a d is given by: * * \a s.x0 = \a r.x0 + \a d \n * \a s.y0 = \a r.y0 + \a d \n * \a s.x1 = \a r.x1 + \a d \n * \a s.y1 = \a r.y1 + \a d * * \ingroup rect_functions_2d */ template inline GenericRectangle operator +( const GenericRectangle& r1, T d2 ) noexcept { return GenericRectangle( r1.x0+d2, r1.y0+d2, r1.x1+d2, r1.y1+d2 ); } /*! * Adds a scalar \a d1 and a rectangle \a r2, and returns the resulting sum * rectangle. * * Rectangle addition is a commutative operation, thus see * pcl::operator +( const GenericRectangle&, T ). * * \ingroup rect_functions_2d */ template inline GenericRectangle operator +( T d1, const GenericRectangle& r2 ) noexcept { return GenericRectangle( d1+r2.x0, d1+r2.y0, d1+r2.x1, d1+r2.y1 ); } /*! * Subtracts two rectangles \a r1 and \a r2, and returns the resulting * difference rectangle. * * Rectangle subtraction consists in subtracting homonym coordinates. Given * two rectangles \a r1 and \a r2, the difference rectangle * \a s = \a r1 - \a r2 is given by: * * \a s.x0 = \a r1.x0 - \a r2.x0 \n * \a s.y0 = \a r1.y0 - \a r2.y0 \n * \a s.x1 = \a r1.x1 - \a r2.x1 \n * \a s.y1 = \a r1.y1 - \a r2.y1 * * \ingroup rect_functions_2d */ template inline GenericRectangle operator -( const GenericRectangle& r1, const GenericRectangle& r2 ) noexcept { return GenericRectangle( T1( r1.x0 - r2.x0 ), T1( r1.y0 - r2.y0 ), T1( r1.x1 - r2.x1 ), T1( r1.y1 - r2.y1 ) ); } /*! * Subtracts a point \a p2 from a rectangle \a r1, and returns the resulting * difference rectangle. * * Given a rectangle \a r and a point \a p, the difference rectangle * \a s = \a r - \a p is given by: * * \a s.x0 = \a r.x0 - \a p.x \n * \a s.y0 = \a r.y0 - \a p.y \n * \a s.x1 = \a r.x1 - \a p.x \n * \a s.y1 = \a r.y1 - \a p.y * * \ingroup rect_functions_2d */ template inline GenericRectangle operator -( const GenericRectangle& r1, const GenericPoint& p2 ) noexcept { return GenericRectangle( T1( r1.x0 - p2.x ), T1( r1.y0 - p2.y ), T1( r1.x1 - p2.x ), T1( r1.y1 - p2.y ) ); } /*! * Subtracts a rectangle \a r2 from a point \a p1, and returns the resulting * difference rectangle. * * Given a rectangle \a r and a point \a p, the difference rectangle * \a s = \a p - \a r is given by: * * \a s.x0 = \a p.x - \a r.x0 \n * \a s.y0 = \a p.y - \a r.y0 \n * \a s.x1 = \a p.x - \a r.x1 \n * \a s.y1 = \a p.y - \a r.y1 * * \ingroup rect_functions_2d */ template inline GenericRectangle operator -( const GenericPoint& p1, const GenericRectangle& r2 ) noexcept { return GenericRectangle( T2( p1.x - r2.x0 ), T2( p1.y - r2.y0 ), T2( p1.x - r2.x1 ), T2( p1.y - r2.y1 ) ); } /*! * Subtracts a scalar \a d2 from a rectangle \a r1, and returns the resulting * difference rectangle. * * Given a rectangle \a r and a scalar \a d, the difference rectangle * \a s = \a r - \a d is given by: * * \a s.x0 = \a r.x0 - \a d \n * \a s.y0 = \a r.y0 - \a d \n * \a s.x1 = \a r.x1 - \a d \n * \a s.y1 = \a r.y1 - \a d * * \ingroup rect_functions_2d */ template inline GenericRectangle operator -( const GenericRectangle& r1, T d2 ) noexcept { return GenericRectangle( r1.x0-d2, r1.y0-d2, r1.x1-d2, r1.y1-d2 ); } /*! * Subtracts a rectangle \a r2 from a scalar \a d1, and returns the resulting * difference rectangle. * * Given a rectangle \a r and a scalar \a d, the difference rectangle * \a s = \a d - \a r is given by: * * \a s.x0 = \a d - \a r.x0 \n * \a s.y0 = \a d - \a r.y0 \n * \a s.x1 = \a d - \a r.x1 \n * \a s.y1 = \a d - \a r.y1 * * \ingroup rect_functions_2d */ template inline GenericRectangle operator -( T d1, const GenericRectangle& r2 ) noexcept { return GenericRectangle( d1-r2.x0, d1-r2.y0, d1-r2.x1, d1-r2.y1 ); } /*! * Multiplies two rectangles \a r1 and \a r2, and returns the resulting * product rectangle. * * Rectangle multiplication consists in multiplying homonym coordinates. Given * two rectangles \a r1 and \a r2, the product rectangle \a P = \a r1 * \a r2 * is given by: * * \a P.x0 = \a r1.x0 * \a r2.x0 \n * \a P.y0 = \a r1.y0 * \a r2.y0 \n * \a P.x1 = \a r1.x1 * \a r2.x1 \n * \a P.y1 = \a r1.y1 * \a r2.y1 * * \ingroup rect_functions_2d */ template inline GenericRectangle operator *( const GenericRectangle& r1, const GenericRectangle& r2 ) noexcept { return GenericRectangle( T1( r1.x0 * r2.x0 ), T1( r1.y0 * r2.y0 ), T1( r1.x1 * r2.x1 ), T1( r1.y1 * r2.y1 ) ); } /*! * Multiplies a rectangle \a r1 by a point \a p2, and returns the resulting * product rectangle. * * Given a rectangle \a r and a point \a p, the product rectangle * \a P = \a r * \a p is given by: * * \a P.x0 = \a r1.x0 * \a p.x \n * \a P.y0 = \a r1.y0 * \a p.y \n * \a P.x1 = \a r1.x1 * \a p.x \n * \a P.y1 = \a r1.y1 * \a p.y * * \ingroup rect_functions_2d */ template inline GenericRectangle operator *( const GenericRectangle& r1, const GenericPoint& p2 ) noexcept { return GenericRectangle( T1( r1.x0 * p2.x ), T1( r1.y0 * p2.y ), T1( r1.x1 * p2.x ), T1( r1.y1 * p2.y ) ); } /*! * Multiplies a point \a p1 by a rectangle \a r2, and returns the resulting * product rectangle. * * Rectangle multiplication is a commutative operation, thus see * pcl::operator *( const GenericRectangle&, const GenericPoint& ). * * \ingroup rect_functions_2d */ template inline GenericRectangle operator *( const GenericPoint& p1, const GenericRectangle& r2 ) noexcept { return GenericRectangle( T2( p1.x * r2.x0 ), T2( p1.y * r2.y0 ), T2( p1.x * r2.x1 ), T2( p1.y * r2.y1 ) ); } /*! * Multiplies a rectangle \a r1 by a scalar \a d2, and returns the resulting * product rectangle. * * Given a rectangle \a r and a scalar \a d, the product rectangle * \a P = \a r * \a d is given by: * * \a P.x0 = \a r1.x0 * \a d \n * \a P.y0 = \a r1.y0 * \a d \n * \a P.x1 = \a r1.x1 * \a d \n * \a P.y1 = \a r1.y1 * \a d * * \ingroup rect_functions_2d */ template inline GenericRectangle operator *( const GenericRectangle& r1, T d2 ) noexcept { return GenericRectangle( r1.x0*d2, r1.y0*d2, r1.x1*d2, r1.y1*d2 ); } /*! * Multiplies a scalar \a d1 by a rectangle \a r2, and returns the resulting * product rectangle. * * Rectangle multiplication is a commutative operation, thus see * pcl::operator *( const GenericRectangle&, T ). * * \ingroup rect_functions_2d */ template inline GenericRectangle operator *( T d1, const GenericRectangle& r2 ) noexcept { return GenericRectangle( d1*r2.x0, d1*r2.y0, d1*r2.x1, d1*r2.y1 ); } /*! * Divides two rectangles \a r1 and \a r2, and returns the resulting quotient * rectangle. * * Rectangle division consists in dividing homonym coordinates. Given two * rectangles \a r1 and \a r2, the quotient rectangle * \a Q = \a r1 / \a r2 is given by: * * \a Q.x0 = \a r1.x0 / \a r2.x0 \n * \a Q.y0 = \a r1.y0 / \a r2.y0 \n * \a Q.x1 = \a r1.x1 / \a r2.x1 \n * \a Q.y1 = \a r1.y1 / \a r2.y1 * * \ingroup rect_functions_2d */ template inline GenericRectangle operator /( const GenericRectangle& r1, const GenericRectangle& r2 ) noexcept { PCL_PRECONDITION( r2.x0 != T2( 0 ) && r2.y0 != T2( 0 ) && r2.x1 != T2( 0 ) && r2.y1 != T2( 0 ) ) return GenericRectangle( T1( r1.x0 / r2.x0 ), T1( r1.y0 / r2.y0 ), T1( r1.x1 / r2.x1 ), T1( r1.y1 / r2.y1 ) ); } /*! * Divides a rectangle \a r1 by a point \a p2, and returns the resulting * quotient rectangle. * * Given a rectangle \a r and a point \a p, the quotient rectangle * \a Q = \a r / \a p is given by: * * \a Q.x0 = \a r.x0 / \a p.x \n * \a Q.y0 = \a r.y0 / \a p.y \n * \a Q.x1 = \a r.x1 / \a p.x \n * \a Q.y1 = \a r.y1 / \a p.y * * \ingroup rect_functions_2d */ template inline GenericRectangle operator /( const GenericRectangle& r1, const GenericPoint& p2 ) noexcept { PCL_PRECONDITION( p2.x != T2( 0 ) && p2.y != T2( 0 ) ) return GenericRectangle( T1( r1.x0 / p2.x ), T1( r1.y0 / p2.y ), T1( r1.x1 / p2.x ), T1( r1.y1 / p2.y ) ); } /*! * Divides a point \a p1 by a rectangle \a r2, and returns the resulting * quotient rectangle. * * Given a rectangle \a r and a point \a p, the quotient rectangle * \a Q = \a p / \a r is given by: * * \a Q.x0 = \a p.x / \a r.x0 \n * \a Q.y0 = \a p.y / \a r.y0 \n * \a Q.x1 = \a p.x / \a r.x1 \n * \a Q.y1 = \a p.y / \a r.y1 * * \ingroup rect_functions_2d */ template inline GenericRectangle operator /( const GenericPoint& p1, const GenericRectangle& r2 ) noexcept { PCL_PRECONDITION( r2.x0 != T2( 0 ) && r2.y0 != T2( 0 ) && r2.x1 != T2( 0 ) && r2.y1 != T2( 0 ) ) return GenericRectangle( T2( p1.x / r2.x0 ), T2( p1.y / r2.y0 ), T2( p1.x / r2.x1 ), T2( p1.y / r2.y1 ) ); } /*! * Divides a rectangle \a r1 by a scalar \a d2, and returns the resulting * quotient rectangle. * * Given a rectangle \a r and a scalar \a d, the quotient rectangle * \a Q = \a r / \a d is given by: * * \a Q.x0 = \a r.x0 / \a d \n * \a Q.y0 = \a r.y0 / \a d \n * \a Q.x1 = \a r.x1 / \a d \n * \a Q.y1 = \a r.y1 / \a d * * \ingroup rect_functions_2d */ template inline GenericRectangle operator /( const GenericRectangle& r1, T d2 ) noexcept { PCL_PRECONDITION( d2 != T( 0 ) ) return GenericRectangle( r1.x0/d2, r1.y0/d2, r1.x1/d2, r1.y1/d2 ); } /*! * Divides a scalar \a d1 by a rectangle \a r2, and returns the resulting * quotient rectangle. * * Given a rectangle \a r and a scalar \a d, the quotient rectangle * \a Q = \a d / \a r is given by: * * \a Q.x0 = \a d / \a r.x0 \n * \a Q.y0 = \a d / \a r.y0 \n * \a Q.x1 = \a d / \a r.x1 \n * \a Q.y1 = \a d / \a r.y1 * * \ingroup rect_functions_2d */ template inline GenericRectangle operator /( T d1, const GenericRectangle& r2 ) noexcept { PCL_PRECONDITION( r2.x0 != T( 0 ) && r2.y0 != T( 0 ) && r2.x1 != T( 0 ) && r2.y1 != T( 0 ) ) return GenericRectangle( d1/r2.x0, d1/r2.y0, d1/r2.x1, d1/r2.y1 ); } /*! * Rotates a rectangle in the plane, given a rotation angle and the * coordinates of a center of rotation. * * \param r Reference to a rectangle that will be rotated. * \param a Rotation angle in radians. Positive angles are measured * counter-clockwise. * \param xc Abscissa (x coordinate) of the center of rotation. * \param yc Ordinate (y coordinate) of the center of rotation. * * The coordinates \a r.x0, \a r.y0, \a r.x1 and \a r.y1 are replaced by their * corresponding rotated values. * * \ingroup rect_functions_2d */ template inline void Rotate( GenericRectangle& r, T1 a, T2 xc, T2 yc ) noexcept { T1 sa, ca; pcl::SinCos( a, sa, ca ); pcl::Rotate( r.x0, r.y0, sa, ca, xc, yc ); pcl::Rotate( r.x1, r.y1, sa, ca, xc, yc ); } /*! * Rotates a rectangle in the plane, given a rotation angle and a rotation * center point. * * \param r Reference to a rectangle that will be rotated. * \param a Rotation angle in radians. Positive angles are measured * counter-clockwise. * \param c Reference to a point that will be taken as the center of * rotation. * * The coordinates \a r.x0, \a r.y0, \a r.x1 and \a r.y1 are replaced by their * corresponding rotated values. * * \ingroup rect_functions_2d */ template inline void Rotate( GenericRectangle& r, T1 a, const GenericPoint& c ) noexcept { pcl::Rotate( r, a, c.x, c.y ); } /*! * Rotates a rectangle in the plane, given a rotation angle by its sine and * cosine, and the coordinates of a center of rotation. * * \param r Reference to a rectangle that will be rotated. * \param sa Sine of the rotation angle. * \param ca Cosine of the rotation angle. * \param xc Abscissa (x coordinate) of the center of rotation. * \param yc Ordinate (y coordinate) of the center of rotation. * * The coordinates \a r.x0, \a r.y0, \a r.x1 and \a r.y1 are replaced by their * corresponding rotated values. * * \ingroup rect_functions_2d */ template inline void Rotate( GenericRectangle& r, T1 sa, T1 ca, T2 xc, T2 yc ) noexcept { pcl::Rotate( r.x0, r.y0, sa, ca, xc, yc ); pcl::Rotate( r.x1, r.y1, sa, ca, xc, yc ); } /*! * Rotates a rectangle in the plane, given a rotation angle by its sine and * cosine, and a rotation center point. * * \param r Reference to a rectangle that will be rotated. * \param sa Sine of the rotation angle. * \param ca Cosine of the rotation angle. * \param c Reference to a point that will be taken as the center of * rotation. * * The coordinates \a r.x0, \a r.y0, \a r.x1 and \a r.y1 are replaced by their * corresponding rotated values. * * \ingroup rect_functions_2d */ template inline void Rotate( GenericRectangle& r, T1 sa, T1 ca, const GenericPoint& c ) noexcept { pcl::Rotate( r, sa, ca, c.x, c.y ); } /*! * Exchanges two rectangles \a r1 and \a r2. Calling this function is * equivalent to: * * \code * pcl::Swap( r1.x0, r2.x0 ); pcl::Swap( r1.y0, r2.y0 ); * pcl::Swap( r1.x1, r2.x1 ); pcl::Swap( r1.y1, r2.y1 ); * \endcode * * \ingroup rect_functions_2d */ template inline void Swap( GenericRectangle& r1, GenericRectangle& r2 ) noexcept { pcl::Swap( r1.x0, r2.x0 ); pcl::Swap( r1.y0, r2.y0 ); pcl::Swap( r1.x1, r2.x1 ); pcl::Swap( r1.y1, r2.y1 ); } // ---------------------------------------------------------------------------- #ifndef __PCL_NO_RECT_INSTANTIATE /*! * \defgroup rect_types_2d Rectangle Types */ /*! * \class pcl::I32Rect * \ingroup rect_types_2d * \brief 32-bit integer rectangle on the plane. * * %I32Rect is a template instantiation of GenericRectangle for \c int32. */ typedef GenericRectangle I32Rect; /*! * \class pcl::Rect * \ingroup rect_types_2d * \brief 32-bit integer rectangle on the plane. * * %Rect is an alias for I32Rect. It is a template instantiation of * GenericRectangle for \c int32. */ typedef I32Rect Rect; /*! * \class pcl::F32Rect * \ingroup rect_types_2d * \brief 32-bit floating-point rectangle in the R^2 space. * * %F32Rect is a template instantiation of GenericRectangle for \c float. */ typedef GenericRectangle F32Rect; /*! * \class pcl::FRect * \ingroup rect_types_2d * \brief 32-bit floating-point rectangle in the R^2 space. * * %FRect is an alias for F32Rect. It is a template instantiation of * GenericRectangle for \c float. */ typedef F32Rect FRect; /*! * \class pcl::F64Rect * \ingroup rect_types_2d * \brief 64-bit floating-point rectangle in the R^2 space. * * %F64Rect is a template instantiation of GenericRectangle for \c double. */ typedef GenericRectangle F64Rect; /*! * \class pcl::DRect * \ingroup rect_types_2d * \brief 64-bit floating-point rectangle in the R^2 space. * * %DRect is an alias for F64Rect. It is a template instantiation of * GenericRectangle for \c double. */ typedef F64Rect DRect; #endif // ---------------------------------------------------------------------------- } // pcl #endif // __PCL_Rectangle_h // ---------------------------------------------------------------------------- // EOF pcl/Rectangle.h - Released 2022-03-12T18:59:29Z